def test_classify_builtin_types(self): # Simple sanity check that all built-in types can have their # attributes classified. for name in dir(__builtin__): builtin = getattr(__builtin__, name) if isinstance(builtin, type): inspect.classify_class_attrs(builtin)
def show_class(class_name, cls, known_globals): base_names = [] for base in cls.__bases__: baseclass_fullname = str(base).split("'")[1] baseclass_name = baseclass_fullname.split('.')[-1] base_names.append(baseclass_name) print 'class %s(%s):' % (class_name, ', '.join(base_names)) print_doc_string(1, cls) # retrieve class attributes for name, value in get_data(cls): print_code_line(1, name + ' = ' + repr(value)) # retrieve methods for class_attr in inspect.classify_class_attrs(cls): #print '#', class_attr name, kind, owner_cls, attr = class_attr # a method may be inherited from a parent class # we want to only print methods defined in this # object. # also we only print methods. if owner_cls == cls and kind != 'data': show_function(name, attr, known_globals, indent=1) print # print class_name, name # if class_name.startswith('rs232') and name == 'reset': print
def _walk_class(self, class_, fullname): # type: (type, str) -> None with self._scope(fullname): if self._visitor.visit_class(fullname, class_, self): return if class_ is type: # Recursion safeguards are expected to be provided by the visitor # however this safeguard is hard coded. return for attr in inspect.classify_class_attrs(class_): subname = self._join(fullname, attr.name) if attr.kind == "data": if inspect.isclass(attr.object): self._enqueue(self._CLASS, self._walk_class, attr.object, subname) continue if inspect.isroutine(attr.object): self._enqueue( self._FUNCTION, self._walk_function, attr.object, class_, subname, ) continue priority, func = self._class_kind_map[attr.kind] self._enqueue(priority, func, attr.object, class_, subname)
def mock(self, parent, selector, replacement): if not hasattr(self, 'mockObjects'): self.mockObjects = [] # Extract the current value if not hasattr(parent, selector): # No current value currval = (None, True) elif isinstance(parent, (type, types.ClassType)): # If this is a class, we need to be careful when we mock, since we # could mock a parent's object import inspect defClasses = [ (x[2], x[3], x[1]) for x in inspect.classify_class_attrs(parent) if x[0] == selector ] # We've just extracted the class that defined the attribute and # the real value if defClasses[0][2] == 'static method': replacement = staticmethod(replacement) if defClasses[0][2] == 'class method': replacement = classmethod(replacement) if defClasses[0][0] != parent: # We inherited this object from the parent currval = (None, True) else: currval = (defClasses[0][1], False) else: currval = (getattr(parent, selector), False) self.mockObjects.append((parent, selector, currval)) setattr(parent, selector, replacement)
def describe_service(self, service_class): assert issubclass(service_class, BaseService) # Do not make a new resource idenity - this is a generic method which # is also used to look for an existing description service_description = coi_resource_descriptions.ServiceDescription() service_description.name = service_class.declare['name'] service_description.version = service_class.declare['version'] service_description.class_name = service_class.__name__ service_description.module = service_class.__module__ service_description.description = inspect.getdoc(service_class) #@Note need to improve inspection of service! #kind and name are accessors added in python 2.6 #they are taken out here, to be 2.5 compatible for attr in inspect.classify_class_attrs(service_class): #if attr.kind == 'method' and 'op_' in attr.name : if attr[1] == 'method' and 'op_' in attr[0]: opdesc = coi_resource_descriptions.ServiceMethodInterface() #opdesc.name = attr.name opdesc.name = attr[0] #print 'INSEPCT',inspect.getdoc(attr.object) #opdesc.description = inspect.getdoc(attr.object) #Can't seem to get the arguments in any meaningful way... #opdesc.arguments = inspect.getargspec(attr.object) service_description.interface.append(opdesc) return service_description
def test_inspect_classify_class_attrs(self): # indirectly test __objclass__ from inspect import Attribute values = [ Attribute(name='__class__', kind='data', defining_class=object, object=EnumMeta), Attribute(name='__doc__', kind='data', defining_class=self.Color, object=None), Attribute(name='__members__', kind='property', defining_class=EnumMeta, object=EnumMeta.__members__), Attribute(name='__module__', kind='data', defining_class=self.Color, object=__name__), Attribute(name='blue', kind='data', defining_class=self.Color, object=self.Color.blue), Attribute(name='green', kind='data', defining_class=self.Color, object=self.Color.green), Attribute(name='red', kind='data', defining_class=self.Color, object=self.Color.red), Attribute(name='name', kind='data', defining_class=Enum, object=Enum.__dict__['name']), Attribute(name='value', kind='data', defining_class=Enum, object=Enum.__dict__['value']), ] values.sort(key=lambda item: item.name) result = list(inspect.classify_class_attrs(self.Color)) result.sort(key=lambda item: item.name) failed = False for v, r in zip(values, result): if r != v: print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') failed = True if failed: self.fail("result does not equal expected, see print above")
def _handle_list(self): from abjad.tools import abctools basic_bases = ( abctools.AbjadObject, abctools.AbjadValueObject, object, ) print('Available materials:') all_materials = self._import_all_materials(verbose=False) if not all_materials: print(' No materials available.') sys.exit(2) materials = {} for material_name, material in all_materials.items(): class_ = type(material) base = class_.__bases__[0] attrs = {attr.name: attr for attr in inspect.classify_class_attrs(class_)} if any(_ in class_.__bases__ for _ in basic_bases): base = class_ elif getattr(class_, '__is_terminal_ajv_list_item__', False) and \ attrs['__is_terminal_ajv_list_item__'].defining_class is class_: base = class_ materials.setdefault(base, []).append((material_name, class_)) #valid_paths = self._list_material_subpackages(self._score_package_path) materials = sorted(materials.items(), key=lambda pair: pair[0].__name__) for base, material_names in materials: print(' {}:'.format(base.__name__)) for material_name, class_ in material_names: print(' {} [{}]'.format(material_name, class_.__name__)) sys.exit(2)
def describe_service(self,service_class): assert issubclass(service_class, BaseService) # Do not make a new resource idenity - this is a generic method which # is also used to look for an existing description service_description = coi_resource_descriptions.ServiceDescription() service_description.name = service_class.declare['name'] service_description.version = service_class.declare['version'] service_description.class_name = service_class.__name__ service_description.module = service_class.__module__ service_description.description = inspect.getdoc(service_class) #@Note need to improve inspection of service! #kind and name are accessors added in python 2.6 #they are taken out here, to be 2.5 compatible for attr in inspect.classify_class_attrs(service_class): #if attr.kind == 'method' and 'op_' in attr.name : if attr[1] == 'method' and 'op_' in attr[0] : opdesc = coi_resource_descriptions.ServiceMethodInterface() #opdesc.name = attr.name opdesc.name = attr[0] #print 'INSEPCT',inspect.getdoc(attr.object) #opdesc.description = inspect.getdoc(attr.object) #Can't seem to get the arguments in any meaningful way... #opdesc.arguments = inspect.getargspec(attr.object) service_description.interface.append(opdesc) return service_description
def parse_references(self): """ Get all the :class:`storm.references.Reference` and create foreign keys for the SQL creation script If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a `Customer` model and an `Adress` model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with `Reference` from Address to Customer using a property like `Address.customer_id` and a `ReferenceSet` from `Customer` to `Address` like: Customer.addresses = ReferenceSet(Customer.id, Address.id) In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself. .. warning: If no InnoDB is used as engine in MySQL then this is skipped. :class:`storm.references.ReferenceSet` does not generate foreign keys by itself. If you need a many2many relation you should add a Reference for the compound primary key in the relation table """ if self.engine != 'InnoDB': return references = [] for attr in inspect.classify_class_attrs(self.model.__class__): if type(attr.object) is Reference: relation = attr.object._relation keys = { 'remote': relation.remote_key[0], 'local': relation.local_key[0] } remote_table = relation.remote_cls.__storm_table__ query = ( 'INDEX `{remote_table}_ind` (`{localkey}`), FOREIGN KEY ' '(`{localkey}`) REFERENCES `{remote_table}`(`{id}`) ' 'ON UPDATE {on_update} ON DELETE {on_delete}'.format( remote_table=remote_table, localkey=keys.get('local').name, id=keys.get('remote').name, on_update=getattr(self.model, '__on_update__', 'RESTRICT'), on_delete=getattr(self.model, '__on_delete__', 'RESTRICT'))) references.append(query) return ', '.join(references)
def parse_references(self): """ Get all the :class:`storm.references.Reference` and create foreign keys for the SQL creation script If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a `Customer` model and an `Adress` model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with `Reference` from Address to Customer using a property like `Address.customer_id` and a `ReferenceSet` from `Customer` to `Address` like: Customer.addresses = ReferenceSet(Customer.id, Address.id) In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself. .. warning: If you need a many2many relation you should add a Reference for the compound primary key in the relation table """ references = [] for attr in inspect.classify_class_attrs(self.model.__class__): if type(attr.object) is Reference: relation = attr.object._relation keys = { 'remote': relation.remote_key, 'local': relation.local_key } remote_table = relation.remote_cls.__storm_table__ localkeys = ', '.join(k.name for k in keys.get('local')) remotekeys = ', '.join(k.name for k in keys.get('remote')) query = ( 'ALTER TABLE {table} ADD ' 'CONSTRAINT {remote_table}_ind FOREIGN KEY ({localkeys}) ' 'REFERENCES {remote_table}({remotekeys}) ' 'ON UPDATE {on_update} ON DELETE {on_delete};\n'.format( table=self.model.__storm_table__, remote_table=remote_table, localkeys=localkeys, remotekeys=remotekeys, on_update=getattr(self.model, '__on_update__', 'RESTRICT'), on_delete=getattr(self.model, '__on_delete__', 'RESTRICT'))) references.append(query) return ''.join(references)
def _handle_list(self): basic_bases = (object, ) print("Available materials:") all_materials = self._import_all_materials(verbose=False) if not all_materials: print(" No materials available.") sys.exit(2) materials = {} for material_name, material in all_materials.items(): class_ = type(material) base = class_.__bases__[0] attrs = { attr.name: attr for attr in inspect.classify_class_attrs(class_) } if any(_ in class_.__bases__ for _ in basic_bases): base = class_ elif (getattr(class_, "__is_terminal_ajv_list_item__", False) and attrs["__is_terminal_ajv_list_item__"].defining_class is class_): base = class_ materials.setdefault(base, []).append((material_name, class_)) # valid_paths = self._list_material_subpackages(self._score_package_path) materials = sorted(materials.items(), key=lambda pair: pair[0].__name__) for base, material_names in materials: print(" {}:".format(base.__name__)) for material_name, class_ in material_names: print(" {} [{}]".format(material_name, class_.__name__)) sys.exit(2)
def localdir(obj): if isclass(obj): fcattrs = filter(lambda att: att.defining_class is myt, inspect.classify_class_attrs(o)) items = map(lambda i: (i.name, i.value), fcattrs) items.sort() return items
def describe_agent(self,agent_class): assert issubclass(agent_class, BaseProcess) # Do not make a new resource idenity - this is a generic method which # is also used to look for an existing description agent_description = coi_resource_descriptions.AgentDescription() #agent_description.name = agent_class.declare['name'] #agent_description.version = agent_class.declare['version'] agent_description.class_name = agent_class.__name__ agent_description.module = agent_class.__module__ agent_description.description = inspect.getdoc(agent_class) #@Note need to improve inspection of agent! for attr in inspect.classify_class_attrs(agent_class): #if attr.kind == 'method' and 'op_' in attr.name : if attr[1] == 'method' and 'op_' in attr[0] : opdesc = coi_resource_descriptions.AgentMethodInterface() #opdesc.name = attr.name opdesc.name = attr[0] #print 'INSEPCT',inspect.getdoc(attr.object) #opdesc.description = inspect.getdoc(attr.object) #Can't seem to get the arguments in any meaningful way... #opdesc.arguments = inspect.getargspec(attr.object) agent_description.interface.append(opdesc) return agent_description
def _trace_class(c): class_attrs = inspect.classify_class_attrs(c) methods = inspect.getmembers(c, lambda obj: inspect.ismethod(obj) or inspect.isfunction(obj)) for name, method in methods: if hasattr(method, 'tracer'): # Method is already being traced continue for attr_name, attr_kind, _, _ in class_attrs: if attr_name == name: kind = attr_kind break else: continue if kind == 'method': decorator = lambda f: f elif kind == 'static method': decorator = staticmethod elif kind == 'class method': decorator = classmethod # To relay calls to the class method, we need to use the underlying function method = method.__func__ else: continue setattr(c, name, decorator(_trace_method(method, c.__name__))) return c
def print_methods(self, arg): """ Print the methods of an object or type. """ args = parse_argstring(self.print_methods, arg) obj = self.get_variable(args.variable) if not isinstance(obj, (type, types.ClassType)): klass = type(obj) else: klass = obj attrs = inspect.classify_class_attrs(klass) grouped = defaultdict(list) all = [] for name, kind, defining, value in attrs: if kind not in ('method', 'class method', 'static method'): continue if args.private or not name.startswith('_'): grouped[defining].append(name) all.append(name) if args.group: for cls in inspect.getmro(klass)[::-1]: if grouped[cls]: name = getattr(cls, '__name__', repr(cls)) print(name) print('-' * len(name)) print(utils.columnize(grouped[cls])) else: print(utils.columnize(all))
def magic_print_methods(self, arg): """ Print the methods of an object or type. """ args = parse_argstring(magic_print_methods, arg) obj = get_variable(self, args.variable) if not isinstance(obj, (type, types.ClassType)): klass = type(obj) else: klass = obj attrs = inspect.classify_class_attrs(klass) grouped = defaultdict(list) all = [] for name, kind, defining, value in attrs: if kind not in ('method', 'class method', 'static method'): continue if args.private or not name.startswith('_'): grouped[defining].append(name) all.append(name) if args.group: for cls in inspect.getmro(klass)[::-1]: if grouped[cls]: name = getattr(cls, '__name__', repr(cls)) print name print '-'*len(name) print utils.columnize(grouped[cls]) else: print utils.columnize(all)
def _handle_list(self): from abjad.tools import abctools basic_bases = ( abctools.AbjadObject, abctools.AbjadValueObject, object, ) print('Available materials:') all_materials = self._import_all_materials(verbose=False) if not all_materials: print(' No materials available.') sys.exit(2) materials = {} for material_name, material in all_materials.items(): class_ = type(material) base = class_.__bases__[0] attrs = { attr.name: attr for attr in inspect.classify_class_attrs(class_) } if any(_ in class_.__bases__ for _ in basic_bases): base = class_ elif getattr(class_, '__is_terminal_ajv_list_item__', False) and \ attrs['__is_terminal_ajv_list_item__'].defining_class is class_: base = class_ materials.setdefault(base, []).append((material_name, class_)) #valid_paths = self._list_material_subpackages(self._score_package_path) materials = sorted(materials.items(), key=lambda pair: pair[0].__name__) for base, material_names in materials: print(' {}:'.format(base.__name__)) for material_name, class_ in material_names: print(' {} [{}]'.format(material_name, class_.__name__)) sys.exit(2)
def formatMethodDocStrings(self,X): r = "" for method in sorted([x for x in inspect.classify_class_attrs(X) if x[2] == X and x[1] == "method"]): methodHead = method[0]+self.formatArgSpec(inspect.getargspec(method[3])) r += self.methodName(methodHead)+ self.docString(method[3].__doc__) return r
def clsinfo(o, sortkey=None): if type(o) is not type: o = type(o) cattrs = inspect.classify_class_attrs(o) if sortkey: return sorted(cattrs, key=lambda att: getattr(att, sortkey, None)) return sorted(cattrs)
def handle_resource_class(cls, base_uri, klass, service, parameters, path): for item in inspect.classify_class_attrs(klass): if item.kind.__contains__('method') and item.defining_class == klass: # resource_shape = None resource_attributes = item.object.__func__() if item.name == 'query_capability': query_capability = cls.create_query_capability(base_uri, resource_attributes, parameters) service.add_query_capability(query_capability) # resource_shape = query_capability.resource_shape if item.name == 'creation_factory': creation_factory = cls.create_creation_factory(base_uri, resource_attributes, parameters) service.add_creation_factory(creation_factory) # resource_shape = creation_factory.resource_shape if item.name == 'selection_dialog': dialog = cls.create_selection_dialog(base_uri, resource_attributes, parameters) service.add_selection_dialog(dialog) if item.name == 'creation_dialog': dialog = cls.create_creation_dialog(base_uri, resource_attributes, parameters) service.add_creation_dialog(dialog) return True
def _handle_list(self): from supriya.system import SupriyaObject, SupriyaValueObject basic_bases = (SupriyaObject, SupriyaValueObject, object) print("Available {}:".format(self._section_plural)) all_objects = self._import_objects(self._section_plural, verbose=False) if not all_objects: print(" No {} available.".format(self._section_plural)) sys.exit(1) categorized_objects = {} for name, object_ in all_objects.items(): class_ = type(object_) base = class_.__bases__[0] attrs = { attr.name: attr for attr in inspect.classify_class_attrs(class_) } if any(_ in class_.__bases__ for _ in basic_bases): base = class_ elif (getattr(class_, "__is_terminal_ajv_list_item__", False) and attrs["__is_terminal_ajv_list_item__"].defining_class is class_): base = class_ categorized_objects.setdefault(base, []).append((name, class_)) categorized_objects = sorted(categorized_objects.items(), key=lambda pair: pair[0].__name__) for base, names in categorized_objects: print(" {}:".format(base.__name__)) for name, class_ in names: print(" {} [{}]".format(name, class_.__name__)) sys.exit(1)
def get_class(word, cls): if issubclass(cls, Exception): node = Node(word, "e") elif isabstract(cls): node = Node(word, "t") else: node = Node(word, "c") if hasattr(cls, "__init__"): v = cls.__init__ if ismethod(v) and hasattr(v, "im_class") and v.im_class is cls: n = get_func(word, v.im_func) node.info = n.info node.info = node.info + "\n" + getinfo(cls) for x in classify_class_attrs(cls): if x.name.startswith("_"): continue if x.defining_class != cls: continue if x.kind == "property": node.add(Node(x.name, "d", info=getinfo(x.object)), True) continue elif x.kind == "data": node.add(Node(x.name, "d"), True) continue elif x.kind == "class method" or x.kind == "static method": kind = "M" else: kind = "m" n = get_func(x.name, x.object) n.kind = kind node.add(n, True) return node
def get_class(word, cls): if issubclass(cls, Exception): node = Node(word, 'e') elif isabstract(cls): node = Node(word, 't') else: node = Node(word, 'c') if hasattr(cls, '__init__'): v = cls.__init__ if ismethod(v) and hasattr(v, 'im_class') and v.im_class is cls: n = get_func(word, v.im_func) node.info = n.info node.info = node.info + '\n' + getinfo(cls) for x in classify_class_attrs(cls): if x.name.startswith('_'): continue if x.defining_class != cls: continue if x.kind == 'property': node.add(Node(x.name, 'd', info=getinfo(x.object)), True) continue elif x.kind == 'data': node.add(Node(x.name, 'd'), True) continue elif x.kind == 'class method' or x.kind == 'static method': kind = 'M' else: kind = 'm' n = get_func(x.name, x.object) n.kind = kind node.add(n, True) return node
def __init__(self, appname, name, classobj, preset, main=False): self._appname = appname self._name = name self._verbose_name = name self._vals = {} self._readonly = False self._cache_prefix = "appsetting-%s-%s-%s-" % (Site.objects.get_current().pk, self._appname, self._name) for attr in inspect.classify_class_attrs(classobj): # for Python 2.5 compatiblity, we use tuple indexes # instead of the attribute names (which are only available # from Python 2.6 onwards). Here's the mapping: # attr[0] attr.name Attribute name # attr[1] attr.kind class/static method, property, data # attr[2] attr.defining_class The `class` object that created this attr # attr[3] attr.object Attribute value # if attr[2] != classobj or attr[1] != "data": continue if attr[0].startswith("_"): continue if attr[0] == "verbose_name": self._verbose_name = attr[3] continue val = attr[3] key = attr[0] if type(val) == int: val = forms.IntegerField(label=key.title(), initial=val) elif type(val) == float: val = forms.FloatField(label=key.title(), initial=val) elif type(val) == str: val = forms.CharField(label=key.title(), initial=val) elif val in (True, False): val = forms.BooleanField(label=key.title(), initial=val) elif not isinstance(val, forms.Field): raise SettingsException, "settings must be of a valid form field type" if preset.has_key(key): val.initial = preset[key] try: val.initial = val.clean(val.initial) except forms.ValidationError: if main: raise SettingsException, "setting %s.%s not set. Please set it in your settings.py" % (appname, key) raise SettingsException, "setting %s.%s.%s not set. Please set it in your settings.py" % ( appname, name, key, ) val._parent = self self._vals[key] = val if has_db: settings = Setting.objects.all().filter(app=self._appname, class_name=self._name) for setting in settings: if self._vals.has_key(setting.key): self._vals[setting.key].initial = self._vals[setting.key].clean(setting.value) else: ## the app removed the setting... shouldn't happen ## in production. maybe error? or del it? pass
def _handle_list(self): from supriya.system import SupriyaObject, SupriyaValueObject basic_bases = (SupriyaObject, SupriyaValueObject, object) print("Available {}:".format(self._section_plural)) all_objects = self._import_objects(self._section_plural, verbose=False) if not all_objects: print(" No {} available.".format(self._section_plural)) sys.exit(1) categorized_objects = {} for name, object_ in all_objects.items(): class_ = type(object_) base = class_.__bases__[0] attrs = {attr.name: attr for attr in inspect.classify_class_attrs(class_)} if any(_ in class_.__bases__ for _ in basic_bases): base = class_ elif ( getattr(class_, "__is_terminal_ajv_list_item__", False) and attrs["__is_terminal_ajv_list_item__"].defining_class is class_ ): base = class_ categorized_objects.setdefault(base, []).append((name, class_)) categorized_objects = sorted( categorized_objects.items(), key=lambda pair: pair[0].__name__ ) for base, names in categorized_objects: print(" {}:".format(base.__name__)) for name, class_ in names: print(" {} [{}]".format(name, class_.__name__)) sys.exit(1)
def test_idetools___doc___01(object_): """ All classes have a docstring. All class methods have a docstring. """ ignored_names = ( '__documentation_section__', '__dict__', '__init__', '__new__', ) ignored_classes = ( ) assert object_.__doc__ is not None if object_.__name__ in ignored_classes: return for attribute in inspect.classify_class_attrs(object_): if attribute.name in ignored_names: continue elif attribute.defining_class is not object_: continue if attribute.name[0].isalpha() or attribute.name.startswith('__'): message = f'{object_.__name__}.{attribute.name}' assert getattr(object_, attribute.name).__doc__ is not None, message
def _stubout(klass, message): """ Scans a class and generates wrapping stubs for __new__() and every class and static method. Returns a dictionary which can be passed to type() to generate a wrapping class. """ overrides = {} def makestub_class(name, func): """ Create a stub for wrapping class methods. """ def stub(cls, *args, **kwargs): warn_deprecated_class(klass, message) return func(*args, **kwargs) # Overwrite the stub's name stub.__name__ = name stub.func_name = name return classmethod(stub) def makestub_static(name, func): """ Create a stub for wrapping static methods. """ def stub(*args, **kwargs): warn_deprecated_class(klass, message) return func(*args, **kwargs) # Overwrite the stub's name stub.__name__ = name stub.func_name = name return staticmethod(stub) for name, kind, _klass, _obj in inspect.classify_class_attrs(klass): # We're only interested in __new__(), class methods, and # static methods... if (name != '__new__' and kind not in ('class method', 'static method')): continue # Get the function... func = getattr(klass, name) # Override it in the class if kind == 'class method': stub = makestub_class(name, func) elif kind == 'static method' or name == '__new__': stub = makestub_static(name, func) # Save it in the overrides dictionary... overrides[name] = stub # Apply the overrides for name, stub in overrides.items(): setattr(klass, name, stub)
def parse_references(self): """ Get all the :class:`storm.references.Reference` and create foreign keys for the SQL creation script If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a `Customer` model and an `Adress` model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with `Reference` from Address to Customer using a property like `Address.customer_id` and a `ReferenceSet` from `Customer` to `Address` like: Customer.addresses = ReferenceSet(Customer.id, Address.id) In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself. .. warning: If you need a many2many relation you should add a Reference for the compound primary key in the relation table """ references = [] for attr in inspect.classify_class_attrs(self.model.__class__): if type(attr.object) is Reference: relation = attr.object._relation keys = { 'remote': relation.remote_key[0], 'local': relation.local_key[0] } remote_table = relation.remote_cls.__storm_table__ query = ( 'ALTER TABLE {table} ADD ' 'CONSTRAINT {remote_table}_ind FOREIGN KEY ({localkey}) ' 'REFERENCES {remote_table}({id}) ' 'ON UPDATE {on_update} ON DELETE {on_delete};\n'.format( table=self.model.__storm_table__, remote_table=remote_table, localkey=keys.get('local').name, id=keys.get('remote').name, on_update=getattr( self.model, '__on_update__', 'RESTRICT'), on_delete=getattr( self.model, '__on_delete__', 'RESTRICT') ) ) references.append(query) return ', '.join(references)
def classify_class_attrs(object): """Wrap inspect.classify_class_attrs, with fixup for data descriptors.""" results = [] for (name, kind, cls, value) in inspect.classify_class_attrs(object): if inspect.isdatadescriptor(value): kind = 'data descriptor' results.append((name, kind, cls, value)) return results
def prepclass(c): name, clzz = c attrs = inspect.classify_class_attrs(clzz) return { 'name': name, 'methods': inspect.getmembers(clzz, predicate=inspect.isfunction), 'attributes' : attrs }
def _get_test_funcs(cls): testcase_methods = dir(unittest.TestCase) for m in inspect.classify_class_attrs(cls): if m.kind == 'method' and \ m.defining_class == cls and \ not m.name.startswith('_') and \ m.name not in testcase_methods: yield (inspect.findsource(getattr(cls, m.name))[1], m.name)
def get_init_doc(klass): for attr in inspect.classify_class_attrs(klass): if attr.name == '__init__': if attr.defining_class is klass: return attr.object.__doc__ else: # Ignore __init__ method inherited from a super class return None return None
def __init__(self, appname, name, classobj, preset, main=False): self._appname = appname self._name = name self._verbose_name = name self._vals = {} self._readonly = False self._cache_prefix = 'appsetting-%s-%s-%s-' % (Site.objects.get_current().pk, self._appname, self._name) for attr in inspect.classify_class_attrs(classobj): # for Python 2.5 compatiblity, we use tuple indexes # instead of the attribute names (which are only available # from Python 2.6 onwards). Here's the mapping: # attr[0] attr.name Attribute name # attr[1] attr.kind class/static method, property, data # attr[2] attr.defining_class The `class` object that created this attr # attr[3] attr.object Attribute value # if attr[2] != classobj or attr[1] != 'data': continue if attr[0].startswith('_'): continue if attr[0] == 'verbose_name': self._verbose_name = attr[3] continue val = attr[3] key = attr[0] if type(val) == int: val = forms.IntegerField(label=key.title(), initial=val) elif type(val) == float: val = forms.FloatField(label=key.title(), initial=val) elif type(val) == str: val = forms.CharField(label=key.title(), initial=val) elif val in (True, False): val = forms.BooleanField(label=key.title(), initial=val) elif not isinstance(val, forms.Field): raise SettingsException, 'settings must be of a valid form field type' if preset.has_key(key): val.initial = preset[key] try: val.initial = val.clean(val.initial) except forms.ValidationError: if main: raise SettingsException, 'setting %s.%s not set. Please set it in your settings.py' % (appname, key) raise SettingsException, 'setting %s.%s.%s not set. Please set it in your settings.py' % (appname, name, key) val._parent = self self._vals[key] = val if has_db: settings = Setting.objects.all().filter(app=self._appname, class_name=self._name) for setting in settings: if self._vals.has_key(setting.key): self._vals[setting.key].initial = self._vals[setting.key].clean(setting.value) else: ## the app removed the setting... shouldn't happen ## in production. maybe error? or del it? pass
def GetClassAttrsDict(component): """Gets the attributes of the component class, as a dict with name keys.""" if not inspect.isclass(component): return None class_attrs_list = inspect.classify_class_attrs(component) return { class_attr.name: class_attr for class_attr in class_attrs_list }
def clear(self): """Clear all properties, resetting them to default values.""" attrdesc = inspect.classify_class_attrs(self.__class__) for attr in attrdesc: if attr[1] == "property": try: delattr(self, attr[0]) except AttributeError, e: pass # probably a non-deletable attribute
def decorate_all_methods(cls, decorator): """ Decorate all public methods of the class with the given decorator. """ for name, clasification, clz, attr in inspect.classify_class_attrs( cls): if clasification == "method" and not name.startswith("_"): setattr(cls, name, decorator(attr)) return cls
def __init__(self, obj, prefix="abjad.tools."): assert isinstance(obj, type) Documenter.__init__(self, obj, prefix) class_methods = [] data = [] inherited_attributes = [] methods = [] readonly_properties = [] readwrite_properties = [] special_methods = [] static_methods = [] attrs = inspect.classify_class_attrs(self._object) for attr in attrs: if attr.defining_class is object: continue if self._attribute_is_inherited(attr): inherited_attributes.append(attr) if attr.kind == "method": if attr.name not in self._ignored_special_methods: if attr.name.startswith("__"): special_methods.append(attr) elif not attr.name.startswith("_"): methods.append(attr) elif attr.kind == "class method": if attr.name not in self._ignored_special_methods: if attr.name.startswith("__"): special_methods.append(attr) elif not attr.name.startswith("_"): class_methods.append(attr) elif attr.kind == "static method": if attr.name not in self._ignored_special_methods: if attr.name.startswith("__"): special_methods.append(attr) elif not attr.name.startswith("_"): static_methods.append(attr) elif attr.kind == "property" and not attr.name.startswith("_"): if attr.object.fset is None: readonly_properties.append(attr) else: readwrite_properties.append(attr) elif ( attr.kind == "data" and not attr.name.startswith("_") and attr.name not in getattr(self.object, "__slots__", ()) ): data.append(attr) self._class_methods = tuple(sorted(class_methods)) self._data = tuple(sorted(data)) self._inherited_attributes = tuple(sorted(inherited_attributes)) self._methods = tuple(sorted(methods)) self._readonly_properties = tuple(sorted(readonly_properties)) self._readwrite_properties = tuple(sorted(readwrite_properties)) self._special_methods = tuple(sorted(special_methods)) self._static_methods = tuple(sorted(static_methods))
def get_declared(type, predicate=None): if not inspect.isclass(type): type = type.__class__ attrs = inspect.classify_class_attrs(type) for item in attrs: if item.defining_class != type: continue elif not predicate or predicate(item): yield item
def deconstruct_class(cls): attributes = inspect.classify_class_attrs(cls) deconstructed = [] for attr in attributes: if attr.defining_class != object and attr.defining_class != type and \ attr.name not in ["__dict__", "__weakref__"]: deconstructed.append((attr.name, attr.object, attr.kind)) return deconstructed
def ButSendValueClick(self, sender, e): testobj = TTrace.debug listObjToSend = inspect.classify_class_attrs(type(testobj)) lst = [TTrace.winTrace,TMemberNode(),TTrace] TTrace.debug.sendValue("sendValue : classify_class_attrs ", listObjToSend, True, 3, "debug node") TTrace.debug.sendValue("sendValue : list", lst, True, 3, "title") TTrace.debug.sendValue("integer 5", 5) TTrace.debug.sendValue("long 5", 5L) TTrace.debug.sendValue("ttrace.RgbColors", ttrace.RgbColors)
def test_compound_model_classify_attributes(): """ Regression test for an issue raised here: https://github.com/astropy/astropy/pull/3231#discussion_r22221123 The issue is that part of the `help` implementation calls a utility function called `inspect.classify_class_attrs`, which was leading to an infinite recursion. This is a useful test in its own right just in that it tests that compound models can be introspected in some useful way without crashing--this works as sort of a test of its somewhat complicated internal state management. This test does not check any of the results of `~inspect.classify_class_attrs`, though it might be useful to at some point. """ inspect.classify_class_attrs(Gaussian1D + Gaussian1D)
def print_stats(self): self.calculate() for attribute in classify_class_attrs(Stats): if type(attribute.object) in (int, float): #import pdb; pdb.set_trace() if type(attribute.object) == float: print "{0:.2f}\t {1}".format(getattr(self, attribute.name), attribute.name) else: print "{0}\t {1}".format(getattr(self, attribute.name), attribute.name)
def get_all_symbols(cls): """ Get all symbols defined by this symbol definition block """ # NOTE: This feels a bit like Enum and the extra property that it # carries which holds all values. I don't know if we should have that # as symbols are not 'bound' to any 'container' like enumeration values # are. return [value for name, kind, defcls, value in inspect.classify_class_attrs(cls) if kind == 'data' and isinstance(value, Symbol)]
def test_inspect_treats_cached_property_as_property(): class A: @utils.cached_property def _prop(self): return "cached_property return value" attrs = inspect.classify_class_attrs(A) for attr in attrs: if attr.name == "_prop": break assert attr.kind == "property"
def _exportStaticMethodAsGlobalFunctions(cls): """ Define utility functions because Toil can't pickle static methods. Note that this relies on the convention that the first argument of a job function is named 'job'. """ for name, kind, clazz, value in inspect.classify_class_attrs(cls): if kind == 'static method': method = value.__func__ args = inspect.getargspec(method).args if args and args[0] == 'job': globals()[name] = method
def test_inspect_treats_cached_property_as_property(): class A(object): @utils.cached_property def _prop(self): return "cached_property return value" attrs = inspect.classify_class_attrs(A) for attr in attrs: if attr.name == "_prop": break assert attr.kind == "property"
def test_inspect_treats_cached_property_as_property(): class A(object): @utils.cached_property def _prop(self): return 'cached_property return value' attrs = inspect.classify_class_attrs(A) for attr in attrs: if attr.name == '_prop': break assert attr.kind == 'property'
def deconstruct_class(cls): attributes = inspect.classify_class_attrs(cls) deconstructed = [] for attr in attributes: if attr.defining_class == object or attr.defining_class == type or attr.name in [ "__dict__", "__weakref__" ]: continue else: deconstructed.append((attr.name, attr.object, attr.kind)) return deconstructed
def get_all_symbols(cls): """ Get all symbols defined by this symbol definition block """ # NOTE: This feels a bit like Enum and the extra property that it # carries which holds all values. I don't know if we should have that # as symbols are not 'bound' to any 'container' like enumeration values # are. return [value for name, kind, defcls, value in inspect.classify_class_attrs(cls) if name != '__locals__' and kind == 'data' and isinstance(value, Symbol)]
def __init__(self, subject=None, prefix='abjad.tools.'): if subject is None: subject = type(None) assert isinstance(subject, type) Documenter.__init__(self, subject, prefix) class_methods = [] data = [] inherited_attributes = [] methods = [] readonly_properties = [] readwrite_properties = [] special_methods = [] static_methods = [] attrs = inspect.classify_class_attrs(self.subject) for attr in attrs: if attr.defining_class is object: continue if self._attribute_is_inherited(attr): inherited_attributes.append(attr) if attr.kind == 'method': if attr.name not in self._ignored_special_methods: if attr.name.startswith('__'): special_methods.append(attr) elif not attr.name.startswith('_'): methods.append(attr) elif attr.kind == 'class method': if attr.name not in self._ignored_special_methods: if attr.name.startswith('__'): special_methods.append(attr) elif not attr.name.startswith('_'): class_methods.append(attr) elif attr.kind == 'static method': if attr.name not in self._ignored_special_methods: if attr.name.startswith('__'): special_methods.append(attr) elif not attr.name.startswith('_'): static_methods.append(attr) elif attr.kind == 'property' and not attr.name.startswith('_'): if attr.object.fset is None: readonly_properties.append(attr) else: readwrite_properties.append(attr) elif attr.kind == 'data' and not attr.name.startswith('_') \ and attr.name not in getattr(self.subject, '__slots__', ()): data.append(attr) self._class_methods = tuple(sorted(class_methods)) self._data = tuple(sorted(data)) self._inherited_attributes = tuple(sorted(inherited_attributes)) self._methods = tuple(sorted(methods)) self._readonly_properties = tuple(sorted(readonly_properties)) self._readwrite_properties = tuple(sorted(readwrite_properties)) self._special_methods = tuple(sorted(special_methods)) self._static_methods = tuple(sorted(static_methods))
def __new__(mcs, name, bases, attrs): new_class = super(MetaMapper, mcs).__new__(mcs, name, bases, attrs) fields = { name: prop for name, kind, cls, prop in classify_class_attrs(new_class) if isinstance(prop, field) } new_class._fields = fields new_class._field_names = tuple(fields.keys()) return new_class