def test_comment_parsing(): s = """ # Map comment 1 # Map comment 2 MAP NAME 'Test' # Name comment # Layer comment LAYER TYPE POLYGON # This is a polygon! END END""" p = Parser(include_comments=True) m = MapfileToDict(include_position=False, include_comments=True) ast = p.parse(s) print(p._comments) assert len(p._comments) == 5 print(ast.pretty()) d = m.transform(ast) # transform the rest print(json.dumps(d, indent=4)) pp = PrettyPrinter(indent=0, quote="'", newlinechar="\n") s = pp.pprint(d) print(s)
def test_all_maps(): sample_dir = os.path.join(os.path.dirname(__file__), "sample_maps") p = Parser(expand_includes=False) m = MapfileToDict(include_position=True) v = Validator() failing_maps = [] for fn in os.listdir(sample_dir): print(fn) try: ast = p.parse_file(os.path.join(sample_dir, fn)) d = m.transform(ast) errors = v.validate(d) try: assert(len(errors) == 0) except AssertionError as ex: logging.warning("Validation errors in %s ", fn) logging.warning(errors) except (BaseException, UnexpectedToken) as ex: logging.warning("Cannot process %s ", fn) logging.error(ex) failing_maps.append(fn) logging.warning(failing_maps)
def test_enumeration(): s = """ MAP EXTENT 0 0 100 100 DEBUG on NAME Test shapepath "test/path" LAYER CLASSITEM "Test" CLASS EXPRESSION "Field" STYLE SIZE [sizefield] END END END END """ p = Parser() m = MapfileToDict() ast = p.parse(s) d = m.transform(ast) print(d) logging.debug(json.dumps(d, indent=4)) pp = PrettyPrinter(indent=4, quote="'", newlinechar="\n") res = pp.pprint(d) print(res)
def to_dict(s): p = Parser() m = MapfileToDict() ast = p.parse(s) d = m.transform(ast) print(json.dumps(d, indent=4)) return d
def loads(s, cwd="", expand_includes=True): p = Parser(cwd=cwd, expand_includes=expand_includes) ast = p.parse(s) m = MapfileToDict() d = m.transform(ast) return d
def test_all_maps(): sample_dir = os.path.join(os.path.dirname(__file__), "sample_maps") p = Parser(expand_includes=False) m = MapfileToDict(include_position=True) v = Validator() failing_maps = [] for fn in os.listdir(sample_dir): print(fn) try: ast = p.parse_file(os.path.join(sample_dir, fn)) d = m.transform(ast) errors = v.validate(d) try: assert (len(errors) == 0) except AssertionError as ex: logging.warning("Validation errors in %s ", fn) logging.warning(errors) except (BaseException, UnexpectedToken) as ex: logging.warning("Cannot process %s ", fn) logging.error(ex) failing_maps.append(fn) logging.warning(failing_maps)
def open(fn, output_o_trace=False, expand_includes=True, include_comments=False, include_position=False, **kwargs): """ Load a Mapfile from the supplied filename into a Python dictionary. Parameters ---------- fn: string The path to the Mapfile, or partial Mapfile output_o_trace: boolean To include a trace of origin include files in the output: tuple (dict, list) expand_includes: boolean Load any ``INCLUDE`` files in the MapFile include_comments: boolean Include or discard comment strings from the Mapfile - *experimental* include_position: boolean Include the position of the Mapfile tokens in the output Returns ------- dict A Python dictionary representing the Mapfile in the mappyfile format trace_o_incl* A trace of the origin of lines for include files, use to find the original location of an error Example ------- To open a Mapfile from a filename and return it as a dictionary object:: d = mappyfile.open('mymap.map') Notes ----- Partial Mapfiles can also be opened, for example a file containing a ``LAYER`` object. """ p = Parser(expand_includes=expand_includes, include_comments=include_comments, **kwargs) ast, trace_o_incl = p.parse_file(fn) m = MapfileToDict(include_position=include_position, include_comments=include_comments, trace_o_incl=trace_o_incl, **kwargs) d = m.transform(ast) if output_o_trace == True: return d, trace_o_incl else: return d
def test_includes_nested_path(): p = Parser() ast = p.parse_file('./tests/samples/include1_nested_path.map') m = MapfileToDict() d = (m.transform(ast)) # works print(mappyfile.dumps(d))
def test_non_ascii(): p = Parser() ast = p.parse_file('./tests/samples/non_ascii.map') m = MapfileToDict() d = (m.transform(ast)) # works print(mappyfile.dumps(d))
def load(fn, cwd=None): p = Parser(cwd=cwd) ast = p.parse_file(fn) m = MapfileToDict() d = m.transform(ast) return d
def test_includes(): p = Parser() ast = p.parse_file('./tests/samples/include1.map') m = MapfileToDict() d = (m.transform(ast)) # works print(mappyfile.dumps(d)) assert d["name"] == "include_test"
def main(): s = """ MAP NAME 'blah' ANGLE 100 DEBUG on CONFIG "ON_MISSING_DATA" FAIL # can be quoted or non-quoted STATUS on # need to enforce lowercase EXTENT -100 -100 100 100 SIZE 400 400 PROJECTION AUTO END LAYER PROJECTION AUTO END STATUS ON NAME "hi" TYPE polygon FEATURE POINTS 1 1 50 50 1 50 1 1 END END CLASS STYLE COLOR 255 0 0 END END END #LAYER # NAME "hi2" # TYPE point #END END """ p = Parser() m = MapfileToDict() ast = p.parse(s) d = m.transform(ast) # test a value passed in from the editor d["status"] = "OFF" # need to convert to uppercase if not already? # d["layers"][0]["type"] = "POINTX" print(d) # s = schema["definitions"]["map"]["properties"]["status"] """
def test_includes_relative_path(): """ File location can be given as a full path to the file, or (in MapServer >= 4.10.1) as a path relative to the mapfile. http://mapserver.org/mapfile/include.html """ p = Parser() ast = p.parse_file('./tests/samples/include4.map') m = MapfileToDict() d = (m.transform(ast)) # works print(mappyfile.dumps(d))
def test_or_expression(): s = """ CLASS EXPRESSION (([val] = 'A') OR ([val] = 'B')) END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(d) print(json.dumps(d, indent=4)) assert(d["expression"] == "( ( [val] = 'A' ) OR ( [val] = 'B' ) )")
def test_boolean(): s = """ LAYER TRANSFORM TRUE TYPE POINT END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(d["transform"])
def test_boolean(): s = """ LAYER TRANSFORM TRUE TYPE POINT END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (d["transform"])
def test_or_expression(): s = """ CLASS EXPRESSION (([val] = 'A') OR ([val] = 'B')) END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(d) print(json.dumps(d, indent=4)) assert (d["expression"] == "( ( [val] = 'A' ) OR ( [val] = 'B' ) )")
def test_lowercase(): s = """ MAP NAME 'blah' ANGLE 100 DEBUG on CONFIG "ON_MISSING_DATA" FAIL # can be quoted or non-quoted STATUS on # need to enforce lowercase EXTENT -100 -100 100 100 SIZE 400 400 PROJECTION AUTO END LAYER PROJECTION AUTO END STATUS ON NAME "hi" TYPE polygon FEATURE POINTS 1 1 50 50 1 50 1 1 END END CLASS STYLE COLOR 255 0 0 END END END #LAYER # NAME "hi2" # TYPE point #END END """ p = Parser() m = MapfileToDict() ast = p.parse(s) d = m.transform(ast) print(json.dumps(d, indent=4)) errors = validate(s) print(errors) assert (len(errors) == 0)
def test_lowercase(): s = """ MAP NAME 'blah' ANGLE 100 DEBUG on CONFIG "ON_MISSING_DATA" FAIL # can be quoted or non-quoted STATUS on # need to enforce lowercase EXTENT -100 -100 100 100 SIZE 400 400 PROJECTION AUTO END LAYER PROJECTION AUTO END STATUS ON NAME "hi" TYPE polygon FEATURE POINTS 1 1 50 50 1 50 1 1 END END CLASS STYLE COLOR 255 0 0 END END END #LAYER # NAME "hi2" # TYPE point #END END """ p = Parser() m = MapfileToDict() ast = p.parse(s) d = m.transform(ast) print(json.dumps(d, indent=4)) errors = validate(s) print(errors) assert(len(errors) == 0)
def test_auto_projection(): s = """ MAP PROJECTION AUTO END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (len(d["projection"]) == 1)
def test_pattern(): s = """ STYLE PATTERN 10 1 50 50 1 50 1 1 END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (len(d["pattern"]) == 4) assert (len(d["pattern"][0]) == 2) assert (d["pattern"][0][0] == 10)
def get_dict(s): """ Parse, transform, and pretty print the result """ p = Parser() m = MapfileToDict() logging.info(inspect.stack()[1][3]) ast = p.parse(s) logging.debug(ast.pretty()) d = m.transform(ast) logging.debug(json.dumps(d, indent=4)) return d
def test_pattern(): s = """ STYLE PATTERN 10 1 50 50 1 50 1 1 END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["pattern"]) == 4) assert(len(d["pattern"][0]) == 2) assert(d["pattern"][0][0] == 10)
def test_auto_projection(): s = """ MAP PROJECTION AUTO END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["projection"]) == 1)
def load(fp, expand_includes=True, include_position=False, include_comments=False, **kwargs): """ Load a Mapfile from an open file or file-like object. Parameters ---------- fp: file A file-like object - as with all Mapfiles this should be encoded in "utf-8" expand_includes: boolean Load any ``INCLUDE`` files in the MapFile include_comments: boolean Include or discard comment strings from the Mapfile - *experimental* include_position: boolean Include the position of the Mapfile tokens in the output Returns ------- dict A Python dictionary representing the Mapfile in the mappyfile format Example ------- To open a Mapfile from a file and return it as a dictionary object:: with open('mymap.map') as fp: d = mappyfile.load(fp) Notes ----- Partial Mapfiles can also be opened, for example a file containing a ``LAYER`` object. """ p = Parser(expand_includes=expand_includes, include_comments=include_comments, **kwargs) ast = p.load(fp) m = MapfileToDict(include_position=include_position, include_comments=include_comments, **kwargs) d = m.transform(ast) return d
def open(fn, expand_includes=True, include_comments=False, include_position=False, **kwargs): """ Load a Mapfile from the supplied filename into a Python dictionary. Parameters ---------- fn: string The path to the Mapfile, or partial Mapfile expand_includes: boolean Load any ``INCLUDE`` files in the MapFile include_comments: boolean Include or discard comment strings from the Mapfile - *experimental* include_position: boolean Include the position of the Mapfile tokens in the output Returns ------- dict A Python dictionary representing the Mapfile in the mappyfile format Example ------- To open a Mapfile from a filename and return it as a dictionary object:: d = mappyfile.open('mymap.map') Notes ----- Partial Mapfiles can also be opened, for example a file containing a ``LAYER`` object. """ p = Parser(expand_includes=expand_includes, include_comments=include_comments, **kwargs) ast = p.parse_file(fn) m = MapfileToDict(include_position=include_position, include_comments=include_comments, **kwargs) d = m.transform(ast) return d
def test_oneline_label(): s = """ label type truetype size 8 font "default" end """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(d["type"] == "truetype") assert(d["size"] == 8) assert(d["font"] == "default") assert(d["__type__"] == "label")
def test_oneline_label(): s = """ label type truetype size 8 font "default" end """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (d["type"] == "truetype") assert (d["size"] == 8) assert (d["font"] == "default") assert (d["__type__"] == "label")
def main(msautotest_fld, create_new_copy=True): msautotest_copy = os.path.join(os.path.dirname(msautotest_fld), "msautotest_mappyfile") if create_new_copy: create_copy(msautotest_fld, msautotest_copy) parser = Parser() transformer = MapfileToDict() pp = PrettyPrinter() # these two maps aren't in utf8, see https://github.com/mapserver/mapserver/pull/5460 #ignore_list = ["wms_inspire_scenario1.map","wms_inspire_scenario2.map"] ignore_list = [] mapfiles = glob.glob(msautotest_fld + '/**/*.map') mapfiles = [f for f in mapfiles if os.path.basename(f) not in ignore_list] for fn in mapfiles: d = parse_mapfile(parser, transformer, pp, fn) output_file = fn.replace(msautotest_fld, msautotest_copy) mf = mappyfile.utils.write(d, output_file) # now try reading it again d = parse_mapfile(parser, transformer, pp, output_file)
def open(fn, expand_includes=True, include_comments=False, include_position=False): """ Load a Mapfile from the supplied filename into a Python dictionary :param string fn: The path to the Mapfile, or partial Mapfile :param boolean expand_includes: Load any ``INCLUDE`` files in the MapFile :param boolean include_comments: Include or discard comment strings from the Mapfile - *experimental* :param boolean include_position: Include the position of the Mapfile tokens in the output """ p = Parser(expand_includes=expand_includes, include_comments=include_comments) ast = p.parse_file(fn) m = MapfileToDict(include_position=include_position, include_comments=include_comments) d = m.transform(ast) return d
def test_config_directive(): s = """ MAP NAME 'ConfigMap' CONFIG MS_ERRORFILE "stderr" CONFIG "PROJ_DEBUG" "OFF" CONFIG "ON_MISSING_DATA" "IGNORE" END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["config"]) == 3)
def test_points(): s = """ FEATURE POINTS 1 1 50 50 1 50 1 1 END POINTS 100 100 50 50 100 50 100 100 END END """ p = Parser() ast = p.parse(s) t = MapfileToDict(include_position=True) d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["points"]) == 2) assert(len(d["points"][0]) == 4) assert(len(d["points"][0][0]) == 2) assert(d["points"][0][0][0] == 1)
def load(fp, expand_includes=True, include_position=False, include_comments=False): """ Load a Mapfile from a file-like object :param fp: A file-like object :param boolean expand_includes: Load any ``INCLUDE`` files in the MapFile :param boolean include_comments: Include or discard comment strings from the Mapfile - *experimental* :param boolean include_position: Include the position of the Mapfile tokens in the output """ p = Parser(expand_includes=expand_includes, include_comments=include_comments) ast = p.load(fp) m = MapfileToDict(include_position=include_position, include_comments=include_comments) d = m.transform(ast) return d
def loads(s, expand_includes=True, include_position=False, include_comments=False): """ Load a Mapfile from a string :param string s: The Mapfile, or partial Mapfile, text :param boolean expand_includes: Load any ``INCLUDE`` files in the MapFile :param boolean include_comments: Include or discard comment strings from the Mapfile - *experimental* :param boolean include_position: Include the position of the Mapfile tokens in the output """ p = Parser(expand_includes=expand_includes, include_comments=include_comments) ast = p.parse(s) m = MapfileToDict(include_position=include_position, include_comments=include_comments) d = m.transform(ast) return d
def test_points(): s = """ FEATURE POINTS 1 1 50 50 1 50 1 1 END POINTS 100 100 50 50 100 50 100 100 END END """ p = Parser() ast = p.parse(s) t = MapfileToDict(include_position=True) d = t.transform(ast) print(json.dumps(d, indent=4)) assert (len(d["points"]) == 2) assert (len(d["points"][0]) == 4) assert (len(d["points"][0][0]) == 2) assert (d["points"][0][0][0] == 1)
def test_config_directive(): s = """ MAP NAME 'ConfigMap' CONFIG MS_ERRORFILE "stderr" CONFIG "PROJ_DEBUG" "OFF" CONFIG "ON_MISSING_DATA" "IGNORE" END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (len(d["config"]) == 3)
def test_processing_directive(): s = """ LAYER NAME 'ProcessingLayer' PROCESSING 'BANDS=1' PROCESSING 'CONTOUR_ITEM=elevation' PROCESSING 'CONTOUR_INTERVAL=20' END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["processing"]) == 3)
def test_processing_directive(): s = """ LAYER NAME 'ProcessingLayer' PROCESSING 'BANDS=1' PROCESSING 'CONTOUR_ITEM=elevation' PROCESSING 'CONTOUR_INTERVAL=20' END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (len(d["processing"]) == 3)
def loads(s, expand_includes=True, include_position=False, include_comments=False, **kwargs): """ Load a Mapfile from a string Parameters ---------- s: string The Mapfile, or partial Mapfile, text expand_includes: boolean Load any ``INCLUDE`` files in the MapFile include_comments: boolean Include or discard comment strings from the Mapfile - *experimental* include_position: boolean Include the position of the Mapfile tokens in the output Returns ------- dict A Python dictionary representing the Mapfile in the mappyfile format Example ------- To open a Mapfile from a string and return it as a dictionary object:: s = '''MAP NAME "TEST" END''' d = mappyfile.loads(s) assert d["name"] == "TEST" """ p = Parser(expand_includes=expand_includes, include_comments=include_comments, **kwargs) ast = p.parse(s) m = MapfileToDict(include_position=include_position, include_comments=include_comments, **kwargs) d = m.transform(ast) return d
def output(): """ Parse, transform, and pretty print the result """ p = Parser() m = MapfileToDict() fn = r"D:\Temp\large.map" with open(fn) as f: s = f.read() ast = p.parse(s) ##print(ast) d = m.transform(ast) ##print(d) pp = PrettyPrinter(indent=0, newlinechar=" ", quote="'") pp.pprint(d)
def output(s): """ Parse, transform, and pretty print the result """ p = Parser() m = MapfileToDict(include_position=True) # https://stackoverflow.com/questions/900392/getting-the-caller-function-name-inside-another-function-in-python logging.info(inspect.stack()[1][3]) ast = p.parse(s) logging.debug(ast.pretty()) d = m.transform(ast) logging.debug(json.dumps(d, indent=4)) pp = PrettyPrinter(indent=0, newlinechar=" ", quote="'") s = pp.pprint(d) logging.debug(s) return s
def test_metadata(): s = """ MAP METADATA "wms_enable_request" "*" "MS_ENABLE_MODES" "!*" END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert (d["metadata"]["wms_enable_request"] == "*") assert (d["metadata"]["MS_ENABLE_MODES"] == "!*") assert (d["metadata"]["wms_ENABLE_request"] == "*") assert (d["metadata"]["MS_enable_MODES"] == "!*")
def output(s, include_position=True, schema_name="map"): """ Parse, transform, validate, and pretty print the result """ p = Parser() m = MapfileToDict(include_position=include_position) ast = p.parse(s) logging.debug(ast.pretty()) d = m.transform(ast) logging.debug(json.dumps(d, indent=4)) v = Validator() errors = v.validate(d, schema_name=schema_name) logging.error(errors) pp = PrettyPrinter(indent=0, newlinechar=" ", quote="'") s = pp.pprint(d) logging.debug(s) assert(len(errors) == 0) return s
def output(s, include_position=True, schema_name="map"): """ Parse, transform, validate, and pretty print the result """ p = Parser() m = MapfileToDict(include_position=include_position) ast = p.parse(s) logging.debug(ast.pretty()) d = m.transform(ast) logging.debug(json.dumps(d, indent=4)) v = Validator() errors = v.validate(d, schema_name=schema_name) logging.error(errors) pp = PrettyPrinter(indent=0, newlinechar=" ", quote="'") s = pp.pprint(d) logging.debug(s) assert (len(errors) == 0) return s
def test_metadata(): s = """ MAP METADATA "wms_enable_request" "*" "MS_ENABLE_MODES" "!*" END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(d["metadata"]["wms_enable_request"] == "*") assert(d["metadata"]["MS_ENABLE_MODES"] == "!*") assert(d["metadata"]["wms_ENABLE_request"] == "*") assert(d["metadata"]["MS_enable_MODES"] == "!*")
def test_empty_config_directive(): """ Check that a config dict can be added directly without needing to create a new dict separately """ s = """ MAP NAME 'ConfigMap' END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) d["config"]["ms_errorfile"] = "stderr" print(json.dumps(d, indent=4)) assert(d["config"]["ms_errorfile"] == "stderr") assert(d["config"]["MS_ERRORFILE"] == "stderr")
def test_header_comment2(): s = """ # Map comment 1 # Map comment 2 MAP # comment 2 NAME "Test" # name comment # post name comment END""" p = Parser(include_comments=True) ast = p.parse(s) print(p._comments) print(ast.pretty()) m = MapfileToDict(include_position=True, include_comments=True) d = m.transform(ast) print(json.dumps(d, indent=4)) pp = PrettyPrinter(indent=4, quote="'", newlinechar="\n") s = pp.pprint(d) print(s)
def test_projection(): s = """ MAP PROJECTION "proj=utm" "ellps=GRS80" "datum=NAD83" "zone=15" "units=m" "north" "no_defs" END END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(json.dumps(d, indent=4)) assert(len(d["projection"]) == 7)
def test_expression(): s = """ CLASS TEXT ([area]) EXPRESSION ([area]) END CLASS TEXT ("[area]") EXPRESSION ("[area]") END """ p = Parser() ast = p.parse(s) t = MapfileToDict() d = t.transform(ast) print(d) print(json.dumps(d, indent=4)) assert(d[0]["text"] == "([area])") assert(d[0]["expression"] == "([area])") assert(d[1]["text"] == "(\"[area]\")") assert(d[1]["expression"] == "(\"[area]\")")
def test_scaletoken(): s = """ SCALETOKEN NAME "%border%" VALUES "0" "ON" "255000000" "OFF" END END """ p = Parser() ast = p.parse(s) print(ast.pretty()) t = MapfileToDict() d = t.transform(ast) print(d) print(json.dumps(d, indent=4)) # print(dict(d["metadata"])) assert(d["__type__"] == "scaletoken") assert(d["values"]["0"] == "ON")
def output(fn): """ Parse, transform, and pretty print the result """ p = Parser(expand_includes=False, include_comments=True) m = MapfileToDict(include_position=True, include_comments=True) v = Validator() try: ast = p.parse_file(fn) # print(ast) d = m.transform(ast) logging.debug("Number of layers: {}".format(len(d["layers"]))) errors = v.validate(d, add_comments=True) assert(len(errors) == 0) except Exception as ex: logging.exception(ex) logging.warning("%s could not be successfully parsed", fn) d = None raise if d: try: s = mappyfile.utils.dumps(d) except Exception: logging.warning(json.dumps(d, indent=4)) logging.warning("%s could not be successfully re-written", fn) raise # now try reading it again ast = p.parse(s) d = m.transform(ast) errors = v.validate(d) assert(len(errors) == 0)
def output(s, include_position=True, schema_name="map"): """ Parse, transform, validate, and pretty print the result """ p = Parser() m = MapfileToDict(include_position=include_position) # https://stackoverflow.com/questions/900392/getting-the-caller-function-name-inside-another-function-in-python logging.info(inspect.stack()[1][3]) ast = p.parse(s) logging.debug(ast.pretty()) d = m.transform(ast) logging.debug(json.dumps(d, indent=4)) v = Validator() errors = v.validate(d, schema_name=schema_name) logging.error(errors) pp = PrettyPrinter(indent=0, newlinechar=" ", quote="'") s = pp.pprint(d) logging.debug(s) assert(len(errors) == 0) return s