def test_basic(self): class Thing(object): x = object() thing = Thing() self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x) self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x) with self.assertRaises(AttributeError): inspect.getattr_static(thing, 'y') self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
def test_instance_attr(self): class Thing(object): x = 2 def __init__(self, x): self.x = x thing = Thing(3) self.assertEqual(inspect.getattr_static(thing, 'x'), 3) del thing.x self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
def discover_benchmarks(module_name, type_=BenchmarksType.TIME.value, repeat=10, number=1): """ Discover benchmarks in the module :param module_name: benchmarks module :param type_: benchmark type :return: time benchmarks """ for module in discover_modules(module_name): for attr_name, module_attr in module.__dict__.items(): if attr_name.startswith('_'): # skip attributes which start with underscore continue if inspect.isclass(module_attr): for name, class_attr in inspect.getmembers(module_attr): if not name.startswith(f'{type_}_'): continue name_parts = module.__name__.split('.', 1)[1:] + [module_attr.__name__, name] benchmark_name = '.'.join(name_parts) func = inspect.getattr_static(module_attr, name) params = inspect.getattr_static(module_attr, 'params', [[]]) for param in itertools.product(*params): yield TimeBenchmark(benchmark_name, func, param, module_attr, repeat=repeat, number=number)
def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) if cls.gradfuncs is None or cls._gradfuncs_auto: cls.gradfuncs = list({ key: val for t in cls.mro()[::-1] for key, val in vars(t).items() if key.startswith('grad_') }.values()) or None cls._update_gradfuncs() if cls.ninputs is None or cls._gradfuncs_auto: cls.ninputs = len(cls.gradfuncs) if cls.gradfuncs else None if cls.gradfuncs: cls._gradfuncs_auto = True if cls.gradfuncs is not None: cls.gradfuncs = [ gf.__get__(None, cls) if isinstance(gf, (staticmethod, classmethod)) else gf for gf in cls.gradfuncs ] if cls.ninputs is None: cls.ninputs = len(cls.gradfuncs) cls.differentiable = True if any( getattr_static(cls, fname) is not getattr_static( TorchFunction, fname) for fname in ('backward', '_backward')): cls.differentiable = True
def test_monkeypatch_classmethod_subclass(): ''' Test `monkeypatch` on a subclass of `classmethod`. This is useful in Django, that uses its own `classmethod` subclass. ''' class FunkyClassMethod(classmethod): is_funky = True class A(EqualByIdentity): @FunkyClassMethod def my_funky_class_method(cls): raise 'Flow should never reach here.' @monkeypatching_tools.monkeypatch(A) @FunkyClassMethod def my_funky_class_method(cls): return cls assert isinstance(inspect.getattr_static(A, 'my_funky_class_method'), FunkyClassMethod) assert inspect.getattr_static(A, 'my_funky_class_method').is_funky assert isinstance(A.my_funky_class_method, types.MethodType) assert A.my_funky_class_method() == A a0 = A() assert a0.my_funky_class_method() == A
def getCallerModAndClassName(callLevel=2): """ Function to get module.class of caller. If caller does not come from a class, just the module name will be returned :return: The name of the caller in format module_name.ClassName """ of = inspect.getouterframes(inspect.currentframe())[callLevel][0] try: callObj = of.f_locals['self'] if isinstance(callObj, object): try: packageName = inspect.getattr_static( callObj, '__package__') except AttributeError: packageName = None moduleName = inspect.getattr_static(callObj, '__module__') className = str(of.f_locals['self']).split( '<')[1].split()[0].split()[0].split('.')[1] if packageName is not None: caller = packageName + '.' + moduleName + '.' + className else: caller = moduleName + '.' + className else: raise KeyError() except IndexError: caller = of.f_locals['self'] except KeyError: cs = inspect.stack() callObj = cs[callLevel + 1][4][0].split('=')[1].strip() modName = inspect.getmodulename(cs[callLevel][1]) className = callObj.split('.')[0] if className.endswith('()'): className = className[:-2] caller = modName + '.' + className return caller
def testcached_value(): class HasFieldWithDefault: foo = Field(default='bar') has_field_w_default = HasFieldWithDefault() foo_field = inspect.getattr_static(has_field_w_default, 'foo') assert foo_field.cached_value is UNSET assert has_field_w_default.foo == 'bar' assert foo_field.cached_value == 'bar' class HasFieldWithDefaultFactory: foo = Field(default_factory=list) has_field_w_default_factory = HasFieldWithDefaultFactory() foo_field = inspect.getattr_static(has_field_w_default_factory, 'foo') assert foo_field.cached_value is UNSET assert has_field_w_default_factory.foo == list() assert foo_field.cached_value == list() class HasFieldWithDefaultValueAndFactory: foo = Field(default=1, default_factory=lambda x: x + 1) has_field_w_default_val_and_factory = HasFieldWithDefaultValueAndFactory() foo_field = inspect.getattr_static(has_field_w_default_val_and_factory, 'foo') assert foo_field.cached_value is UNSET assert has_field_w_default_val_and_factory.foo == 2 assert has_field_w_default_val_and_factory.foo == 2 assert foo_field.cached_value == 2
def inheritance_conflicts(c1, c2): class c1c2(c1, c2): pass class c2c1(c2, c1): pass return [attr for attr in dir(c1c2) if getattr_static( c1c2, attr) != getattr_static(c2c1, attr)]
def __call__(self, attempt: CallAttempt): if type(attempt.func) is not bound_method_type: return None # todo get these statically owner = attempt.func.__self__ if not _passes_constraint(type(owner), self.optional_positional[0]): return None func = getattr_static(attempt.func, '__func__', None) or getattr_static(type(owner), attempt.func.__name__) new_attempt = CallAttempt(func, (owner, *attempt.args), attempt.kwargs) return super().__call__(new_attempt)
def inheritance_conflicts(c1: Type[object], c2: Type[object]) -> List[str]: """Return attributes defined differently in classes c1 and c2""" class c1c2(c1, c2): # type: ignore pass class c2c1(c2, c1): # type: ignore pass return [attr for attr in dir(c1c2) if getattr_static( c1c2, attr) != getattr_static(c2c1, attr)]
def __init__(self, name, func, param, sources): self.name = name self.func = func self.param = param self.source = sources self.setup = inspect.getattr_static(sources, 'setup', None) self.teardown = inspect.getattr_static(sources, 'teardown', None) self.instance = sources()
def test_types(qtbot): p = P(a=1, b=2, c=3) # TODO: this would be nice but all ideas so far are ugly # assert isinstance(P.a, attr.Attribute) assert isinstance(attr.fields(P).a, attr.Attribute) assert isinstance(inspect.getattr_static(p, 'a'), property) assert isinstance(inspect.getattr_static(p, 'c'), PyQt5.QtCore.pyqtProperty)
def inheritance_conflicts(c1, c2): """Return attributes defined differently in classes c1 and c2""" class c1c2(c1, c2): pass class c2c1(c2, c1): pass return [attr for attr in dir(c1c2) if getattr_static( c1c2, attr) != getattr_static(c2c1, attr)]
def deserialize(clazz: str, args=None): if args is None: args = {} type_ = get_type(clazz) try: inspect.getattr_static(type_, "deserialize") # noinspection PyUnresolvedReferences return type_.deserialize(**args) except AttributeError: return type_(**args)
def getCaller(callLevel=2): """ Function to get the FQN of caller (FQN = module.class.function or module.function) :return: The name of the calling function """ of = inspect.getouterframes(inspect.currentframe())[callLevel][0] try: callObj = of.f_locals['self'] if isinstance(callObj, object): print('yes') try: packageName = inspect.getattr_static( callObj, '__package__') except AttributeError: packageName = None moduleName = inspect.getattr_static(callObj, '__module__') className = str(of.f_locals['self']).split( '<')[1].split()[0].split()[0].split('.')[1] cs = inspect.stack() fxName = cs[callLevel][3] if packageName is not None: caller = packageName + '.' + moduleName + '.' + className + '.' + fxName else: caller = moduleName + '.' + className + '.' + fxName else: raise KeyError() except IndexError: caller = of.f_locals['self'] except KeyError: cs = inspect.stack() callObj = cs[callLevel + 1][4][0].split('=')[1].strip() dynMod = inspect.getmodule(callObj) dmm = inspect.getmembers(dynMod) cm = inspect.getmembers(callObj) try: packageName = inspect.getattr_static(dmm, '__package__') except AttributeError: packageName = None pathArray = str(cs[callLevel][1]).replace('/', '|').replace( path.sep, '|').split('|') modName = pathArray[len(pathArray) - 1].split('.')[0] className = callObj.split('.')[0] fxName = callObj.split('.')[1][:-2] if packageName is None: caller = modName + '.' + className + '.' + fxName else: caller = packageName + '.' + modName + '.' + className + '.' + fxName ''' if caller == '<module>': caller = cs[callLevel][0].f_locals['__name__'] caller = mod + '.' + caller ''' return caller
def test_slots(self): class Thing(object): y = 'bar' __slots__ = ['x'] def __init__(self): self.x = 'foo' thing = Thing() self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x) self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar') del thing.x self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
def get_magic_methods(cls) -> MagicMethods: magic_methods = {} for func in [ inspect.getattr_static(cls, func) for func in dir(cls) if callable(inspect.getattr_static(cls, func)) and func.startswith("__") ]: if func.__name__ in binary_magic_mappings.keys(): signature = inspect.signature(func) symbol, protocol, default_type = binary_magic_mappings[ func.__name__] rhs = list(signature.parameters.items())[1][1].annotation return_value = signature.return_annotation if signature.return_annotation != inspect.Parameter.empty else None magic_methods[func.__name__.lstrip('_')] = BinaryMagicMethod( symbol=symbol, python_magic_method=func.__name__, swift_protocol_name=protocol, right_classes=[(rhs, return_value or default_type)]) elif func.__name__ in unary_magic_mappings.keys(): symbol, protocol, default_type = unary_magic_mappings[ func.__name__] magic_methods[func.__name__.lstrip('_')] = UnaryMagicMethod( symbol=symbol, python_magic_method=func.__name__, swift_protocol_name=protocol, ) elif func.__name__ == '__len__': magic_methods[func.__name__.lstrip('_')] = True elif func.__name__ == '__getitem__': signature = inspect.signature(func) magic_methods[func.__name__.lstrip('_')] = SimpleNamespace( index_type=list(signature.parameters.items())[1][1].annotation, return_type=signature.return_annotation if signature.return_annotation != inspect.Parameter.empty else None, ) generic = getattr(cls, '__orig_bases__', [None])[0] if generic and len(generic.__args__) == 1: magic_methods['Sequence'] = True # elif generic and len(generic.__args__) == 2: # magic_methods['DictLike'] = True elif func.__name__ == '__setitem__': magic_methods[func.__name__.lstrip('_')] = True for protocol_name in get_swift_wrapper_annotations(cls): if protocol_name in expressible_by_literal_protocols.keys(): magic_methods[protocol_name] = ExpressibleByLiteralProtocol( protocol_name=protocol_name, literal_type=expressible_by_literal_protocols[protocol_name], ) return MagicMethods(**magic_methods)
def apply(self, attrs=None, kattrs=None, merge=False): """ Apply new attributes or classes to the target """ for attr in attrs: kattrs = kattrs or {} # Treat objects as assigned to their name if hasattr(attr, "__name__"): kattrs[attr.__name__] = attr else: kattrs[attr] = inspect.getattr_static(self.source, attr) for attr, value in kattrs.items(): old_value = inspect.getattr_static(self.target, attr, None) # If callable, preserve old func if callable(value) and callable(old_value): # Prevent duplicate patching if value in patchy_records: continue patchy_records[value] = old_value # Merge collections and classes instead of replacing if merge: if isinstance(old_value, abc.Container): if isinstance(value, abc.Mapping) and isinstance( old_value, abc.MutableMapping): old_value.update(value) logger.info('Merging mapping {mod}.{attr}'.format( mod=self.target.__name__, attr=attr)) elif isinstance(value, abc.Sequence) and isinstance( old_value, abc.MutableSequence): old_value.extend(value) logger.info('Merging sequence {mod}.{attr}'.format( mod=self.target.__name__, attr=attr)) elif isinstance(value, abc.Set) and isinstance( old_value, abc.MutableSet): old_value.update(value) logger.info('Merging set {mod}.{attr}'.format( mod=self.target.__name__, attr=attr)) else: setattr(self.target, attr, value) logger.info( "Couldn't merge collection {target}.{attr}, replaced instead" .format(target=self.target.__name__, attr=attr)) continue elif isinstance(old_value, type): logger.info('Merging class for {target}.{attr}'.format( target=self.target.__name__, attr=attr)) self.cls(old_value, value).auto() continue logger.info('Setting value {target}.{attr}'.format( target=self.target.__name__, attr=attr)) # Apply patched value setattr(self.target, attr, value)
def test_slots(self): class Thing(object): y = "bar" __slots__ = ["x"] def __init__(self): self.x = "foo" thing = Thing() self.assertEqual(inspect.getattr_static(thing, "x"), Thing.x) self.assertEqual(inspect.getattr_static(thing, "y"), "bar") del thing.x self.assertEqual(inspect.getattr_static(thing, "x"), Thing.x)
def t1(): print = old_print c = C() print('c.__dict__') c.__dict__ print('c.__getattribute__') c.__getattribute__ print('c.__iter__()') c.__iter__() print('c.__getattribute__(__iter__)()') c.__getattribute__(__iter__)() print('getattr(c, __iter__)()') getattr(c, __iter__)() print('iter(c)') iter(c) print('c.f()') c.f() print('getattr(c, __getattribute__)') getattr(c, __getattribute__) import inspect print('inspect.getattr_static(C, __getattribute__)') inspect.getattr_static(C, __getattribute__) print('inspect.getattr_static(D, __getattribute__)') inspect.getattr_static(D, __getattribute__) d = D() print('iter(d)') iter(d) print('d.__dict__') d.__dict__ print('assert not d.__dict__') assert not d.__dict__ print('c.__f__') c.__f__() print('C.__f__(c)') C.__f__(c)
def test_mro_as_property(self): class Meta(type): @property def __mro__(self): return (object,) class Base(object): foo = 3 class Something(Base, metaclass=Meta): pass self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3) self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
def __init__(self, *args, **kw): if not 'spec' in kw: kw['spec'] = AbstractAssetManager super().__init__(*args, **kw) if 'wraps' in kw and hasattr(kw['wraps'], 'asset_content'): wraps = kw['wraps'] attr = inspect.getattr_static(wraps, 'asset_content') # prop = Property[Mapping[AnyStr, AnyStr]](attr, 'asset_content') assets_attr = inspect.getattr_static(wraps, 'assets') # type(self).assets = PropertyMock(wraps=Property(wraps, 'assets', {})) else: logger.critical("not stuffing property mock")
def test_class_as_property(self): class Base(object): foo = 3 class Something(Base): executed = False @property def __class__(self): self.executed = True return object instance = Something() self.assertEqual(inspect.getattr_static(instance, 'foo'), 3) self.assertFalse(instance.executed) self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
def is_method_static(cls, method_name): try: return isinstance(inspect.getattr_static(cls, method_name), staticmethod) except AttributeError: raise RuntimeError("Unable to find %s in %s" % (method_name, cls.__name__))
def getattr_safe(obj, name): """side effect free getattr (calls getattr_static).""" result = inspect.getattr_static(obj, name) # Slots are a MemberDescriptorType if isinstance(result, MemberDescriptorType): result = getattr(obj, name) return result
def test_property(self): class Thing(object): @property def x(self): raise AttributeError("I'm pretending not to exist") thing = Thing() self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
def __init__(self, path): dict.__init__(self) if not os.path.exists(path): raise FileNotFoundError(path) name, extension = os.path.splitext(path) # Don't want to create the __pycache__ folder in the users project. original_value = sys.dont_write_bytecode sys.dont_write_bytecode = True self.module = imp.load_module(os.path.basename(name), open(path), path, (extension, 'r', imp.PY_SOURCE)) for method in inspect.getmembers(self.module): name = method[0] item = inspect.getattr_static(self.module, name) if isinstance(item, pyke.TargetWrapper): self[name] = item sys.dont_write_bytecode = original_value self.path = os.path.dirname(path) self.meta_path = os.path.join(self.path, '.pyke') if not os.path.exists(self.meta_path): os.mkdir(self.meta_path) if platform.system().lower() == 'windows': ctypes.windll.kernel32.SetFileAttributesW(self.meta_path, 2) self.meta = meta.File(os.path.join(self.meta_path, 'pyke.json')) self.builders = builders.Factory()
def test_inherited_classattribute(self): class Thing(object): x = object() class OtherThing(Thing): pass self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
def __new__(cls, name, bases, namespace, **kwargs): self = super(__class__, cls).__new__(cls, name, bases, namespace, **kwargs) new_finals = frozendict((attr, obj) for attr, obj in namespace.items() if isinstance(obj, final_attr)) self.__this_finals = new_finals #print(self, list(self.mro())) _self, iter_bases = head_ex(base for base in self.mro()) assert _self is self dicts = map(cls.get_this_finals, iter_bases) # NOTE: order is important: ([new_finals], dicts) dicts = tuple(chain([new_finals], dicts)) finals = sum_dicts(dicts) if len(finals) != sum(map(len, dicts)): raise FinalAttrCollisionError('final attrs collision') #print(finals) #print(self, sorted(vars(self))) for attr in finals: #print(attr) #print(type(getattr_static(self, attr))) if getattr(self, attr) is not finals[attr].__get__(None, self) or\ getattr_static(self, attr) is not finals[attr]: raise FinalAttrCollisionError( 'override final attr: {!r}'.format(attr)) return self
def _get_relevant_values(self, source, frame): value = None is_attribute = False is_valid_value = False for token in self._syntax_highlighter.tokenize(source): type_, string, (_, col), *_ = token if type_ == tokenize.NAME and not keyword.iskeyword(string): if not is_attribute: for variables in (frame.f_locals, frame.f_globals): try: value = variables[string] except KeyError: continue else: is_valid_value = True yield (col, self._format_value(value)) break elif is_valid_value: try: value = inspect.getattr_static(value, string) except AttributeError: is_valid_value = False else: yield (col, self._format_value(value)) elif type_ == tokenize.OP and string == ".": is_attribute = True else: is_attribute = False is_valid_value = False
def getmembers_static(object, predicate=None): """ Return all members of an object as (name, value) pairs sorted by name via `getattr_static`. Optionally, only return members that satisfy a given predicate. - A static version of `get_members` function at: https://github.com/python/cpython/blob/3.9/Lib/inspect.py#L326-L368 https://github.com/python/cpython/blob/14ba761078b5ae83519e34d66ab883743912c45b/Lib/inspect.py#L444-L486 - `getmembers` function (from the inspect module) triggers execution instead of doing static analysis. - This leads to errors, particularly on properties of classes in cindex.py, which causes segmentation errors or raises an Exception if a particular condition is not satisfied. - To curb this, we fetch the members statically. We define a custom function based on the one in the inspect module. """ results = [] names = dir(object) # :dd any DynamicClassAttributes to the list of names if object is a class; # this may result in duplicate entries if, for example, a virtual # attribute with the same name as a DynamicClassAttribute exists try: base_members = filter( lambda k, v: isinstance(v, types.DynamicClassAttribute), object.__bases__.__dict__.items(), ) names.extend(base_members) except AttributeError: pass for key in names: value = inspect.getattr_static(object, key) if not predicate or predicate(value): results.append((key, value)) results.sort(key=lambda pair: pair[0]) return results
def test_metaclass_with_metaclass_with_dict_as_property(self): class MetaMeta(type): @property def __dict__(self): self.executed = True return dict(spam=42) class Meta(type, metaclass=MetaMeta): executed = False class Thing(metaclass=Meta): pass with self.assertRaises(AttributeError): inspect.getattr_static(Thing, "spam") self.assertFalse(Thing.executed)
def test_kernconf(): # Parse args once to ensure target_manager is initialized # check default values config = _parse_arguments([]) cheribsd_cheri = _get_cheribsd_instance("cheribsd-mips64-hybrid", config) cheribsd_mips = _get_cheribsd_instance("cheribsd-mips64", config) freebsd_mips = _get_target_instance("freebsd-mips64", config, BuildFreeBSD) freebsd_native = _get_target_instance("freebsd-amd64", config, BuildFreeBSD) assert config.freebsd_kernconf is None assert freebsd_mips.kernel_config == "MALTA64" assert cheribsd_cheri.kernel_config == "CHERI_MALTA64" assert freebsd_native.kernel_config == "GENERIC" # Check that --kernconf is used as the fallback config = _parse_arguments(["--kernconf=LINT", "--freebsd-mips64/kernel-config=NOTMALTA64"]) assert config.freebsd_kernconf == "LINT" attr = inspect.getattr_static(freebsd_mips, "kernel_config") # previously we would replace the command line attribute with a string -> check this is no longer true assert isinstance(attr, JsonAndCommandLineConfigOption) assert freebsd_mips.kernel_config == "NOTMALTA64" assert cheribsd_cheri.kernel_config == "LINT" assert freebsd_native.kernel_config == "LINT" config = _parse_arguments(["--kernconf=LINT", "--cheribsd-mips64-hybrid/kernel-config=SOMETHING"]) assert config.freebsd_kernconf == "LINT" assert freebsd_mips.kernel_config == "LINT" assert cheribsd_cheri.kernel_config == "SOMETHING" assert freebsd_native.kernel_config == "LINT" config = _parse_arguments(["--kernconf=GENERIC", "--cheribsd/kernel-config=SOMETHING_ELSE"]) assert config.freebsd_kernconf == "GENERIC" assert cheribsd_cheri.kernel_config == "SOMETHING_ELSE" assert cheribsd_mips.kernel_config == "SOMETHING_ELSE" assert freebsd_mips.kernel_config == "GENERIC" assert freebsd_native.kernel_config == "GENERIC"
def _property_names(self): """Return a set of the names of the properties defined on the model.""" names = [] for name in dir(self.model): attr = inspect.getattr_static(self.model, name) if isinstance(attr, property): names.append(name) return frozenset(names)
def triggers(cls): """Property returning all statically declared triggers.""" tl = {} for member_name in dir(cls): member = inspect.getattr_static(cls, member_name) if isinstance(member, TriggerBase): tl[member_name] = member return tl
def test_metaclass(self): class meta(type): attr = 'foo' class Thing(object, metaclass=meta): pass self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo') class sub(meta): pass class OtherThing(object, metaclass=sub): x = 3 self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo') class OtherOtherThing(OtherThing): pass # this test is odd, but it was added as it exposed a bug self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
def test_descriptor(self): class descriptor(object): def __get__(self, instance, owner): return 3 class Foo(object): d = descriptor() foo = Foo() # for a non data descriptor we return the instance attribute foo.__dict__['d'] = 1 self.assertEqual(inspect.getattr_static(foo, 'd'), 1) # if the descriptor is a data-desciptor we should return the # descriptor descriptor.__set__ = lambda s, i, v: None self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
def cant_modify(self, name): class_repr = repr(self.__class__.__name__) name_repr = repr(name) if inspect.getattr_static(self, name, MISSING) is MISSING: format_msg = "{class_repr} object has no attribute {name_repr}" else: format_msg = "{class_repr} object attribute {name_repr} is read-only" raise AttributeError(format_msg.format(class_repr=class_repr, name_repr=name_repr))
def activities(cls): """Property returning all statically declared activities.""" al = {} for member_name in dir(cls): member = inspect.getattr_static(cls, member_name) if isinstance(member, ActivityBase): al[member_name] = member return al
def is_strategy_static(player_class) -> bool: """ Returns True if `player_class.strategy` is a `staticmethod`, else False. """ for class_ in player_class.mro(): method = inspect.getattr_static(class_, "strategy", default=None) if method is not None: return isinstance(method, staticmethod)
def test_inherited(self): class Thing(object): x = object() class OtherThing(Thing): pass something = OtherThing() self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
def is_index_property(obj: object, name: str) -> bool: """Check if an object property is index_property like. This is needed to correctly generate Colander schema for index_property in SQLAlchemy models. """ # http://docs.sqlalchemy.org/en/rel_1_1/changelog/migration_11.html#new-indexable-orm-extension attr = inspect.getattr_static(obj, name) return isinstance(attr, index_property)
def ports(cls) -> dict: """Property returning all statically declared ports.""" ps = {} for member_name in dir(cls): member = inspect.getattr_static(cls, member_name) if isinstance(member, PortDescriptorBase): ps[member_name] = member return ps
def test_descriptor(self): class descriptor(object): def __get__(*_): raise AttributeError("I'm pretending not to exist") desc = descriptor() class Thing(object): x = desc thing = Thing() self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
def __subclasscheck__(cls, subclass): """Override for isinstance(instance, cls).""" if cls is subclass: return True # TODO: support attributes for name, signature in cls.__signatures__.items(): try: function = inspect.getattr_static(subclass, name) except AttributeError: return False if isinstance(function, (staticmethod, classmethod)): return False try: subclass_signature = inspect.signature(function) except TypeError: return False except ValueError: # we probably got a builtin return True cls_params = list(signature.parameters.values()) subclass_params = list(subclass_signature.parameters.values()) subclass_params.pop(0) # remove 'self' if len(cls_params) != len(subclass_params): return False for cls_param, instance_param in zip(cls_params, subclass_params): if cls_param.name != instance_param.name: return False cls_annotation = cls_param.annotation instance_annotation = instance_param.annotation if cls_annotation is EMPTY_ANNOTATION: cls_annotation = AnyType if instance_annotation is EMPTY_ANNOTATION: instance_annotation = AnyType if not issubclass(cls_annotation, instance_annotation): return False cls_annotation = signature.return_annotation instance_annotation = subclass_signature.return_annotation if cls_annotation is EMPTY_ANNOTATION: cls_annotation = AnyType if instance_annotation is EMPTY_ANNOTATION: instance_annotation = AnyType if not issubclass(instance_annotation, cls_annotation): return False return True
def get_descriptor(cls, descname): """ Returns the descriptor object that is stored under *descname* instead of whatever the descriptor would have returned from its `__get__()` method. :param cls: class to find the descriptor on :param descname: name of the descriptor :return: the descriptor stored under *descname* on *instance* """ return inspect.getattr_static(cls, descname)
def test_metaclass_with_descriptor(self): class descriptor(object): def __get__(self, instance, owner): return 3 class meta(type): d = descriptor() class Thing(object, metaclass=meta): pass self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
def is_json_property(cls, obj, name): """Check if given attribute on an object is JSONBProperty. :param obj: Python object :return: True or False """ attr = python_inspect.getattr_static(obj, name) return isinstance(attr, JSONBProperty)
def __initialize_descriptors(self): """Initializes the DescriptorInstance instances in this object.""" # I'm not sure whether this function has any effect. Descriptors are initialized when they are first requested # anyways. I probably had a reason why some descriptors had to be initialized during initialization back when I # made this function. - Aaron klass = type(self) for member_name in dir(klass): member = inspect.getattr_static(klass, member_name) if isinstance(member, DescriptorStatic): getattr(self, member_name)
def __init__(self): # type(self).__dict__ wouldn't return inherited messages, hence dir self.message_groups = [] for name in dir(self): group_class = getattr_static(self, name) if isinstance(group_class, type) and \ issubclass(group_class, MessageGroup) and \ group_class is not MessageGroup: bound_group = group_class(self) setattr(self, name, bound_group) self.message_groups.append(bound_group) self.message_groups.sort(key=attrgetter("severity"), reverse=True)
def test_inherited_slots(self): # returns descriptor class Thing(object): __slots__ = ['x'] def __init__(self): self.x = 'foo' class OtherThing(Thing): pass # it would be nice if this worked... # we get the descriptor instead of the instance attribute self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
def __getattr__(self, name): # First look for a resource factory in the whole context chain for ctx in self.context_chain: factory = ctx._resource_factories_by_context_attr.get(name) if factory: return factory.generate_value(self) # When that fails, look directly for an attribute in the parents for ctx in self.context_chain[1:]: value = getattr_static(ctx, name, None) if value is not None: return getattr(ctx, name) raise AttributeError('no such context variable: {}'.format(name))
def test_metaclass_dict_as_property(self): class Meta(type): @property def __dict__(self): self.executed = True class Thing(metaclass=Meta): executed = False def __init__(self): self.spam = 42 instance = Thing() self.assertEqual(inspect.getattr_static(instance, "spam"), 42) self.assertFalse(Thing.executed)