def test_no_source_file(): code = compile("lambda x: 12", __file__, "eval") with pytest.raises(AttributeError): qualname(code) fn = eval(code) with pytest.raises(AttributeError): qualname(code)
def _get_callable(obj, of_class = None): """ Get callable for an object and its full name. Supports: * functions * classes (jumps to __init__()) * methods * @classmethod * @property :param obj: function|class :type obj: Callable :param of_class: Class that this method is a member of :type of_class: class|None :return: (qualname, Callable|None, Class|None). Callable is None for classes without __init__() :rtype: (str, Callable|None, Class|None) """ # Cases o = obj if inspect.isclass(obj): try: o = obj.__init__ of_class = obj except AttributeError: pass # Finish return qualname(obj), o, of_class
def allowed_client_methods(self): method_names = [] if self.client_methods_gatekeeper: methods = self.client_methods_gatekeeper.allowed for method in methods: method_names.append(qualname(method)) return method_names
def get_qualname(fn): # Python >= 3.3 only try: return fn.__qualname__.split('.') except AttributeError: pass # Python < 3.3 try: import qualname return qualname.qualname(fn).split('.') except ImportError: pass # Hack: Issue error if we're wrapping a class method and failed to # get the qualname import inspect context = [ x[0].f_code.co_name for x in inspect.stack() if '__module__' in x[0].f_code.co_names and inspect.getmodule(x[0].f_code).__name__ != __name__ ] if len(context) > 0: raise Exception( 'To use a task defined in a class, please upgrade to Python >= 3.3 or install qualname (e.g. pip install qualname)' ) return [fn.__name__]
def wrapped(*args, **kwargs): before = time.time() try: return f(*args, **kwargs) finally: stop = time.time() print("{} +{:f} ".format(qualname(f), (stop - before) * 1000))
def safe_qualname(obj): result = safe_qualname._cache.get(obj) if not result: try: result = qualname(obj) except AttributeError: result = obj.__name__ if '<locals>' not in result: safe_qualname._cache[obj] = result return result
def closure_params(closure): """ Stores closure parameters in a dict Parameters ---------- closure : function A closure function Returns ------- out : dict Dictionary """ if sys.version_info >= (3, 4): pass else: from qualname import qualname attrs = {} for cell_name, cell in zip(closure.__code__.co_freevars, closure.__closure__): cell_contents = cell.cell_contents if not callable(cell_contents): if "params" not in attrs: attrs["params"] = {} attrs["params"][cell_name] = cell_contents if sys.version_info >= (3, 4): attrs["type"] = closure.__qualname__.split(".")[0] else: attrs["type"] = qualname(closure).split(".")[0] else: attrs[cell_name] = closure_params(cell_contents) if sys.version_info >= (3, 4): attrs[cell_name]["type"] = cell_contents.__qualname__.split("." )[0] else: attrs[cell_name]["type"] = qualname(cell_contents).split(".")[0] return attrs
def filter_queryset(self, request, queryset, view): filter_class = getattr(view,'filter_class', None) if filter_class is None: return queryset if not issubclass(filter_class, BaseFilterset): raise TypeError("%s expects filter_class to be %s: %s" % (qualname(self.__class__), qualname(BaseFilterset), repr(filter_class))) if not hasattr(view,'get_queryset'): raise TypeError("%s expects view to have get_queryset method" % (qualname(self.__class__),)) if issubclass(filter_class, ModelFilterset): fs_model = filter_class.Meta.model qs_model = view.get_queryset()._document if not issubclass(qs_model, fs_model): raise TypeError("filter and view document class mismatch: %s vs %s " % (qualname(fs_model), qualname(qs_model))) filterset = filter_class(request.query_params) return filterset.filter_queryset(queryset)
def safe_qualname(cls): # type: (type) -> str result = _safe_qualname_cache.get(cls) if not result: try: result = qualname(cls) except (AttributeError, IOError, SyntaxError): result = cls.__name__ if '<locals>' not in result: _safe_qualname_cache[cls] = result return result
def autodoc_skip_member(app, what, name, obj, skip, options): # skip everything that isn't decorated with @autobahn.public or .. if hasattr(obj, '_is_public') and obj._is_public: if qualname: try: qn = qualname(obj) except AttributeError as e: print(e) qn = name print('public API: {}.{}'.format(obj.__module__, qn)) return False else: return True
def model_equation(eqparam, funccomp): """ The module which builds and evaluates the EBM by adding functions parsed through the **funccomp**. Input has to be given as `Dictionaries` supplied by ``lowEBMs.Packages.Configuration.importer`` from a specific **configuration.ini**. **Function-call arguments** \n :param dict eqparam: Configuration dictionary containing additional information for the model equation: * C_ao: The systems heat capacity (times the height of the system) * type: float * unit: Joule*Meter/Kelvin * value: > 0 :param dict funccomp: Configuration 2D dictionary containing function names and function parameters used: * funcnames: a dictionary of names of functions defined in ``lowEBMs.Packages.Functions`` which are added up. See :doc:`here <functions>` for a list of functions * funcparams: a dictionary of functions parameters corresponding to the functions chosen within **funcnames**. For details on the parameters see the specific function :doc:`here <functions>` :returns: The temperature gradient :math:`\\frac{dT}{dt}` (Kelvin/seconds) :rtype: float or array(float), depending on 0D EBM or 1D EBM. In 1D, output is an array containing the temperature gradient for each latitudinal belt. """ y = 0 #variable which can be used to sum up functions funclist = funccomp[ 'funclist'] #Extracting needed arrays from the funccomp array funcparam = funccomp['funcparam'] C_ao = eqparam['c_ao'] #Extracting Equationparameters if builtins.parallelization == True: C_ao = np.transpose(np.array( [C_ao] * len(Vars.Lat))) if np.shape(C_ao) == ( builtins.number_of_parallels, ) else C_ao for funcnum in funclist: if builtins.control == True: if qualname(funclist[funcnum])[:7] == 'forcing': pass else: y += funclist[funcnum]( funcparam[funcnum] ) #Calling the selected function and sum them up else: y += funclist[funcnum]( funcparam[funcnum] ) #Calling the selected function and sum them up return y / C_ao #output of y, weighted with the heat capacity
def get_path(obj): # type: (Any) -> str """ Get full import path to an object. .. code:: python >>> from abc import abstractmethod >>> from objetto.utils.lazy_import import get_path >>> get_path(abstractmethod) 'abc|abstractmethod' :param obj: Object. :return: Import path. :rtype: str :raises ValueError: Can't determine consistent import path. """ module = obj.__module__ if not module: error = "can't get module for {}".format(obj) raise ValueError(error) try: qual_name = qualname(obj) if not qual_name: raise AttributeError() except AttributeError: qual_name = obj.__name__ if not qual_name: error = "can't get name for {}".format(obj) raise ValueError(error) path = "|".join((module, qual_name)) try: imported_obj = import_path(path) except (ValueError, ImportError): imported_obj = None if imported_obj is not obj: error = "can't get consistent import path to {}".format(obj) raise ValueError(error) return path
def filter_queryset(self, request, queryset, view): filter_class = getattr(view, 'filter_class', None) if filter_class is None: return queryset if not issubclass(filter_class, BaseFilterset): raise TypeError("%s expects filter_class to be %s: %s" % (qualname( self.__class__), qualname(BaseFilterset), repr(filter_class))) if not hasattr(view, 'get_queryset'): raise TypeError("%s expects view to have get_queryset method" % (qualname(self.__class__), )) if issubclass(filter_class, ModelFilterset): fs_model = filter_class.Meta.model qs_model = view.get_queryset()._document if not issubclass(qs_model, fs_model): raise TypeError( "filter and view document class mismatch: %s vs %s " % (qualname(fs_model), qualname(qs_model))) filterset = filter_class(request.query_params) return filterset.filter_queryset(queryset)
def __fullname__(cls): # type: () -> str """ Get qualified class name if possible, fall back to class name otherwise. :return: Full class name. :rtype: str """ try: name = qualname(cls) if not name: raise AttributeError() except AttributeError: name = cls.__name__ return name
def inner(self, *args, **kwargs): call_info = call_info_nt(orig_method, args, kwargs, None, None) client_methods_gatekeeper(qualname(func), call_info) ret = None error = None try: ret = func(self, *args, **kwargs) except Exception as error: pass finally: call_info = call_info_nt(func, args, kwargs, ret, error) call_store.append(call_info) if error: # Probably rework this flow, probably messes up chaining raise error return ret
def get_class_name_from_method(func): # type: (Any) -> str if hasattr(func, "__self__"): class_name = func.__self__.__class__.__name__ elif hasattr(func, "__class__"): class_name = func.__class__.__name__ else: raise Protocol0Error("Cannot get class_name from func") if class_name and all(word not in class_name for word in ["function", "None"]): return class_name try: return ".".join(qualname(func).split(".")[:-1]) except (AttributeError, IOError): return "unknown %s" % func
def find_qualified_name(obj): name = None try: name = qualname(obj) except (AttributeError, IOError): pass if name is None: try: name = obj.__name__ except AttributeError: pass if name is None: name = repr(obj) module = inspect.getmodule(obj) return '.'.join(filter(None, (getattr(module, '__name__', ''), name)))
def add_dir(self, *args): if not args: raise TypeError( 'AddonDirectory.add_dir() Missing endpoint argument') name = None params = () if len(args) < 2: if isinstance(args[0], str): name = endpoint = args[0] else: endpoint = args[0] elif len(args) < 3: name, endpoint = args else: raise TypeError('AddonDirectory.add_dir() Too many arguments') if isinstance(endpoint, Call): endpoint, params = endpoint.method, endpoint.args if ismethod(endpoint): obj = endpoint.__self__ ser = obj if not params: params = (), {} params = (ser, ) + params[0], params[1] if name is None: handle = self.addon._find_call(endpoint) if handle: name = getattr(handle, 'title', endpoint) else: name = endpoint url = self.addon.mkurl(qualname(endpoint), params=params or None) item = xbmcgui.ListItem(name) xbmcplugin.addDirectoryItem(handle=self.addon.id, url=url, listitem=item, isFolder=True) print('DD : %r : %r' % (name, url)) print('ITEM·%s·%s·' % (name, url)) return item
def test_local_classes_with_same_name(): assert qualname(class_maker1()) == 'class_maker1.<locals>.C' X, Y, Z = class_maker2() assert qualname(X) == 'class_maker2.<locals>.X' assert qualname(Y) == 'class_maker2.<locals>.Y' assert qualname(Z) == 'class_maker2.<locals>.Z' assert qualname(X.D) == 'class_maker2.<locals>.X.D' assert qualname(Y.D) == 'class_maker2.<locals>.Y.D' assert qualname(Z.D) == 'class_maker2.<locals>.Z.D' assert qualname(X.D.f1) == 'class_maker2.<locals>.X.D.f1' assert qualname(X.D.f2) == 'class_maker2.<locals>.X.D.f2' assert qualname(Y.D.g) == 'class_maker2.<locals>.Y.D.g' assert qualname(Z.D.h) == 'class_maker2.<locals>.Z.D.h' assert qualname(Z.D.i) == 'class_maker2.<locals>.Z.D.i' A1, A2 = class_maker3() options = ['class_maker3.<locals>.A1.B', 'class_maker3.<locals>.A2.B'] assert qualname(A1.B) in options assert qualname(A2.B) in options
def test_classes_with_same_name(): assert qualname(C.D) == 'C.D' assert qualname(D) == 'D'
def test_problematic_docstring(): assert qualname(ClassWithProblematicDocstring.InnerClass) == 'ClassWithProblematicDocstring.InnerClass'
def test_builtins(): assert qualname(int) == 'int' assert qualname(len) == 'len'
def test_directly_constructed_type(): new_type = type('NewCls', (object,), {}) assert qualname(new_type) == 'NewCls'
def key_name(func): return '{module}.{name}'.format( module=func.__module__, name=qualname(func), )
def test_nested_functions(): assert qualname(f) == 'f' assert qualname(f()) == 'f.<locals>.g' assert qualname(C.D.h()) == 'C.D.h.<locals>.i.<locals>.j'
def fullname(obj): """Return a fully qualified name for a module, function, class, etc.""" if hasattr(obj, '__module__'): return obj.__module__ + '.' + qualname(obj) else: return obj.__name__
def test_builtin(): assert qualname(int) == 'int' assert qualname(DeprecationWarning) == 'DeprecationWarning'
def add_path(config, view, path, **kwargs): route_name = '%s_%s' % (qualname(view), path.replace('/', '_').split('{')[0]) config.add_route(route_name, path) config.add_view(view, route_name=route_name, **kwargs)
def test_nested_classes(): assert qualname(C) == 'C' assert qualname(C.D) == 'C.D'
def test_methods_in_nested_classes(): assert qualname(C.f) == 'C.f' assert qualname(C.D.g) == 'C.D.g'
def qual_name_safe(f): try: return f.__qualname__ except AttributeError: # Occurs when Python <= 3.3 from qualname import qualname return qualname(f)
def output_importer(functiondict): functionlist = list(functiondict.values()) """ Creates empty lists for the storage-variables which will be filled during the simulation. The lists are directly written to their entry in ``Variable.Vars`` and can be returned after the simulation is finished. """ if (builtins.number_of_integration) % builtins.data_readout == 0: #Assigning dynamical variables in Variables Package with initial values from var for func in functionlist: if qualname(func) == 'transfer.sellers': Vars.cL = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.C = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.F = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.P = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.Transfer = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) if qualname(func) == 'transfer.budyko': Vars.BudTransfer = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) if qualname(func) == 'forcing.co2_myhre': Vars.CO2Output = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) if qualname(func) == 'forcing.solar': Vars.SolarOutput = np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) if qualname(func) == 'forcing.aod': Vars.AODOutput == np.array([0] * int( builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.ExternalOutput = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.alpha = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.solar = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.noise = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) Vars.Rdown = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) #Vars.Rup=np.reshape(np.zeros(int(builtins.number_of_integration/builtins.data_readout)*len(Vars.Lat)),(int(builtins.number_of_integration/builtins.data_readout),len(Vars.Lat))) Vars.Rup = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout), dtype=object) else: for func in functionlist: if qualname(func) == 'transfer.sellers': Vars.cL = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.C = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.F = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.P = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.Transfer = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) if qualname(func) == 'transfer.budyko': Vars.BudTransfer = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) if qualname(func) == 'forcing.co2_myhre': Vars.CO2Output = np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) if qualname(func) == 'forcing.solar': Vars.SolarOutput = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) if qualname(func) == 'forcing.aod': Vars.AODOutput == np.array([0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.ExternalOutput = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.alpha = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.solar = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.noise = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.Rdown = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) #Vars.Rup=np.reshape(np.zeros(int(builtins.number_of_integration/builtins.data_readout)*len(Vars.Lat)),(int(builtins.number_of_integration/builtins.data_readout),len(Vars.Lat))) Vars.Rup = np.array( [0] * int(builtins.number_of_integration / builtins.data_readout + 1), dtype=object) Vars.ExternalOutput = np.array([ Vars.ExternalOutput for i in range(int(builtins.number_of_externals)) ], dtype=object) Vars.External_time_start = np.array( [0 for i in range(int(builtins.number_of_externals))], dtype=object) Vars.ForcingTracker = np.array( [[0, 0] for i in range(int(builtins.number_of_externals))], dtype=object) Vars.ExternalInput = np.array( [0 for i in range(int(builtins.number_of_externals))], dtype=object) Vars.Read = { 'cL': Vars.cL, 'C': Vars.C, 'F': Vars.F, 'P': Vars.P, 'Transfer': Vars.Transfer, 'alpha': Vars.alpha, 'BudTransfer': Vars.BudTransfer, 'solar': Vars.solar, 'noise': Vars.noise, 'Rdown': Vars.Rdown, 'Rup': Vars.Rup, 'ExternalOutput': Vars.ExternalOutput, 'CO2Output': Vars.CO2Output, 'SolarOutput': Vars.SolarOutput, 'AODOutput': Vars.AODOutput }
def __repr__(self): return "%s(name='%s',lookup='%s')" % (qualname( self.__class__), self.name, self.lookup_type)
def __repr__(self): return "%s(name='%s',lookup='%s')" % (qualname(self.__class__), self.name, self.lookup_type)
def __call__(self, f): # If there are decorator arguments, __call__() is only called once, as # part of the decoration process! You can only give it a single # argument, which is the function object. # TODO: Check if there are no arguments in the wrapped method func_name = f.__name__ if not self.field_name: # TODO: Check if field already exists on model field_name = '_{}_cached'.format(func_name) else: field_name = self.field_name # In Python 3: f.__qualname__.split('.')[0] class_name = qualname(f).split('.')[0] class_path = '{}.{}'.format(f.__module__, class_name) register.add( class_path, f, self.field, field_name, self.dirty_func, self.invalidated_by ) # Also run on initialization of code def wrapped_f(*args, **kwargs): if 'use_dbcache' in kwargs: use_dbcache = kwargs.pop('use_dbcache') else: use_dbcache = True instance = args[0] # If `None` is an actual valid value, this causes the decorated # method to always call the original method. cached_value = getattr(instance, field_name, None) if not use_dbcache or cached_value is None: # Call original method. value = f(*args, **kwargs) logger.debug('{}.{} call returned: {}'.format( class_path, func_name, value )) if value != cached_value: # Update database field for next call and to store when saved. setattr(instance, field_name, value) logger.debug('{}.{} updated and returned dbcache field ("{}") value: {}'.format( class_path, func_name, field_name, value )) # TODO: Not sure if this is the right approach. Saving # when calling a method is not really nice design. # Update the database only if the instance already has a PK. if instance.pk: logger.debug('{}.{} updated dbcache field ("{}") in the database: {}'.format( class_path, func_name, field_name, value )) # WARNING: This causes a database update query when # calling a method that most likely does not imply # such behaviour (like: Model.get_FOO). # # Bypass triggers by using update instance.__class__.objects.filter(pk=instance.pk).update(**{field_name: value}) else: value = cached_value logger.debug('{}.{} returned dbcache field ("{}") value: {}'.format( class_path, func_name, field_name, value )) return value return wrapped_f
def recursive_repr( func, # type: Callable max_depth=1, # type: Optional[int] max_global_depth=2, # type: Optional[int] *args, # type: Any **kwargs # type: Any ): # type: (...) -> str """ Decorate a representation method/function and prevents infinite recursion. .. code:: python >>> from objetto.utils.recursive_repr import recursive_repr >>> class MyClass(object): ... ... @recursive_repr ... def __repr__(self): ... return "MyClass<" + repr(self) + ">" ... >>> my_obj = MyClass() >>> repr(my_obj) 'MyClass<...>' :param func: The '__repr__' and/or '__str__' method/function. :type func: function :param max_depth: Maximum recursion depth before returning fill value. :type max_depth: int :param max_global_depth: Maximum global depth before returning fill value. :type max_global_depth: int :return: Decorated method function. :rtype: function """ self = args[0] self_id = id(self) try: reprs = _local.reprs except AttributeError: reprs = _local.reprs = ValueCounter() try: global_reprs = _local.global_reprs except AttributeError: global_reprs = _local.global_reprs = [0] reprs[self_id] += 1 global_reprs[0] += 1 try: if max_depth is not None and reprs[self_id] > max_depth: return "..." elif max_global_depth is not None and global_reprs[ 0] > max_global_depth: try: qual_name = qualname(type(self)) except AttributeError: qual_name = type(self).__name__ return "<{} at {}>".format(qual_name, hex(id(self))) else: return func(*args, **kwargs) finally: reprs[self_id] -= 1 if not reprs[self_id]: del reprs[self_id] if not reprs: del _local.reprs global_reprs[0] -= 1 if not global_reprs[0]: del _local.global_reprs