def _generate_struct_class_repr(self, data_type): """ Generates something like: def __repr__(self): return 'Employee(first_name={!r}, last_name={!r}, age={!r})'.format( self._first_name_value, self._last_name_value, self._age_value, ) """ self.emit('def __repr__(self):') with self.indent(): if data_type.all_fields: constructor_kwargs_fmt = ', '.join( '{}={{!r}}'.format(fmt_var(f.name, True)) for f in data_type.all_fields) self.emit("return '{}({})'.format(".format( class_name_for_data_type(data_type), constructor_kwargs_fmt, )) with self.indent(): for f in data_type.all_fields: self.emit("self._{}_value,".format(fmt_var(f.name))) self.emit(")") else: self.emit("return '%s()'" % class_name_for_data_type(data_type)) self.emit()
def _generate_union_class_reflection_attributes(self, ns, data_type): """ Adds a class attribute for each union member assigned to a validator. Also adds an attribute that is a map from tag names to validators. """ class_name = fmt_class(data_type.name) for field in data_type.fields: field_name = fmt_var(field.name) validator_name = generate_validator_constructor( ns, field.data_type) self.emit('{}._{}_validator = {}'.format( class_name, field_name, validator_name)) with self.block('{}._tagmap ='.format(class_name)): for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format( class_name, var_name) self.emit("'{}': {},".format(var_name, validator_name)) if data_type.parent_type: self.emit('{0}._tagmap.update({1}._tagmap)'.format( class_name, class_name_for_data_type(data_type.parent_type, ns))) self.emit()
def _generate_struct_class_repr(self, data_type): """ Generates something like: def __repr__(self): return 'Employee(first_name={!r}, last_name={!r}, age={!r})'.format( self._first_name_value, self._last_name_value, self._age_value, ) """ self.emit('def __repr__(self):') with self.indent(): if data_type.all_fields: constructor_kwargs_fmt = ', '.join( '{}={{!r}}'.format(fmt_var(f.name, True)) for f in data_type.all_fields) self.emit("return '{}({})'.format(".format( class_name_for_data_type(data_type), constructor_kwargs_fmt, )) with self.indent(): for f in data_type.all_fields: self.emit("self._{}_value,".format(fmt_var(f.name))) self.emit(")") else: self.emit("return '%s()'" % class_name_for_data_type(data_type)) self.emit()
def _generate_union_class_reflection_attributes(self, ns, data_type): """ Adds a class attribute for each union member assigned to a validator. Also adds an attribute that is a map from tag names to validators. """ class_name = fmt_class(data_type.name) for field in data_type.fields: field_name = fmt_var(field.name) validator_name = generate_validator_constructor( ns, field.data_type) self.emit('{}._{}_validator = {}'.format( class_name, field_name, validator_name)) with self.block('{}._tagmap ='.format(class_name)): for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format( class_name, var_name) self.emit("'{}': {},".format(var_name, validator_name)) if data_type.parent_type: self.emit('{0}._tagmap.update({1}._tagmap)'.format( class_name, class_name_for_data_type(data_type.parent_type, ns))) self.emit()
def _generate_union_class(self, ns, data_type): # type: (ApiNamespace, Union) -> None """Defines a Python class that represents a union in Stone.""" self.emit(self._class_declaration_for_type(ns, data_type)) with self.indent(): self.emit('"""') if data_type.doc: self.emit_wrapped_text( self.process_doc(data_type.doc, self._docf)) self.emit() self.emit_wrapped_text( 'This class acts as a tagged union. Only one of the ``is_*`` ' 'methods will return true. To get the associated value of a ' 'tag (if one exists), use the corresponding ``get_*`` method.') if data_type.has_documented_fields(): self.emit() for field in data_type.fields: if not field.doc: continue if is_void_type(field.data_type): ivar_doc = ':ivar {}: {}'.format( fmt_var(field.name), self.process_doc(field.doc, self._docf)) elif is_user_defined_type(field.data_type): ivar_doc = ':ivar {} {}: {}'.format( fmt_class(field.data_type.name), fmt_var(field.name), self.process_doc(field.doc, self._docf)) else: ivar_doc = ':ivar {} {}: {}'.format( self._python_type_mapping(ns, field.data_type), fmt_var(field.name), field.doc) self.emit_wrapped_text(ivar_doc, subsequent_prefix=' ') self.emit('"""') self.emit() self._generate_union_class_vars(data_type) self._generate_union_class_variant_creators(ns, data_type) self._generate_union_class_is_set(data_type) self._generate_union_class_get_helpers(ns, data_type) self._generate_union_class_repr(data_type) self.emit('{0}_validator = bv.Union({0})'.format( class_name_for_data_type(data_type) )) self.emit()
def _generate_union_class(self, ns, data_type): # type: (ApiNamespace, Union) -> None """Defines a Python class that represents a union in Stone.""" self.emit(self._class_declaration_for_type(ns, data_type)) with self.indent(): self.emit('"""') if data_type.doc: self.emit_wrapped_text( self.process_doc(data_type.doc, self._docf)) self.emit() self.emit_wrapped_text( 'This class acts as a tagged union. Only one of the ``is_*`` ' 'methods will return true. To get the associated value of a ' 'tag (if one exists), use the corresponding ``get_*`` method.') if data_type.has_documented_fields(): self.emit() for field in data_type.fields: if not field.doc: continue if is_void_type(field.data_type): ivar_doc = ':ivar {}: {}'.format( fmt_var(field.name), self.process_doc(field.doc, self._docf)) elif is_user_defined_type(field.data_type): ivar_doc = ':ivar {} {}: {}'.format( fmt_class(field.data_type.name), fmt_var(field.name), self.process_doc(field.doc, self._docf)) else: ivar_doc = ':ivar {} {}: {}'.format( self._python_type_mapping(ns, field.data_type), fmt_var(field.name), field.doc) self.emit_wrapped_text(ivar_doc, subsequent_prefix=' ') self.emit('"""') self.emit() self._generate_union_class_vars(data_type) self._generate_union_class_variant_creators(ns, data_type) self._generate_union_class_is_set(data_type) self._generate_union_class_get_helpers(ns, data_type) self._generate_union_class_repr(data_type) self.emit('{0}_validator = bv.Union({0})'.format( class_name_for_data_type(data_type) )) self.emit()
def _generate_struct_class(self, ns, data_type): """Defines a Python class that represents a struct in Stone.""" self.emit(self._class_declaration_for_type(ns, data_type)) with self.indent(): if data_type.has_documented_type_or_fields(): self.emit('"""') if data_type.doc: self.emit_wrapped_text( self.process_doc(data_type.doc, self._docf)) if data_type.has_documented_fields(): self.emit() for field in data_type.fields: if not field.doc: continue self.emit_wrapped_text(':ivar {}: {}'.format( fmt_var(field.name), self.process_doc(field.doc, self._docf)), subsequent_prefix=' ') self.emit('"""') self.emit() self._generate_struct_class_slots(data_type) self._generate_struct_class_has_required_fields(data_type) self._generate_struct_class_init(data_type) self._generate_struct_class_properties(ns, data_type) self._generate_struct_class_repr(data_type) if data_type.has_enumerated_subtypes(): validator = 'StructTree' else: validator = 'Struct' self.emit('{0}_validator = bv.{1}({0})'.format( class_name_for_data_type(data_type), validator, )) self.emit()
def _generate_struct_class(self, ns, data_type): """Defines a Python class that represents a struct in Stone.""" self.emit(self._class_declaration_for_type(ns, data_type)) with self.indent(): if data_type.has_documented_type_or_fields(): self.emit('"""') if data_type.doc: self.emit_wrapped_text( self.process_doc(data_type.doc, self._docf)) if data_type.has_documented_fields(): self.emit() for field in data_type.fields: if not field.doc: continue self.emit_wrapped_text(':ivar {}: {}'.format( fmt_var(field.name), self.process_doc(field.doc, self._docf)), subsequent_prefix=' ') self.emit('"""') self.emit() self._generate_struct_class_slots(data_type) self._generate_struct_class_has_required_fields(data_type) self._generate_struct_class_init(data_type) self._generate_struct_class_properties(ns, data_type) self._generate_struct_class_repr(data_type) if data_type.has_enumerated_subtypes(): validator = 'StructTree' else: validator = 'Struct' self.emit('{0}_validator = bv.{1}({0})'.format( class_name_for_data_type(data_type), validator, )) self.emit()
def _generate_python_value(self, namespace, value): if is_tag_ref(value): return '{}.{}.{}'.format( namespace.name, class_name_for_data_type(value.union_data_type), fmt_var(value.tag_name)) else: return fmt_obj(value)
def _generate_python_value(self, namespace, value): if is_tag_ref(value): return '{}.{}.{}'.format( namespace.name, class_name_for_data_type(value.union_data_type), fmt_var(value.tag_name)) else: return fmt_obj(value)
def _generate_python_value(self, ns, value): if is_tag_ref(value): ref = '{}.{}'.format( class_name_for_data_type(value.union_data_type), fmt_var(value.tag_name)) if ns != value.union_data_type.namespace: ref = '%s.%s' % (value.union_data_type.namespace.name, ref) return ref else: return fmt_obj(value)
def _generate_python_value(self, ns, value): if is_tag_ref(value): ref = '{}.{}'.format( class_name_for_data_type(value.union_data_type), fmt_var(value.tag_name)) if ns != value.union_data_type.namespace: ref = '%s.%s' % (value.union_data_type.namespace.name, ref) return ref else: return fmt_obj(value)
def _generate_struct_class_init(self, data_type): """ Generates constructor. The constructor takes all possible fields as optional arguments. Any argument that is set on construction sets the corresponding field for the instance. """ args = ['self'] for field in data_type.all_fields: field_name_reserved_check = fmt_var(field.name, True) args.append('%s=None' % field_name_reserved_check) self.generate_multiline_list(args, before='def __init__', after=':') with self.indent(): lineno = self.lineno # Call the parent constructor if a super type exists if data_type.parent_type: class_name = class_name_for_data_type(data_type) self.generate_multiline_list( [ fmt_func(f.name, True) for f in data_type.parent_type.all_fields ], before='super({}, self).__init__'.format(class_name)) # initialize each field for field in data_type.fields: field_var_name = fmt_var(field.name) self.emit('self._{}_value = None'.format(field_var_name)) self.emit('self._{}_present = False'.format(field_var_name)) # handle arguments that were set for field in data_type.fields: field_var_name = fmt_var(field.name, True) self.emit('if {} is not None:'.format(field_var_name)) with self.indent(): self.emit('self.{0} = {0}'.format(field_var_name)) if lineno == self.lineno: self.emit('pass') self.emit()
def _generate_struct_class_slots(self, data_type): """Creates a slots declaration for struct classes. Slots are an optimization in Python. They reduce the memory footprint of instances since attributes cannot be added after declaration. """ with self.block('__slots__ =', delim=('[', ']')): for field in data_type.fields: field_name = fmt_var(field.name) self.emit("'_%s_value'," % field_name) self.emit("'_%s_present'," % field_name) self.emit()
def _generate_struct_class_slots(self, data_type): """Creates a slots declaration for struct classes. Slots are an optimization in Python. They reduce the memory footprint of instances since attributes cannot be added after declaration. """ with self.block('__slots__ =', delim=('[', ']')): for field in data_type.fields: field_name = fmt_var(field.name) self.emit("'_%s_value'," % field_name) self.emit("'_%s_present'," % field_name) self.emit()
def _generate_struct_class_init(self, data_type): """ Generates constructor. The constructor takes all possible fields as optional arguments. Any argument that is set on construction sets the corresponding field for the instance. """ args = ['self'] for field in data_type.all_fields: field_name_reserved_check = fmt_var(field.name, True) args.append('%s=None' % field_name_reserved_check) self.generate_multiline_list(args, before='def __init__', after=':') with self.indent(): lineno = self.lineno # Call the parent constructor if a super type exists if data_type.parent_type: class_name = class_name_for_data_type(data_type) self.generate_multiline_list( [fmt_func(f.name, True) for f in data_type.parent_type.all_fields], before='super({}, self).__init__'.format(class_name)) # initialize each field for field in data_type.fields: field_var_name = fmt_var(field.name) self.emit('self._{}_value = None'.format(field_var_name)) self.emit('self._{}_present = False'.format(field_var_name)) # handle arguments that were set for field in data_type.fields: field_var_name = fmt_var(field.name, True) self.emit('if {} is not None:'.format(field_var_name)) with self.indent(): self.emit('self.{0} = {0}'.format(field_var_name)) if lineno == self.lineno: self.emit('pass') self.emit()
def _generate_namespace_module(self, namespace): for data_type in namespace.linearize_data_types(): if not is_struct_type(data_type): # Only handle user-defined structs (avoid unions and primitives) continue # Define a class for each struct class_def = 'class {}(object):'.format(fmt_class(data_type.name)) self.emit(class_def) with self.indent(): if data_type.doc: self.emit('"""') self.emit_wrapped_text(data_type.doc) self.emit('"""') self.emit() # Define constructor to take each field args = ['self'] for field in data_type.fields: args.append(fmt_var(field.name)) self.generate_multiline_list(args, 'def __init__', ':') with self.indent(): if data_type.fields: self.emit() # Body of init should assign all init vars for field in data_type.fields: if field.doc: self.emit_wrapped_text(field.doc, '# ', '# ') member_name = fmt_var(field.name) self.emit('self.{0} = {0}'.format(member_name)) else: self.emit('pass') self.emit()
def _generate_struct_class_init(self, ns, struct): # type: (ApiNamespace, Struct) -> None args = [] for field in struct.all_fields: field_name_reserved_check = fmt_var(field.name, True) field_type = self.map_stone_type_to_pep484_type( ns, field.data_type) args.append("{field_name}: {field_type} = ...".format( field_name=field_name_reserved_check, field_type=field_type, )) self.generate_multiline_list(before='def __init__', items=["self"] + args, after=' -> None: ...')
def _generate_union_class_vars(self, ns, data_type): # type: (ApiNamespace, Union) -> None lineno = self.lineno # Generate stubs for class variables so that IDEs like PyCharms have an # easier time detecting their existence. for field in data_type.fields: if is_void_type(field.data_type): field_name = fmt_var(field.name) field_type = class_name_for_data_type(data_type, ns) self.emit('{field_name} = ... # type: {field_type}'.format( field_name=field_name, field_type=field_type, )) if lineno != self.lineno: self.emit()
def _generate_struct_class_init(self, ns, struct): # type: (ApiNamespace, Struct) -> None args = [] for field in struct.all_fields: field_name_reserved_check = fmt_var(field.name, True) field_type = self.map_stone_type_to_pep484_type(ns, field.data_type) args.append( "{field_name}: {field_type} = ...".format( field_name=field_name_reserved_check, field_type=field_type, ) ) self.generate_multiline_list( before='def __init__', items=["self"] + args, after=' -> None: ...')
def _generate_union_class_vars(self, ns, data_type): # type: (ApiNamespace, Union) -> None lineno = self.lineno # Generate stubs for class variables so that IDEs like PyCharms have an # easier time detecting their existence. for field in data_type.fields: if is_void_type(field.data_type): field_name = fmt_var(field.name) field_type = class_name_for_data_type(data_type, ns) self.emit('{field_name} = ... # type: {field_type}'.format( field_name=field_name, field_type=field_type, )) if lineno != self.lineno: self.emit()
def _generate_union_class_vars(self, data_type): """ Adds a _catch_all_ attribute to each class. Also, adds a placeholder attribute for the construction of union members of void type. """ lineno = self.lineno if data_type.catch_all_field: self.emit("_catch_all = '%s'" % data_type.catch_all_field.name) elif not data_type.parent_type: self.emit('_catch_all = None') # Generate stubs for class variables so that IDEs like PyCharms have an # easier time detecting their existence. for field in data_type.fields: if is_void_type(field.data_type): field_name = fmt_var(field.name) self.emit('# Attribute is overwritten below the class definition') self.emit('{} = None'.format(field_name)) if lineno != self.lineno: self.emit()
def _generate_union_class_vars(self, data_type): """ Adds a _catch_all_ attribute to each class. Also, adds a placeholder attribute for the construction of union members of void type. """ lineno = self.lineno if data_type.catch_all_field: self.emit("_catch_all = '%s'" % data_type.catch_all_field.name) elif not data_type.parent_type: self.emit('_catch_all = None') # Generate stubs for class variables so that IDEs like PyCharms have an # easier time detecting their existence. for field in data_type.fields: if is_void_type(field.data_type): field_name = fmt_var(field.name) self.emit('# Attribute is overwritten below the class definition') self.emit('{} = None'.format(field_name)) if lineno != self.lineno: self.emit()
def _generate_route_helper(self, namespace, route, download_to_file=False): """Generate a Python method that corresponds to a route. :param namespace: Namespace that the route belongs to. :param bool download_to_file: Whether a special version of the route that downloads the response body to a file should be generated. This can only be used for download-style routes. """ arg_data_type = route.arg_data_type result_data_type = route.result_data_type request_binary_body = route.attrs.get('style') == 'upload' response_binary_body = route.attrs.get('style') == 'download' if download_to_file: assert response_binary_body, 'download_to_file can only be set ' \ 'for download-style routes.' self._generate_route_method_decl(namespace, route, arg_data_type, request_binary_body, method_name_suffix='_to_file', extra_args=['download_path']) else: self._generate_route_method_decl(namespace, route, arg_data_type, request_binary_body) with self.indent(): extra_request_args = None extra_return_arg = None footer = None if request_binary_body: extra_request_args = [('f', 'bytes', 'Contents to upload.')] elif download_to_file: extra_request_args = [('download_path', 'str', 'Path on local machine to save file.')] if response_binary_body: extra_return_arg = ':class:`requests.models.Response`' if not download_to_file: footer = DOCSTRING_CLOSE_RESPONSE if route.doc: func_docstring = self.process_doc(route.doc, self._docf) else: func_docstring = None self._generate_docstring_for_func( namespace, arg_data_type, result_data_type, route.error_data_type, overview=func_docstring, extra_request_args=extra_request_args, extra_return_arg=extra_return_arg, footer=footer, ) self._maybe_generate_deprecation_warning(route) # Code to instantiate a class for the request data type if is_void_type(arg_data_type): self.emit('arg = None') elif is_struct_type(arg_data_type): self.generate_multiline_list( [f.name for f in arg_data_type.all_fields], before='arg = {}.{}'.format(arg_data_type.namespace.name, fmt_class(arg_data_type.name)), ) elif not is_union_type(arg_data_type): raise AssertionError('Unhandled request type %r' % arg_data_type) # Code to make the request args = [ '{}.{}'.format(namespace.name, fmt_var(route.name)), "'{}'".format(namespace.name), 'arg' ] if request_binary_body: args.append('f') else: args.append('None') self.generate_multiline_list(args, 'r = self.request', compact=False) if download_to_file: self.emit('self._save_body_to_file(download_path, r[1])') if is_void_type(result_data_type): self.emit('return None') else: self.emit('return r[0]') else: if is_void_type(result_data_type): self.emit('return None') else: self.emit('return r') self.emit()
def _generate_route_helper(self, namespace, route, download_to_file=False): """Generate a Python method that corresponds to a route. :param namespace: Namespace that the route belongs to. :param bool download_to_file: Whether a special version of the route that downloads the response body to a file should be generated. This can only be used for download-style routes. """ arg_data_type = route.arg_data_type result_data_type = route.result_data_type request_binary_body = route.attrs.get('style') == 'upload' response_binary_body = route.attrs.get('style') == 'download' if download_to_file: assert response_binary_body, 'download_to_file can only be set ' \ 'for download-style routes.' self._generate_route_method_decl(namespace, route, arg_data_type, request_binary_body, method_name_suffix='_to_file', extra_args=['download_path']) else: self._generate_route_method_decl(namespace, route, arg_data_type, request_binary_body) with self.indent(): extra_request_args = None extra_return_arg = None footer = None if request_binary_body: extra_request_args = [('f', 'bytes', 'Contents to upload.')] elif download_to_file: extra_request_args = [('download_path', 'str', 'Path on local machine to save file.')] if response_binary_body: extra_return_arg = ':class:`requests.models.Response`' if not download_to_file: footer = DOCSTRING_CLOSE_RESPONSE if route.doc: func_docstring = self.process_doc(route.doc, self._docf) else: func_docstring = None self._generate_docstring_for_func( namespace, arg_data_type, result_data_type, route.error_data_type, overview=func_docstring, extra_request_args=extra_request_args, extra_return_arg=extra_return_arg, footer=footer, ) self._maybe_generate_deprecation_warning(route) # Code to instantiate a class for the request data type if is_void_type(arg_data_type): self.emit('arg = None') elif is_struct_type(arg_data_type): self.generate_multiline_list( [f.name for f in arg_data_type.all_fields], before='arg = {}.{}'.format( arg_data_type.namespace.name, fmt_class(arg_data_type.name)), ) elif not is_union_type(arg_data_type): raise AssertionError('Unhandled request type %r' % arg_data_type) # Code to make the request args = [ '{}.{}'.format(namespace.name, fmt_var(route.name)), "'{}'".format(namespace.name), 'arg'] if request_binary_body: args.append('f') else: args.append('None') self.generate_multiline_list(args, 'r = self.request', compact=False) if download_to_file: self.emit('self._save_body_to_file(download_path, r[1])') if is_void_type(result_data_type): self.emit('return None') else: self.emit('return r[0]') else: if is_void_type(result_data_type): self.emit('return None') else: self.emit('return r') self.emit()
def _generate_struct_class_reflection_attributes(self, ns, data_type): """ Generates two class attributes: * _all_field_names_: Set of all field names including inherited fields. * _all_fields_: List of tuples, where each tuple is (name, validator). If a struct has enumerated subtypes, then two additional attributes are generated: * _field_names_: Set of all field names excluding inherited fields. * _fields: List of tuples, where each tuple is (name, validator), and excludes inherited fields. These are needed because serializing a struct with enumerated subtypes requires knowing the fields defined in each level of the hierarchy. """ class_name = class_name_for_data_type(data_type) if data_type.parent_type: parent_type_class_name = class_name_for_data_type( data_type.parent_type, ns) else: parent_type_class_name = None for field in data_type.fields: field_name = fmt_var(field.name) validator_name = generate_validator_constructor(ns, field.data_type) self.emit('{}._{}_validator = {}'.format( class_name, field_name, validator_name)) if data_type.is_member_of_enumerated_subtypes_tree(): self.generate_multiline_list( ["'%s'" % field.name for field in data_type.fields], before='{}._field_names_ = set('.format(class_name), after=')', delim=('[', ']'), compact=False) if parent_type_class_name: self.emit( '{0}._all_field_names_ = ' '{1}._all_field_names_.union({0}._field_names_)' .format(class_name, parent_type_class_name)) else: self.emit('{0}._all_field_names_ = {0}._field_names_'.format( class_name)) else: if parent_type_class_name: before = ( '{}._all_field_names_ = ' '{}._all_field_names_.union(set(').format( class_name, parent_type_class_name) after = '))' else: before = '{}._all_field_names_ = set('.format(class_name) after = ')' self.generate_multiline_list( ["'%s'" % field.name for field in data_type.fields], before=before, after=after, delim=('[', ']'), compact=False) if data_type.is_member_of_enumerated_subtypes_tree(): items = [] for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format(class_name, var_name) items.append("('{}', {})".format(var_name, validator_name)) self.generate_multiline_list( items, before='{}._fields_ = '.format(class_name), delim=('[', ']'), compact=False, ) if parent_type_class_name: self.emit( '{0}._all_fields_ = ' '{1}._all_fields_ + {0}._fields_'.format( class_name, parent_type_class_name)) else: self.emit('{0}._all_fields_ = {0}._fields_'.format(class_name)) else: if parent_type_class_name: before = '{}._all_fields_ = {}._all_fields_ + '.format( class_name, parent_type_class_name) else: before = '{}._all_fields_ = '.format(class_name) items = [] for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format( class_name, var_name) items.append("('{}', {})".format(var_name, validator_name)) self.generate_multiline_list( items, before=before, delim=('[', ']'), compact=False) self.emit()
def _generate_struct_class_reflection_attributes(self, ns, data_type): """ Generates two class attributes: * _all_field_names_: Set of all field names including inherited fields. * _all_fields_: List of tuples, where each tuple is (name, validator). If a struct has enumerated subtypes, then two additional attributes are generated: * _field_names_: Set of all field names excluding inherited fields. * _fields: List of tuples, where each tuple is (name, validator), and excludes inherited fields. These are needed because serializing a struct with enumerated subtypes requires knowing the fields defined in each level of the hierarchy. """ class_name = class_name_for_data_type(data_type) if data_type.parent_type: parent_type_class_name = class_name_for_data_type( data_type.parent_type, ns) else: parent_type_class_name = None for field in data_type.fields: field_name = fmt_var(field.name) validator_name = generate_validator_constructor(ns, field.data_type) self.emit('{}._{}_validator = {}'.format( class_name, field_name, validator_name)) if data_type.is_member_of_enumerated_subtypes_tree(): self.generate_multiline_list( ["'%s'" % field.name for field in data_type.fields], before='{}._field_names_ = set('.format(class_name), after=')', delim=('[', ']'), compact=False) if parent_type_class_name: self.emit( '{0}._all_field_names_ = ' '{1}._all_field_names_.union({0}._field_names_)' .format(class_name, parent_type_class_name)) else: self.emit('{0}._all_field_names_ = {0}._field_names_'.format( class_name)) else: if parent_type_class_name: before = ( '{}._all_field_names_ = ' '{}._all_field_names_.union(set(').format( class_name, parent_type_class_name) after = '))' else: before = '{}._all_field_names_ = set('.format(class_name) after = ')' self.generate_multiline_list( ["'%s'" % field.name for field in data_type.fields], before=before, after=after, delim=('[', ']'), compact=False) if data_type.is_member_of_enumerated_subtypes_tree(): items = [] for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format(class_name, var_name) items.append("('{}', {})".format(var_name, validator_name)) self.generate_multiline_list( items, before='{}._fields_ = '.format(class_name), delim=('[', ']'), compact=False, ) if parent_type_class_name: self.emit( '{0}._all_fields_ = ' '{1}._all_fields_ + {0}._fields_'.format( class_name, parent_type_class_name)) else: self.emit('{0}._all_fields_ = {0}._fields_'.format(class_name)) else: if parent_type_class_name: before = '{}._all_fields_ = {}._all_fields_ + '.format( class_name, parent_type_class_name) else: before = '{}._all_fields_ = '.format(class_name) items = [] for field in data_type.fields: var_name = fmt_var(field.name) validator_name = '{}._{}_validator'.format( class_name, var_name) items.append("('{}', {})".format(var_name, validator_name)) self.generate_multiline_list( items, before=before, delim=('[', ']'), compact=False) self.emit()