def do_translation_override(port_specs, names, rows, opts): if 'name' in opts: names = opts['name'] if names is None: raise ValueError("Must specify name of port to use translation for") if isinstance(names, basestring) or not matplotlib.cbook.iterable(names): names = [names] should_reverse = opts.get('reverse', True) values_only = opts.get('values_only', False) (t, port_type, values) = \ parse_translation(rows, should_reverse) for name in names: print "TRANSLATING", name if name not in port_specs: port_specs[name] = InputPortSpec(name) port_specs[name].entry_types = ['enum'] port_specs[name].values = [values] if not values_only: port_specs[name].translations = t
def parse_argspec(obj_or_str): if isinstance(obj_or_str, basestring): obj_or_str = obj_or_str.strip() if not obj_or_str.endswith(":"): obj_or_str += ":" if not obj_or_str.startswith("def "): obj_or_str = "def " + obj_or_str try: tree = ast.parse(obj_or_str + "\n pass") except SyntaxError: # cannot parse the argspec print "*** CANNOT PARSE", obj_or_str return [] argspec_name = tree.body[0].name argspec_args = [a.id for a in tree.body[0].args.args] print tree.body[0].args.defaults argspec_defaults = [] for i, d in enumerate(tree.body[0].args.defaults): try: d_val = ast.literal_eval(d) except ValueError: d_val = None argspec_defaults.append(d_val) # argspec_defaults = \ # [ast.literal_eval(d) for d in tree.body[0].args.defaults] else: argspec = inspect.getargspec(obj_or_str) argspec_args = argspec.args argspec_defaults = argspec.defaults # print argspec if not argspec_defaults: start_defaults = len(argspec_args) + 1 else: start_defaults = len(argspec_args) - len(argspec_defaults) port_specs_list = [] has_self = False for i, arg in enumerate(argspec_args): if i == 0 and arg == "self": has_self = True continue port_spec = InputPortSpec(arg) port_spec.arg_pos = (i-1) if has_self else i if i >= start_defaults: port_spec.required = False default_val = argspec_defaults[i-start_defaults] if default_val is not None: port_spec.defaults = [str(default_val)] port_type = get_type_from_val(default_val) if port_type is not None: port_spec.port_type = port_type else: port_spec.required = True # port_specs[arg].entry_types = [None,] # port_specs[arg].values = [[]] # port_specs[arg].translations = [None,] port_specs_list.append(port_spec) return port_specs_list
def parse_argspec(obj_or_str): if isinstance(obj_or_str, basestring): obj_or_str = obj_or_str.strip() if not obj_or_str.endswith(":"): obj_or_str += ":" if not obj_or_str.startswith("def "): obj_or_str = "def " + obj_or_str try: tree = ast.parse(obj_or_str + "\n pass") except SyntaxError: # cannot parse the argspec print "*** CANNOT PARSE", obj_or_str return [] argspec_name = tree.body[0].name argspec_args = [a.id for a in tree.body[0].args.args] print tree.body[0].args.defaults argspec_defaults = [] for i, d in enumerate(tree.body[0].args.defaults): try: d_val = ast.literal_eval(d) except ValueError: d_val = None argspec_defaults.append(d_val) else: argspec = inspect.getargspec(obj_or_str) argspec_args = argspec.args argspec_defaults = argspec.defaults if not argspec_defaults: start_defaults = len(argspec_args) + 1 else: start_defaults = len(argspec_args) - len(argspec_defaults) port_specs_list = [] has_self = False for i, arg in enumerate(argspec_args): if i == 0 and arg == "self": has_self = True continue port_spec = InputPortSpec(arg) port_spec.arg_pos = (i - 1) if has_self else i if i >= start_defaults: port_spec.required = False default_val = argspec_defaults[i - start_defaults] if default_val is not None: port_spec.defaults = [default_val] port_type = get_type_from_val(default_val) if port_type is not None: port_spec.port_type = port_type else: port_spec.required = True port_specs_list.append(port_spec) return port_specs_list
def apply_diff(in_fname, diff_fname, out_fname): in_specs = SpecList.read_from_xml(in_fname) in_refs = dict((spec.code_ref, (i, spec)) for i, spec in enumerate(in_specs.module_specs)) in_ips_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.port_specs)) in_ops_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.output_port_specs)) in_alt_refs = dict(((spec.code_ref, ps.arg, alt_ps.name), (i, ps)) for spec in in_specs.module_specs for ps in spec.port_specs for i, alt_ps in enumerate(ps.alternate_specs)) tree = ET.parse(diff_fname) for elt in tree.getroot(): if elt.tag == "changeCustomCode": val = elt.getchildren()[0].text in_specs.custom_code = val continue code_ref = elt.get("code_ref") m_spec = in_refs[code_ref][1] port = elt.get("port", None) if port: port_type = elt.get("type") if port_type == "alternate": alt_name = elt.get("altName") if elt.tag.startswith('delete'): if port: if port_type == "input": idx = in_ips_refs[(code_ref, port)][0] del m_spec.port_specs[idx] elif port_type == 'output': idx = in_ops_refs[(code_ref, port)][0] del m_spec.output_port_specs[idx] elif port_type == 'alternate': ps = in_ips_refs[(code_ref, port)][1] idx = in_alt_refs[(code_ref, port, alt_name)][0] del ps.alternate_specs[idx] else: raise ValueError('Cannot access list of type "%s"' % port_type) else: idx = in_refs[code_ref][0] del in_specs.module_specs[idx] elif elt.tag.startswith('add'): for child in elt.getchildren(): if child.tag == 'value': for subchild in child.getchildren(): value = subchild if port: if port_type == "input": m_spec.port_specs.append(InputPortSpec.from_xml(value)) elif port_type == "output": m_spec.output_port_specs.append( OutputPortSpec.from_xml(value)) elif port_type == "alternate": ps = in_ips_refs[(code_ref, port)][1] ps.alternate_specs.append(AlternatePortSpec.from_xml(value)) else: raise ValueError('Cannot access list of type "%s"' % port_type) else: in_specs.module_specs.append(ModuleSpec.from_xml(value)) elif elt.tag.startswith('change'): attr = elt.get("attr") for child in elt.getchildren(): if child.tag == 'value': value = child.text if port: # KLUDGE to fix change from output_type to port_type if attr == "output_type": attr = "port_type" if port_type == "input": port_spec = in_ips_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "output": port_spec = in_ops_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "alternate": port_spec = in_alt_refs[(code_ref, port, alt_name)][1] setattr(port_spec, attr, value) else: setattr(m_spec, attr, value) in_specs.write_to_xml(out_fname)
def apply_diff(in_fname, diff_fname, out_fname): in_specs = SpecList.read_from_xml(in_fname) in_refs = dict((spec.code_ref, (i, spec)) for i, spec in enumerate(in_specs.module_specs)) in_ips_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.port_specs)) in_ops_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.output_port_specs)) in_alt_refs = dict(((spec.code_ref, ps.arg, alt_ps.name), (i, ps)) for spec in in_specs.module_specs for ps in spec.port_specs for i, alt_ps in enumerate(ps.alternate_specs)) tree = ET.parse(diff_fname) for elt in tree.getroot(): if elt.tag == "changeCustomCode": val = elt.getchildren()[0].text in_specs.custom_code = val continue code_ref = elt.get("code_ref") m_spec = in_refs[code_ref][1] port = elt.get("port", None) if port: port_type = elt.get("type") if port_type == "alternate": alt_name = elt.get("altName") if elt.tag.startswith('delete'): if port: if port_type == "input": idx = in_ips_refs[(code_ref, port)][0] del m_spec.port_specs[idx] elif port_type == 'output': idx = in_ops_refs[(code_ref, port)][0] del m_spec.output_port_specs[idx] elif port_type == 'alternate': ps = in_ips_refs[(code_ref, port)][1] idx = in_alt_refs[(code_ref, port, alt_name)][0] del ps.alternate_specs[idx] else: raise ValueError('Cannot access list of type "%s"' % port_type) else: idx = in_refs[code_ref][0] del in_specs.module_specs[idx] elif elt.tag.startswith('add'): for child in elt.getchildren(): if child.tag == 'value': for subchild in child.getchildren(): value = subchild if port: if port_type == "input": m_spec.port_specs.append(InputPortSpec.from_xml(value)) elif port_type == "output": # print "VALUE:", ET.tostring(value) m_spec.output_port_specs.append( OutputPortSpec.from_xml(value)) elif port_type == "alternate": ps = in_ips_refs[(code_ref, port)][1] ps.alternate_specs.append(AlternatePortSpec.from_xml(value)) else: raise ValueError('Cannot access list of type "%s"' % port_type) else: in_specs.module_specs.append(ModuleSpec.from_xml(value)) elif elt.tag.startswith('change'): attr = elt.get("attr") for child in elt.getchildren(): if child.tag == 'value': value = child.text if port: # KLUDGE to fix change from output_type to port_type if attr == "output_type": attr = "port_type" if port_type == "input": port_spec = in_ips_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "output": port_spec = in_ops_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "alternate": port_spec = in_alt_refs[(code_ref, port, alt_name)][1] setattr(port_spec, attr, value) else: setattr(m_spec, attr, value) # with f = open(diff_fname): # f_iter = f.__iter__() # for line in f_iter: # line = line.strip() # if not re.match("[+-C]", line): # raise RuntimeError("Problem parsing line\n%s" % line) # if line.startswith('-'): # arr = line.split(' ', 1) # prop = arr[1].split('.') # if len(prop) < 2: # idx = in_refs[prop[0]][0] # del in_specs.module_specs[idx] # else: # m_specs = in_refs[prop[0]][1] # if prop[1] == 'input': # idx = in_ips_refs[prop[0], prop[2]][0] # del m_specs.port_specs[idx] # elif prop[1] == 'output': # idx = in_ops_refs[prop[0], prop[2]][0] # del m_specs.output_port_specs[idx] # else: # raise ValueError('Cannot access list of type "%s"' % # prop[1]) # elif line.startswith('+'): # arr = line.split(' ', 2) # prop = arr[1].split('.') # if len(prop) < 2: # in_specs.module_specs.append(ModuleSpec.from_xml(arr[2])) # line.split(' ', 2) in_specs.write_to_xml(out_fname)
def parse_artists(artist_types, table_overrides={}): def get_module_name(obj): return obj.__name__ def get_super_name(obj): for base in obj.__bases__: if issubclass(base, Artist): return base.__name__ return "" module_specs = [] for klass in artist_types: (klass, module_name, super_name) = \ get_names(klass, get_module_name, get_super_name, "Mpl", "Properties") port_specs = {} insp = ArtistInspector(klass) klass_name = klass.__name__ klass_qualname = klass.__module__ + "." + klass_name for (s, t) in insp._get_setters_and_targets(): print "** %s **" % s if t.rsplit('.', 1)[0] != klass_qualname: # let inheritance work continue if s in port_specs: raise ValueError('duplicate port "%s"' % s) port_spec = InputPortSpec(s) port_specs[s] = port_spec accepts_raw = insp.get_valid_values(s) (accepts, deflists, tables, call_sigs) = \ parse_docutils_str(accepts_raw) if len(deflists) + len(tables) > 0: raise ValueError("accepts has deflists and/or tables") (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) if default_val is not None: port_spec.default_val = default_val if len(option_strs) > 0: port_spec.entry_types = ['enum'] port_spec.values = [option_strs] port_spec.hide = False docstring = getattr(insp.o, 'set_' + s).__doc__ if docstring is None: docstring = "" else: docstring = docstring % matplotlib.docstring.interpd.params match = _get_accepts_regex.search(docstring) if match is not None: print "STARTING DOCSTRING:", docstring groups = match.groups() if len(groups) > 2 and groups[2]: docstring = groups[0] + groups[2] else: docstring = groups[0] print "FIXED DOCSTRING:", docstring (cleaned_docstring, args, tables, call_sigs) = \ parse_docutils_str(docstring) port_spec.docstring = cleaned_docstring translations = None for (table_intro, header, rows) in tables: print "TABLE:", table_intro if (klass.__name__, s, table_intro) in table_overrides: (override_type, opts) = \ table_overrides[(klass.__name__, s, table_intro)] if override_type == "translation": do_translation_override(port_specs, s, rows, opts) continue elif override_type == "ports": table_intro = "kwarg" elif override_type == "skip": continue if len(header) != 2: raise ValueError("Table not two columns!") if translations is not None: raise ValueError("Two translations in one attr") (translations, pt2, values) = parse_translation(rows) port_spec.translations = translations port_spec.values = [values] port_types.extend(pt2) resolve_port_type(port_types, port_spec) constructor_port_specs = {} port_specs_list = parse_argspec(klass.__init__) for port_spec in port_specs_list: constructor_port_specs[port_spec.arg] = port_spec constructor_docstring = klass.__init__.__doc__ if constructor_docstring is not None: _, output_port_specs = process_docstring( constructor_docstring, constructor_port_specs, (klass.__name__, '__init__'), table_overrides) for arg, ps in constructor_port_specs.iteritems(): if arg not in port_specs: ps.constructor_arg = True ps.required = False port_specs[arg] = ps module_spec = ModuleSpec(module_name, super_name, klass_qualname, klass.__doc__, port_specs.values()) module_specs.append(module_spec) my_specs = SpecList(module_specs) return my_specs
def process_docstring(docstring, port_specs, parent, table_overrides): (cleaned_docstring, args, tables, call_sigs) = \ parse_docutils_str(docstring) if len(call_sigs) > 0: for call_sig in call_sigs: port_specs_list = parse_argspec(call_sig) for port_spec in port_specs_list: if port_spec.arg in port_specs: # have to reconcile the two old_port_spec = port_specs[port_spec.arg] resolve_port_type([port_spec.port_type], old_port_spec) if old_port_spec.defaults is None: if port_spec.defaults is not None: assign_port_values(old_port_spec, [], port_spec.defaults[0]) # old_port_spec.defaults = port_spec.defaults elif old_port_spec.defaults != port_spec.defaults: # keep it as the old spec is print "*** Different defaults!" + \ str(old_port_spec.defaults) + \ " : " + str(port_spec.defaults) assign_port_values(old_port_spec, [], old_port_spec.defaults[0]) else: port_specs[port_spec.arg] = port_spec output_port_specs = [] for (deflist_intro, deflist) in args: print "PROCESSING DEFLIST", deflist_intro if re.search("return value", deflist_intro, re.IGNORECASE): print " -> RETURN VALUE" for (name, accepts, port_doc) in deflist: (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) (pt2, _, dv2, _) = parse_description(port_doc) port_types.extend(pt2) if default_val is None: default_val = dv2 oport = OutputPortSpec(name, docstring=port_doc) resolve_port_type(port_types, oport) output_port_specs.append(oport) elif (re.search("argument", deflist_intro, re.IGNORECASE) or re.search("kwarg", deflist_intro, re.IGNORECASE)): print " -> ARGUMENTS" for (name, accepts, port_doc) in deflist: if name not in port_specs: port_specs[name] = InputPortSpec(name, docstring=port_doc) else: port_specs[name].docstring = port_doc (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) (pt2, _, dv2, _) = parse_description(port_doc) port_types.extend(pt2) if default_val is None: default_val = dv2 resolve_port_type(port_types, port_specs[name]) assign_port_values(port_specs[name], option_strs, default_val) for (table_intro, header, rows) in tables: print "GOT TABLE", table_intro, rows[0] table_key = parent + (table_intro, ) if table_key in table_overrides: (override_type, opts) = table_overrides[table_key] if override_type == "translation": do_translation_override(port_specs, None, rows, opts) continue elif override_type == "ports": table_intro = "kwarg" elif override_type == "skip": continue if re.search("return value", table_intro, re.IGNORECASE): print " -> RETURN" if len(rows[0]) != 2: raise ValueError("row that has more/less than 2 columns!") for (name, port_doc) in rows: (port_types, option_strs, default_val, allows_none) = \ parse_description(port_doc) oport = OutputPortSpec(name, docstring=port_doc) resolve_port_type(port_types, oport) output_port_specs.append(oport) elif (re.search("argument", table_intro, re.IGNORECASE) or re.search("kwarg", table_intro, re.IGNORECASE)): print " -> ARGUMENT" if len(rows[0]) != 2: raise ValueError("row that has more/less than 2 columns!") for (name, port_doc) in rows: if name not in port_specs: port_specs[name] = InputPortSpec(name, docstring=port_doc) else: port_specs[name].docstring = port_doc (port_types, option_strs, default_val, allows_none) = \ parse_description(port_doc) resolve_port_type(port_types, port_specs[name]) assign_port_values(port_specs[name], option_strs, default_val) else: raise ValueError("Unknown table: %s\n %s %s" % (parent, table_intro, header)) return cleaned_docstring, output_port_specs
def parse_artists(artist_types, table_overrides={}): def get_module_name(obj): return obj.__name__ def get_super_name(obj): for base in obj.__bases__: if issubclass(base, Artist): return base.__name__ return "" # if obj.__bases__[0].__name__ != 'object': # return obj.__bases__[0].__name__ # else: # return "" module_specs = [] for klass in artist_types: (klass, module_name, super_name) = \ get_names(klass, get_module_name, get_super_name, "Mpl", "Properties") port_specs = {} insp = ArtistInspector(klass) klass_name = klass.__name__ klass_qualname = klass.__module__ + "." + klass_name for (s, t) in insp._get_setters_and_targets(): print "** %s **" % s if t.rsplit('.',1)[0] != klass_qualname: # let inheritance work continue if s in port_specs: raise ValueError('duplicate port "%s"' % s) port_spec = InputPortSpec(s) port_specs[s] = port_spec accepts_raw = insp.get_valid_values(s) (accepts, deflists, tables, call_sigs) = \ parse_docutils_str(accepts_raw) if len(deflists) + len(tables) > 0: raise ValueError("accepts has deflists and/or tables") (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) # port_spec.port_type = port_type if default_val is not None: port_spec.default_val = default_val if len(option_strs) > 0: port_spec.entry_types = ['enum'] port_spec.values = [option_strs] port_spec.hide = False docstring = getattr(insp.o, 'set_' + s).__doc__ if docstring is None: docstring = "" else: docstring = docstring % matplotlib.docstring.interpd.params match = _get_accepts_regex.search(docstring) if match is not None: print "STARTING DOCSTRING:", docstring groups = match.groups() if len(groups) > 2 and groups[2]: docstring = groups[0] + groups[2] else: docstring = groups[0] print "FIXED DOCSTRING:", docstring (cleaned_docstring, args, tables, call_sigs) = \ parse_docutils_str(docstring) port_spec.docstring = cleaned_docstring translations = None for (table_intro, header, rows) in tables: print "TABLE:", table_intro if (klass.__name__, s, table_intro) in table_overrides: (override_type, opts) = \ table_overrides[(klass.__name__, s, table_intro)] if override_type == "translation": do_translation_override(port_specs, s, rows, opts) continue elif override_type == "ports": table_intro = "kwarg" elif override_type == "skip": continue if len(header) != 2: raise ValueError("Table not two columns!") if translations is not None: raise ValueError("Two translations in one attr") (translations, pt2, values) = parse_translation(rows) port_spec.translations = translations port_spec.values = [values] port_types.extend(pt2) resolve_port_type(port_types, port_spec) constructor_port_specs = {} port_specs_list = parse_argspec(klass.__init__) for port_spec in port_specs_list: constructor_port_specs[port_spec.arg] = port_spec constructor_docstring = klass.__init__.__doc__ if constructor_docstring is not None: _, output_port_specs = process_docstring(constructor_docstring, constructor_port_specs, (klass.__name__, '__init__'), table_overrides) for arg, ps in constructor_port_specs.iteritems(): if arg not in port_specs: ps.constructor_arg = True ps.required = False port_specs[arg] = ps module_spec = ModuleSpec(module_name, super_name, klass_qualname, klass.__doc__, port_specs.values()) module_specs.append(module_spec) my_specs = SpecList(module_specs) return my_specs
def process_docstring(docstring, port_specs, parent, table_overrides): (cleaned_docstring, args, tables, call_sigs) = \ parse_docutils_str(docstring) if len(call_sigs) > 0: for call_sig in call_sigs: port_specs_list = parse_argspec(call_sig) for port_spec in port_specs_list: if port_spec.arg in port_specs: # have to reconcile the two old_port_spec = port_specs[port_spec.arg] resolve_port_type([port_spec.port_type], old_port_spec) if old_port_spec.defaults is None: old_port_spec.defaults = port_spec.defaults elif old_port_spec.defaults != port_spec.defaults: # keep it as the old spec is print "*** Different defaults!" + \ str(old_port_spec.defaults) + \ " : " + str(port_spec.defaults) # raise RuntimeError("Different defaults! %s: %s" % ( # old_port_spec.defaults, # port_spec.defaults)) else: port_specs[port_spec.arg] = port_spec output_port_specs = [] for (deflist_intro, deflist) in args: print "PROCESSING DEFLIST", deflist_intro if re.search("return value", deflist_intro, re.IGNORECASE): print " -> RETURN VALUE" for (name, accepts, port_doc) in deflist: (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) (pt2, _, dv2, _) = parse_description(port_doc) port_types.extend(pt2) if default_val is None: default_val = dv2 oport = OutputPortSpec(name, docstring=port_doc) resolve_port_type(port_types, oport) output_port_specs.append(oport) elif (re.search("argument", deflist_intro, re.IGNORECASE) or re.search("kwarg", deflist_intro, re.IGNORECASE)): print " -> ARGUMENTS" for (name, accepts, port_doc) in deflist: if name not in port_specs: port_specs[name] = InputPortSpec(name, docstring=port_doc) else: port_specs[name].docstring = port_doc (port_types, option_strs, default_val, allows_none) = \ parse_description(accepts) (pt2, _, dv2, _) = parse_description(port_doc) port_types.extend(pt2) if default_val is None: default_val = dv2 resolve_port_type(port_types, port_specs[name]) if len(option_strs) > 0: port_specs[name].entry_types = ['enum'] port_specs[name].values = [option_strs] if default_val is not None: port_specs[name].defaults = [str(default_val)] for (table_intro, header, rows) in tables: print "GOT TABLE", table_intro, rows[0] table_key = parent + (table_intro,) if table_key in table_overrides: (override_type, opts) = table_overrides[table_key] if override_type == "translation": do_translation_override(port_specs, None, rows, opts) continue elif override_type == "ports": table_intro = "kwarg" elif override_type == "skip": continue if re.search("return value", table_intro, re.IGNORECASE): print " -> RETURN" if len(rows[0]) != 2: raise ValueError("row that has more/less than 2 columns!") for (name, port_doc) in rows: (port_types, option_strs, default_val, allows_none) = \ parse_description(port_doc) # (port_types, option_strs) = parse_desc(port_doc) # port_type_set = set(port_types) # # print port_name, "PORT_TYPES:", port_type_set # port_type = "UNKNOWN" # if len(port_type_set) == 1: # port_type = port_types[0] oport = OutputPortSpec(name, docstring=port_doc) resolve_port_type(oport, port_types) output_port_specs.append(oport) elif (re.search("argument", table_intro, re.IGNORECASE) or re.search("kwarg", table_intro, re.IGNORECASE)): print " -> ARGUMENT" if len(rows[0]) != 2: raise ValueError("row that has more/less than 2 columns!") for (name, port_doc) in rows: if name not in port_specs: port_specs[name] = InputPortSpec(name, docstring=port_doc) else: port_specs[name].docstring = port_doc (port_types, option_strs, default_val, allows_none) = \ parse_description(port_doc) # (port_types, option_strs) = parse_desc(port_doc) # port_type_set = set(port_types) # # print port_name, "PORT_TYPES:", port_type_set # port_type = "UNKNOWN" # if len(port_type_set) == 1: # port_specs[name].port_type = port_types[0] resolve_port_type(port_types, port_specs[name]) if len(option_strs) > 0: port_specs[name].entry_types = ['enum'] port_specs[name].values = [option_strs] if default_val is not None: port_specs[name].defaults = [str(default_val)] else: raise ValueError("Unknown table: %s\n %s %s" % ( parent, table_intro, header)) # print "HIT SPEC:", name # if name not in port_specs: # port_specs[name] = PortSpec(name, name, "UNKNOWN", "") # port_specs[name].translations = dict(reversed(r) for r in rows) return cleaned_docstring, output_port_specs
def apply_diff(in_fname, diff_fname, out_fname): in_specs = SpecList.read_from_xml(in_fname) in_refs = dict((spec.code_ref, (i, spec)) for i, spec in enumerate(in_specs.module_specs)) in_ips_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.port_specs)) in_ops_refs = dict(((spec.code_ref, ps.arg), (i, ps)) for spec in in_specs.module_specs for i, ps in enumerate(spec.output_port_specs)) in_alt_refs = dict(((spec.code_ref, ps.arg, alt_ps.name), (i, ps)) for spec in in_specs.module_specs for ps in spec.port_specs for i, alt_ps in enumerate(ps.alternate_specs)) tree = ET.parse(diff_fname) for elt in tree.getroot(): if elt.tag == "changeCustomCode": val = elt.getchildren()[0].text in_specs.custom_code = val continue code_ref = elt.get("code_ref") m_spec = in_refs[code_ref][1] port = elt.get("port", None) if port: port_type = elt.get("type") if port_type == "alternate": alt_name = elt.get("altName") if elt.tag.startswith('delete'): if port: if port_type == "input": idx = in_ips_refs[(code_ref, port)][0] del m_spec.port_specs[idx] elif port_type == 'output': idx = in_ops_refs[(code_ref, port)][0] del m_spec.output_port_specs[idx] elif port_type == 'alternate': ps = in_ips_refs[(code_ref, port)][1] idx = in_alt_refs[(code_ref, port, alt_name)][0] del ps.alternate_specs[idx] else: raise ValueError('Cannot access list of type "%s"' % port_type) else: idx = in_refs[code_ref][0] del in_specs.module_specs[idx] elif elt.tag.startswith('add'): for child in elt.getchildren(): if child.tag == 'value': for subchild in child.getchildren(): value = subchild if port: if port_type == "input": m_spec.port_specs.append(InputPortSpec.from_xml(value)) elif port_type == "output": m_spec.output_port_specs.append( OutputPortSpec.from_xml(value)) elif port_type == "alternate": ps = in_ips_refs[(code_ref, port)][1] ps.alternate_specs.append( AlternatePortSpec.from_xml(value)) else: raise ValueError('Cannot access list of type "%s"' % port_type) else: in_specs.module_specs.append(ModuleSpec.from_xml(value)) elif elt.tag.startswith('change'): attr = elt.get("attr") for child in elt.getchildren(): if child.tag == 'value': value = child.text if port: # KLUDGE to fix change from output_type to port_type if attr == "output_type": attr = "port_type" if port_type == "input": port_spec = in_ips_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "output": port_spec = in_ops_refs[(code_ref, port)][1] setattr(port_spec, attr, value) elif port_type == "alternate": port_spec = in_alt_refs[(code_ref, port, alt_name)][1] setattr(port_spec, attr, value) else: setattr(m_spec, attr, value) in_specs.write_to_xml(out_fname)