|
|
@ -24,6 +24,7 @@ import socket |
|
|
|
import struct |
|
|
|
import subprocess |
|
|
|
import sys |
|
|
|
import tempfile |
|
|
|
import traceback |
|
|
|
import xml.etree.ElementTree |
|
|
|
import zlib |
|
|
@ -228,18 +229,36 @@ else: |
|
|
|
assert type(s) == type(u'') |
|
|
|
print(s) |
|
|
|
|
|
|
|
# In Python 2.x, json.dump expects a bytestream. |
|
|
|
# In Python 3.x, it writes to a character stream |
|
|
|
if sys.version_info < (3,0): |
|
|
|
def write_json_file(obj, fn): |
|
|
|
with open(fn, 'wb') as f: |
|
|
|
json.dump(obj, f) |
|
|
|
else: |
|
|
|
def write_json_file(obj, fn): |
|
|
|
with open(fn, 'w', encoding='utf-8') as f: |
|
|
|
json.dump(obj, f) |
|
|
|
|
|
|
|
if sys.version_info >= (2,7): |
|
|
|
def write_json_file(obj, fn): |
|
|
|
""" Encode obj as JSON and write it to fn, atomically """ |
|
|
|
|
|
|
|
# In Python 2.x, json.dump expects a bytestream. |
|
|
|
# In Python 3.x, it writes to a character stream |
|
|
|
if sys.version_info < (3, 0): |
|
|
|
mode = 'wb' |
|
|
|
encoding = None |
|
|
|
else: |
|
|
|
mode = 'w' |
|
|
|
encoding = 'utf-8' |
|
|
|
tf = tempfile.NamedTemporaryFile( |
|
|
|
suffix='.tmp', prefix=os.path.basename(fn) + '.', |
|
|
|
dir=os.path.dirname(fn), |
|
|
|
delete=False) |
|
|
|
|
|
|
|
try: |
|
|
|
with tf: |
|
|
|
json.dump(obj, tf) |
|
|
|
os.rename(tf.name, fn) |
|
|
|
except: |
|
|
|
try: |
|
|
|
os.remove(tf.name) |
|
|
|
except OSError: |
|
|
|
pass |
|
|
|
raise |
|
|
|
|
|
|
|
|
|
|
|
if sys.version_info >= (2, 7): |
|
|
|
def find_xpath_attr(node, xpath, key, val): |
|
|
|
""" Find the xpath xpath[@key=val] """ |
|
|
|
assert re.match(r'^[a-zA-Z-]+$', key) |
|
|
|