def prepare_atom(self, atom): if not atom: msg = "\n*** WARNING: nothing to register for " \ "the data model '{nm:s}'!"\ "\n [probable reason: {fdata:s}/imported_data/{nm:s}/ not " \ "populated with sample files]".format(nm=self._dm.name, fdata=gr.fuddly_data_folder) raise UserWarning(msg) if isinstance(atom, dict): mb = NodeBuilder(dm=self._dm) desc_name = 'Unreadable Name' try: desc_name = atom['name'] atom = mb.create_graph_from_desc(atom) except: print('-' * 60) traceback.print_exc(file=sys.stdout) print('-' * 60) msg = "*** ERROR: problem encountered with the '{desc:s}' descriptor!".format( desc=desc_name) raise UserWarning(msg) if atom.env is None: self.update_atom(atom) else: self.update_atom(atom, existing_env=True) self._confs = self._confs.union(atom.gather_alt_confs()) return atom.name, atom
def build_data_model(self): ep_desc = \ {'name': 'EP_desc', 'contents': [ {'name': 'bLength', 'contents': UINT8(values=[7])}, {'name': 'bDescType', 'contents': UINT8(values=[USB_DEFS.DT_ENDPOINT])}, {'name': 'bEndpointAddr', 'contents': BitField(subfield_limits=[4,7,8], subfield_val_extremums=[[0,0b1111],None,[0,1]], subfield_values=[None,[0],None], endian=VT.LittleEndian), 'alt': [ {'conf': 'BULK-IN', 'contents': BitField(subfield_limits=[4,7,8], subfield_values=[[1],[0],[1]], endian=VT.LittleEndian)}, {'conf': 'BULK-OUT', 'contents': BitField(subfield_limits=[4,7,8], subfield_values=[[2],[0],[0]], endian=VT.LittleEndian)}]}, {'name': 'bmAttributes', 'contents': BitField(subfield_limits=[2,6,8], subfield_values=[[0,2,3],[0],[0]], endian=VT.LittleEndian), 'fuzz_weight': 5, 'alt': [ {'conf': 'ISO', 'contents': BitField(subfield_limits=[2,4,6,8], subfield_val_extremums=[None,[0,3],[0,2],None], subfield_values=[[1],None,None,[0]], endian=VT.LittleEndian)} ]}, {'name': 'wMaxPacketSize', 'contents': BitField(subfield_limits=[11,13,16], subfield_val_extremums=[None,[0,2],[0,0]], subfield_values=[[2**x for x in range(1,12)],None,[0]], endian=VT.LittleEndian), 'random': True, 'alt': [ {'conf': 'MSD', 'contents': BitField(subfield_limits=[11,13,16], subfield_val_extremums=[None,[0,2],[0,0]], subfield_values=[[0x8, 0x10, 0x20, 0x40],[0],[0]], endian=VT.LittleEndian)}]}, {'name': 'bInterval', 'contents': UINT8(values=[4]), 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[0])}]} ]} mb = NodeBuilder(add_env=False) ep_node = mb.create_graph_from_desc(ep_desc) msd_ep_bulkin = ep_node.get_clone('EP_BLKIN') msd_ep_bulkin.set_current_conf('MSD', recursive=True) msd_ep_bulkin.set_current_conf('BULK-IN', recursive=True) msd_ep_bulkout = ep_node.get_clone('EP_BLKOUT') msd_ep_bulkout.set_current_conf('MSD', recursive=True) msd_ep_bulkout.set_current_conf('BULK-OUT', recursive=True) interface_desc = \ {'name': 'Interface', 'contents': [ {'name': ('Ihdr', 2), 'contents': [ {'name': ('bLength', 2), 'contents': UINT8(values=[9])}, {'name': ('bDescType', 2), 'contents': UINT8(values=[USB_DEFS.DT_INTERFACE])}, {'name': 'bInterfaceNum', 'contents': UINT8(min=0, max=10)}, {'name': 'bAlternateSetting', 'contents': UINT8(values=[0, 1, 2, 3, 4])}, {'name': 'bNumEndpoints', # 'random': True, 'contents': UINT8(min=1, max=8, default=4), 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[2])} ]}, {'name': 'bInterfaceClass', 'contents': UINT8(values=[ USB_DEFS.USB_CLASS_MASS_STORAGE, USB_DEFS.USB_CLASS_PRINTER, USB_DEFS.USB_CLASS_HID, USB_DEFS.USB_CLASS_HUB, USB_DEFS.USB_CLASS_PHYSICAL, USB_DEFS.USB_CLASS_MISC, USB_DEFS.USB_CLASS_VENDOR_SPEC] ), 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[0x8])} ] }, {'name': 'bInterfaceSubClass', 'contents': UINT8(values=[0x06, 0, 1, 2, 3, 4, 5, 7, 8]), 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[0x6])} ]}, {'name': 'bInterfaceProtocol', 'contents': UINT8(values=[0x80, 0x06, 0, 1, 2]), 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[0x50])} ]}, {'name': 'iInterface', 'contents': UINT8(values=[USB_DEFS.STRINGID_INTERFACE])}, ]}, {'name': 'EP_Group', 'custo_clear': MH.Custo.NTerm.MutableClone, 'contents': [ {'qty_from': 'bNumEndpoints', 'contents': ep_node} ], 'alt': [ {'conf': 'MSD', 'contents': [ (msd_ep_bulkin, 1), (msd_ep_bulkout, 1), ]} ]} ]} mb = NodeBuilder(add_env=False) intf_node = mb.create_graph_from_desc(interface_desc) conf_desc = \ {'name': 'CONF', 'semantics': 'CONF_DESC', 'contents': [ {'name': 'hdr', 'contents': [ {'name': 'bLength', 'contents': UINT8(values=[9])}, {'name': 'bDescType', 'contents': UINT8(values=[USB_DEFS.DT_CONFIGURATION])}, {'name': 'wTotalLength', 'contents': LEN(vt=UINT16_le, base_len=9), 'node_args': 'Intf_Group'}, {'name': 'bNumInterfaces', 'contents': QTY('Interface', vt=UINT8), 'node_args': 'Intf_Group', 'alt': [ {'conf': 'MSD', 'contents': UINT8(values=[1])} ]}, {'name': 'bConfValue', 'contents': UINT8(min=1, max=50)}, {'name': 'iConf', 'contents': UINT8(values=[USB_DEFS.STRINGID_CONFIG])}, {'name': 'bmAttributes', 'contents': BitField(subfield_limits=[5,6,7,8], subfield_values=[[0],[1],[1],[1]], endian=VT.LittleEndian)}, {'name': 'bMaxPower', 'contents': UINT8(values=[50])}, ]}, {'name': 'Intf_Group', 'custo_clear': MH.Custo.NTerm.MutableClone, 'contents': [ {'qty': (1,5), 'contents': intf_node} ], 'alt': [ {'conf': 'MSD', 'contents': [ {'qty': 1, 'contents': intf_node.get_clone()} ]}, {'conf': 'BIGCONF', 'contents': [ {'qty': 1700, 'contents': intf_node.get_clone()} ]} ] }, ]} dev_desc = \ {'name': 'DEV', 'semantics': 'DEV_DESC', 'contents': [ {'name': 'bLength', 'contents': UINT8(values=[18])}, {'name': 'bDescType', 'contents': UINT8(values=[USB_DEFS.DT_DEVICE])}, {'name': 'bcdUSB', 'contents': UINT16_le(values=[0x200, 0x100])}, {'name': 'bDeviceClass', 'contents': UINT8(values=[0]), 'alt': [ {'conf': 'MS', # mass-storage 'contents': UINT8(values=[0])} ]}, {'name': 'bDeviceSubClass', 'contents': UINT8(values=[0]), 'alt': [ {'conf': 'MS', # mass-storage 'contents': UINT8(values=[0])} ]}, {'name': 'bDeviceProto', 'contents': UINT8(values=[0]), 'alt': [ {'conf': 'MS', # mass-storage 'contents': UINT8(values=[0])} ]}, {'name': 'bMaxPacketSize0', 'contents': UINT8(values=[64])}, {'name': 'idVendor', 'contents': UINT16_le(values=[0x1307])}, {'name': 'idProduct', 'contents': UINT16_le(values=[0x0165])}, {'name': 'bcdDevice', 'contents': UINT16_le(values=[0x100])}, {'name': 'iManufacturer', 'contents': UINT8(values=[USB_DEFS.STRINGID_MFR])}, {'name': 'iProduct', 'contents': UINT8(values=[USB_DEFS.STRINGID_PRODUCT])}, {'name': 'iSerialNumber', 'contents': UINT8(values=[USB_DEFS.STRINGID_SERIAL])}, {'name': 'bNumConfigs', 'contents': UINT8(values=[1])} ]} langid_desc = \ {'name': 'LANGID', 'semantics': 'LANGID_DESC', 'contents': [ {'name': 'bLength', 'contents': LEN(vt=UINT8,base_len=2), 'node_args': 'contents'}, {'name': 'bDescType', 'contents': UINT8(values=[USB_DEFS.DT_STRING])}, {'name': 'contents', 'contents': [ {'name': 'LangID', 'qty': (0,30), 'contents': UINT16_le(values=[0x040c, 0x0409])} ]}, ]} string_desc = \ {'name': 'STR', 'semantics': 'STRING_DESC', 'contents': [ {'name': 'bLength', 'contents': UINT8()}, {'name': 'bDescType', 'contents': UINT8(values=[USB_DEFS.DT_STRING])}, {'name': 'contents', 'sync_enc_size_with': ('bLength', 2), 'contents': String(values=[u'\u00fcber string', u'what an interesting string!'], max_sz=126, max_encoded_sz=253, codec='utf-16-le')}, ]} self.register(conf_desc, dev_desc, langid_desc, string_desc)
def build_data_model(self): jpg_desc = \ {'name': 'jpg', 'contents': [ {'name': 'before_SOF', 'contents': String(size=0), 'absorb_csts': AbsNoCsts(), 'set_attrs': MH.Attr.Abs_Postpone, 'mutable': False}, {'name': 'SOF_hdr', 'contents': [ {'name': 'F_marker', 'contents': UINT16_be(values=[m for m in markers['SOF'].values()])}, {'name': 'Lf', 'contents': LEN(vt=UINT16_be, base_len=8), 'node_args': 'F_CompGroup', 'alt': [ {'conf': 'ABS', 'contents': UINT16_be()} ]}, {'name': 'P', 'contents': UINT8(values=[8,12])}, {'name': 'Y', 'contents': UINT16_be(max=65535), 'specific_fuzzy_vals': [65500]}, {'name': 'X', 'contents': UINT16_be(min=1, max=65535)}, {'name': 'Nf', 'contents': UINT8(min=1, max=255)}, {'name': 'F_CompGroup', 'custo_clear': MH.Custo.NTerm.MutableClone, 'contents': [ {'name': 'F_Comp', 'qty_from': 'Nf', 'contents': [ {'name': 'Cf', 'contents': UINT8(min=0, max=255)}, {'name': 'H&V', 'contents': BitField(subfield_sizes=[4,4], endian=VT.BigEndian, subfield_val_extremums=[[1,4], [1,4]], subfield_descs=['H sampling', 'V sampling'])}, {'name': 'Tq', 'contents': UINT8(min=0, max=3)}, ]} ]}, ]}, {'name': 'between_SOF_SOS', 'contents': String(), 'random': True, 'absorb_csts': AbsNoCsts(), 'set_attrs': MH.Attr.Abs_Postpone, 'mutable': False}, {'name': 'SOS_hdr', 'contents': [ {'name': 'S_marker', 'contents': UINT16_be(values=[markers['SOS']])}, {'name': 'Ls', 'contents': LEN(vt=UINT16_be, base_len=6), 'node_args': 'S_CompGroup', 'alt': [ {'conf': 'ABS', 'contents': UINT16_be()} ]}, {'name': 'Ns', 'contents': UINT8(min=1, max=4)}, {'name': 'S_CompGroup', 'custo_clear': MH.Custo.NTerm.MutableClone, 'contents': [ {'name': 'S_Comp', 'qty_from': 'Ns', 'contents': [ {'name': 'Cs', 'contents': UINT8()}, {'name': 'Td&Ta', 'contents': BitField(subfield_sizes=[4, 4], endian=VT.BigEndian, subfield_val_extremums=[[0, 3], [0, 3]], subfield_descs=['DC entropy', 'AC entropy'])}, ]} ]}, {'name': 'Ss', 'contents': UINT8(min=0, max=63)}, {'name': 'Se', 'contents': UINT8(min=0, max=63)}, {'name': 'Ah&Al', 'contents': BitField(subfield_sizes=[4, 4], endian=VT.BigEndian, subfield_val_extremums=[[0, 13], [0, 13]], subfield_descs=['approx high', 'approx low'])}, ]}, {'name': 'afterSOS', 'mutable': False, 'contents': String(min_sz=0), 'absorb_csts': AbsNoCsts()} ]} mb = NodeBuilder(delayed_jobs=True) self.jpg = mb.create_graph_from_desc(jpg_desc) self.jpg_dict = self.import_file_contents(extension='jpg') self.register(self.jpg, *self.jpg_dict.values())
def build_data_model(self): OCTET = "\x00-\xFF" # any 8-bit sequence of data CHAR = "\x00-\x7F" # any US-ASCII character (octets 0-127) UPALPHA = "A-Z" # any US-ASCII uppercase letter ("A".."Z") LOALPHA = "a-z" # any US-ASCII lowercase letter ("a".."z") ALPHA = UPALPHA + LOALPHA # UPALPHA or LOALPHA DIGIT = "0-9" # any US-ASCII digit ("0".."9") HEX = string.hexdigits CTL = "\x7F\x00-\x1F" # any US-ASCII control character (octets 0 - 31) and DEL (127) CR = "\x0D" # US-ASCII CR, carriage return (13)> LF = "\x0A" # US-ASCII LF, linefeed (10) SP = ' ' # US-ASCII SP, space (32) HT = '\x09' # US-ASCII HT, horizontal-tab (9) VCHAR = "\x21-\x7E" # visible (printing) characters (%x21-7E) CRLF = CR + LF LWS = "" + CRLF + "(" + SP + "|" + HT + ")+" # [CRLF] 1 * (SP | HT) OWS = "[" + SP + HT + "]*" # optional whitespace: *( SP / HTAB ) RWS = "[" + SP + HT + "]+" # required whitespace: 1*( SP / HTAB ) BWS = OWS # "bad" whitespace tchar = r"!#$%&'\*\+\-.^_`\|~" + DIGIT + ALPHA token = "[" + tchar + "]+" obs_text = "\x80-\xFF" obs_fold = CRLF + RWS # obsolete line folding qvalue = "0(.\d{0,3})?|1(.0{0,3})?" weight = OWS + ";" + OWS + "q=" + qvalue HTTP_message = \ {'name': 'HTTP_message', 'shape_type': MH.Ordered, 'contents': [ {'name': 'start_line', 'shape_type': MH.Pick, 'separator': {'contents': {'name': ('CRLF', 'start_line'), 'contents': CRLF}, 'prefix': False, 'suffix': True}, 'contents': [ {'name': 'request_line', 'separator': {'contents': {'name': ('SP', 'request_line'), 'contents': SP}, 'prefix': False, 'suffix': False}, 'contents': [ {'name': 'method', 'contents': token, 'alt': [ {'conf': 'standard', 'contents': "GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE" }] }, {'name': 'request_target', 'contents': String()}, # ... {'name': ('HTTP_version', 1), 'contents': '(HTTP)/[0-9]\.[0-9]'} ]}, {'name': 'status_line', 'separator': {'contents': {'name': ('SP', 'status_line'), 'contents': SP}, 'prefix': False, 'suffix': False}, 'contents': [ {'name': ('HTTP_version', 2), 'clone': ('HTTP_version', 1)}, {'name': 'status_code', 'contents': "\d{3}", 'alt': [ {'conf': 'standard', 'shape_type': MH.Pick, 'contents': [{'name': 'status_code_informational', 'contents': "100|101"}, {'name': 'status_code_successful', 'contents': "200|201|202|203|204|205|206"}, {'name': 'status_code_redirection', 'contents': "300|301|302|303|304|305|307"}, {'name': 'status_code_client_error', 'contents': "400|401|402|403|404|405|406|407|408|409|" + "410|411|412|413|414|415|416|417|426"}, {'name': 'status_code_server_error', 'contents': "500|501|502|503|504|505"} ] }] }, {'name': 'reason_phrase', 'contents': "[" + VCHAR + HT + SP + obs_text + "]*", 'alt': [ {'conf': 'standard', 'contents': [ {"name": "reason_phrase_100", "exists_if": (RawCondition('100'), 'status_code_informational'), "contents": "Continue"}, {"name": "reason_phrase_101", "exists_if": (RawCondition('101'), 'status_code_informational'), "contents": "Switching Protocols"}, {"name": "reason_phrase_200", "exists_if": (RawCondition('200'), 'status_code_successful'), "contents": "OK"}, {"name": "reason_phrase_201", "exists_if": (RawCondition('201'), 'status_code_successful'), "contents": "Created"}, {"name": "reason_phrase_202", "exists_if": (RawCondition('200'), 'status_code_successful'), "contents": "Accepted"}, {"name": "reason_phrase_203", "exists_if": (RawCondition('203'), 'status_code_successful'), "contents": "Non-Authoritative Information"}, {"name": "reason_phrase_204", "exists_if": (RawCondition('204'), 'status_code_successful'), "contents": "No Content"}, {"name": "reason_phrase_205", "exists_if": (RawCondition('205'), 'status_code_successful'), "contents": "Reset Content"}, {"name": "reason_phrase_206", "exists_if": (RawCondition('206'), 'status_code_successful'), "contents": "Partial Content"}, {"name": "reason_phrase_300", "exists_if": (RawCondition('300'), 'status_code_redirection'), "contents": "Multiple Choices"}, {"name": "reason_phrase_301", "exists_if": (RawCondition('301'), 'status_code_redirection'), "contents": "Moved Permanently"}, {"name": "reason_phrase_302", "exists_if": (RawCondition('302'), 'status_code_redirection'), "contents": "Found"}, {"name": "reason_phrase_303", "exists_if": (RawCondition('303'), 'status_code_redirection'), "contents": "See Other"}, {"name": "reason_phrase_304", "exists_if": (RawCondition('304'), 'status_code_redirection'), "contents": "Not Modified"}, {"name": "reason_phrase_305", "exists_if": (RawCondition('305'), 'status_code_redirection'), "contents": "Use Proxy"}, {"name": "reason_phrase_307", "exists_if": (RawCondition('307'), 'status_code_redirection'), "contents": "Temporary Redirect"}, {"name": "reason_phrase_400", "exists_if": (RawCondition('400'), 'status_code_client_error'), "contents": "Bad Request"}, {"name": "reason_phrase_401", "exists_if": (RawCondition('401'), 'status_code_client_error'), "contents": "Unauthorized"}, {"name": "reason_phrase_402", "exists_if": (RawCondition('402'), 'status_code_client_error'), "contents": "Payment Required"}, {"name": "reason_phrase_403", "exists_if": (RawCondition('403'), 'status_code_client_error'), "contents": "Forbidden"}, {"name": "reason_phrase_404", "exists_if": (RawCondition('404'), 'status_code_client_error'), "contents": "Not Found"}, {"name": "reason_phrase_405", "exists_if": (RawCondition('405'), 'status_code_client_error'), "contents": "Method Not Allowed"}, {"name": "reason_phrase_406", "exists_if": (RawCondition('406'), 'status_code_client_error'), "contents": "Not Acceptable"}, {"name": "reason_phrase_407", "exists_if": (RawCondition('407'), 'status_code_client_error'), "contents": "Proxy Authentication Required"}, {"name": "reason_phrase_408", "exists_if": (RawCondition('408'), 'status_code_client_error'), "contents": "Request Timeout"}, {"name": "reason_phrase_409", "exists_if": (RawCondition('409'), 'status_code_client_error'), "contents": "Conflict"}, {"name": "reason_phrase_410", "exists_if": (RawCondition('410'), 'status_code_client_error'), "contents": "Gone"}, {"name": "reason_phrase_411", "exists_if": (RawCondition('411'), 'status_code_client_error'), "contents": "Length Required"}, {"name": "reason_phrase_412", "exists_if": (RawCondition('412'), 'status_code_client_error'), "contents": "Precondition Failed"}, {"name": "reason_phrase_413", "exists_if": (RawCondition('413'), 'status_code_client_error'), "contents": "Payload Too Large"}, {"name": "reason_phrase_414", "exists_if": (RawCondition('414'), 'status_code_client_error'), "contents": "URI Too Long"}, {"name": "reason_phrase_415", "exists_if": (RawCondition('415'), 'status_code_client_error'), "contents": "Unsupported Media Type"}, {"name": "reason_phrase_416", "exists_if": (RawCondition('416'), 'status_code_client_error'), "contents": "Range Not Satisfiable"}, {"name": "reason_phrase_417", "exists_if": (RawCondition('417'), 'status_code_client_error'), "contents": "Expectation Failed"}, {"name": "reason_phrase_426", "exists_if": (RawCondition('426'), 'status_code_client_error'), "contents": "Upgrade Required"}, {"name": "reason_phrase_500", "exists_if": (RawCondition('500'), 'status_code_server_error'), "contents": "Internal Server Error"}, {"name": "reason_phrase_501", "exists_if": (RawCondition('501'), 'status_code_server_error'), "contents": "Not Implemented"}, {"name": "reason_phrase_502", "exists_if": (RawCondition('502'), 'status_code_server_error'), "contents": "Bad Gateway"}, {"name": "reason_phrase_503", "exists_if": (RawCondition('503'), 'status_code_server_error'), "contents": "Service Unavailable"}, {"name": "reason_phrase_504", "exists_if": (RawCondition('504'), 'status_code_server_error'), "contents": "Gateway Timeout"}, {"name": "reason_phrase_505", "exists_if": (RawCondition('505'), 'status_code_server_error'), "contents": "HTTP Version Not Supported"}, ]}] }]} ]}, {'name': 'header_fields', 'separator': {'contents': {'name': ('CRLF', "header_fields"), 'contents': CRLF}, 'prefix': False, 'suffix': True}, 'contents':[ {'name': 'header_field', 'qty': (0, -1), 'contents': [ {'name': 'field_name', 'contents': token, 'alt': [ {'conf': 'standard', 'shape_type': MH.Pick, 'contents': [ {'name': 'field_name_controls', 'shape_type': MH.Pick, 'contents': [ {'name': 'field_name_others', 'contents': 'Cache-Control|Expect|Host|Pragma|Range|TE'}, {'name':'field_name_max_forwards', 'contents': 'Max-Forwards', 'exists_if': (RawCondition(['TRACE', 'OPTIONS']), 'method')} ]}, {'name': 'field_name_conditionals', 'contents': 'If-Match|If-None-Match|If-Modified-Since|' + 'If-Unmodified-Since|If-Range'}, {'name': 'field_name_content_negotiation', 'contents': 'Accept|Accept-Charset|Accept-Encoding|Accept-Language'}, {'name': 'field_name_authentication_credentials', 'contents': 'Authorization|Proxy-Authorization'}, {'name': 'field_name_request_context', 'contents': 'From|Referer|User-Agent'}, ]} ]}, {'name': 'header_field_name_value_separator:', 'contents': ":"}, {'name': 'header_field_ows_1', 'contents': OWS}, {'name': 'field_value', 'shape_type': MH.Pick, 'contents': [ {'name': 'field_content', 'qty': (1, -1), 'separator': {'contents': {'name': 'RWS', 'contents': RWS}, 'prefix': False, 'suffix': False}, 'contents': [{'name': 'field_vchar', 'contents': "[" + VCHAR + obs_text + "]"}]}, {'name': 'obs_fold', 'contents': obs_fold} ], 'alt': [ {'conf': 'standard', 'contents': [ {'name': 'field_value_expect', 'exists_if': (RawCondition('Expect'), 'field_name_controls'), 'contents': '100-continue'}, {'name': 'field_value_max_forwards', 'exists_if': (RawCondition('Max-Forwards'), 'field_name_controls'), 'contents': '\d+'}, # { ... } ]} ]}, {'name': 'header_field_ows_2', 'clone': 'header_field_ows_1'}, ]} ]}, {'name': 'CRLF', 'contents': CRLF}, {'name': 'message_body', 'contents': "[" + OCTET + "]*"} ]} model_helper = NodeBuilder(self) model_root_node = model_helper.create_graph_from_desc(HTTP_message) model_root_node.set_current_conf(conf="standard", recursive=True) self.register(model_root_node)