Coverage for pygeodesy/props.py : 99%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*-
deprecation decorators.
To enable C{DeprecationWarning}s from C{PyGeodesy}, set env var C{PYGEODESY_WARNINGS} to a non-empty string I{AND} run C{python} with command line option C{-X dev} or with one of the C{-W} choices, see function L{DeprecationWarnings} below. '''
_xkwds, _xkwds_get _DEPRECATED_, _DNL_, _DOT_, _EQUALSPACED_, \ _immutable_, _invalid_, _N_A_, _not_, \ _SPACE_, _UNDER_ # from pygeodesy.named import callname # from _MODS, avoid circular _FOR_DOCS, _PYTHON_X_DEV, _sys # from pygeodesy.streprs import Fmt # from _MODS
and _getenv('PYGEODESY_WARNINGS', NN)
'''(INTERNAL) Yield all C{R/property/_RO}s at C{Clas_or_inst} as specified in the C{Bases} arguments. ''' else: # class and super-classes of inst except AttributeError: raise S = () # not an inst
'''(INTERNAL) Assert the number of C{R/property/_RO}s at C{Clas_or_inst}. ''' raise _AssertionError(_COMMASPACE_.join(t), Clas_or_inst, txt=_COMMASPACE_(len(t), _not_(n)))
'''(INTERNAL) Check whether C{inst} has a C{P/property/_RO} by this C{name}. ''' and p.name == name)
'''(INTERNAL) Zap all I{cached} L{property_RO}s, L{Property}s, L{Property_RO}s and the named C{attrs} of an instance.
@return: The number of updates (C{int}), if any. ''' raise _AssertionError(inst, txt=_not_an_inst_) except AttributeError: return 0
# def _update_all_from(inst, other, **Base): # '''(INTERNAL) Update all I{cached} L{Property}s and # L{Property_RO}s of instance C{inst} from C{other}. # # @return: The number of updates (C{int}), if any. # ''' # if isclass(inst): # raise _AssertionError(inst, txt=_not_an_inst_) # try: # d = inst.__dict__ # f = other.__dict__ # except AttributeError: # return 0 # u = len(f) # if u: # u = len(d) # B = _xkwds_get(Base, Base=_PropertyBase) # for p in _allPropertiesOf(inst, B): # p._update_from(inst, other) # u -= len(d) # return u # updates
'''(INTERNAL) Zap all named C{attrs} of an instance.
@return: The number of updates (C{int}), if any. ''' except AttributeError: return 0 for a in attrs: # PYCHOK no cover if _p(a, MISSING) is MISSING and not hasattr(inst, a): n = _MODS.named.classname(inst, prefixed=True) a = _DOT_(n, _SPACE_(a, _invalid_)) raise _AssertionError(a, txt=repr(inst))
'''(INTERNAL) Base class for C{P/property/_RO}. '''
self.getter(method) # PYCHOK no cover
self.__doc__ = d # PYCHOK no cover
'''Zap the I{cached/memoized} C{property} value. ''' self._update(inst, None) # PYCHOK no cover
'''Get and I{cache/memoize} the C{property} value. ''' except KeyError: # cache the value in the instance' __dict__ inst.__dict__[self.name] = val = self.method(inst) return val
'''Throws an C{AttributeError}, always. ''' raise self._Error(_immutable_, n, None)
'''(INTERNAL) Zap the I{cached/memoized} C{inst.__dict__[name]} item. '''
'''(INTERNAL) Copy a I{cached/memoized} C{inst.__dict__[name]} item from C{other.__dict__[name]} if present, otherwise zap it. ''' else:
'''Throws an C{AttributeError}, always. ''' raise self._Error(_invalid_, self.deleter, fdel)
'''Throws an C{AttributeError}, always. ''' raise self._Error(_invalid_, self.getter, fget)
'''Throws an C{AttributeError}, always. ''' raise self._Error(_immutable_, self.setter, fset)
'''(INTERNAL) Return an C{AttributeError} instance. ''' else:
# No __doc__ on purpose '''New I{immutable}, I{caching}, I{memoizing} C{property} I{Factory} to be used as C{decorator}.
@arg method: The callable being decorated as this C{property}'s C{getter}, to be invoked only once. @kwarg doc: Optional property documentation (C{str}).
@note: Like standard Python C{property} without a C{setter}, but with a more descriptive error message when set.
@see: Python 3's U{functools.cached_property<https://docs.Python.org/3/ library/functools.html#functools.cached_property>} and U{-.cache <https://Docs.Python.org/3/library/functools.html#functools.cache>} to I{cache} or I{memoize} the property value.
@see: Luciano Ramalho, "Fluent Python", page 636, O'Reilly, 2016, "Coding a Property Factory", especially Example 19-24 and U{class Property<https://docs.Python.org/3/howto/descriptor.html>}. '''
except (AttributeError, KeyError): return self._fget(inst)
# No __doc__ on purpose '''New I{mutable}, I{caching}, I{memoizing} C{property} I{Factory} to be used as C{decorator}.
@see: L{Property_RO} for more details.
@note: Unless and until the C{setter} is defined, this L{Property} behaves like an I{immutable}, I{caching}, I{memoizing} L{Property_RO}. '''
'''Make this C{Property} I{mutable}.
@arg method: The callable being decorated as this C{Property}'s C{setter}.
@note: Setting a new property value always clears the previously I{cached} or I{memoized} value I{after} invoking the B{C{method}}. ''' _PropertyBase.setter(self, method) # PYCHOK no cover
if _FOR_DOCS: # XXX force method.__doc__ into epydoc _PropertyBase.__init__(self, self.method, self.method, method) else:
'''Set and I{cache}, I{memoize} the C{property} value. '''
# class Property <https://docs.Python.org/3/howto/descriptor.html>
# No __doc__ on purpose
'''New I{immutable}, standard C{property} to be used as C{decorator}.
@arg method: The callable being decorated as C{property}'s C{getter}. @kwarg doc: Optional property documentation (C{str}).
@note: Like standard Python C{property} without a setter, but with a more descriptive error message when set.
@see: L{Property_RO}. '''
'''(INTERNAL) Zap the I{cached} C{B{inst}.__dict__[_name]} item. ''' d = Clas[0].__dict__.get(uname, MISSING) else: # if d is MISSING: # XXX superfluous # for c in inst.__class__.__mro__[:-1]: # if uname in c.__dict__: # d = c.__dict__[uname] # break
'''Class C{property} with retrievable name. ''' '''Get the name of this C{property} (C{str}). '''
'''Decorator for a standard C{property} with basic documentation.
@arg doc: The property documentation (C{str}).
@example:
>>> @property_doc_("documentation text.") >>> def name(self): >>> ... >>> >>> @name.setter >>> def name(self, value): >>> ... ''' # See Luciano Ramalho, "Fluent Python", page 212ff, O'Reilly, 2016, # "Parameterized Decorators", especially Example 7-23. Also, see # <https://Python-3-Patterns-Idioms-Test.ReadTheDocs.io/en/latest/PythonDecorators.html>
'''(INTERNAL) Return the documented C{property}. '''
'''(INTERNAL) Decorator for DEPRECATED functions, methods, etc.
@see: Brett Slatkin, "Effective Python", page 105, 2nd ed, Addison-Wesley, 2019. '''
else: # PYCHOK no cover q = call.__name__
'''Use inside __new__ or __init__ of a DEPRECATED class.
@arg cls_or_class: The class (C{cls} or C{Class}).
@note: NOT a decorator! '''
'''Decorator for a DEPRECATED function.
@arg call: The deprecated function (C{callable}).
@return: The B{C{call}} DEPRECATED. ''' call.__module__, call.__name__)) if \ _W_DEV else call
'''Decorator for a DEPRECATED method.
@arg call: The deprecated method (C{callable}).
@return: The B{C{call}} DEPRECATED. '''
def _deprecated_module(name): # PYCHOK no cover '''(INTERNAL) Callable within a DEPRECATED module. ''' if _W_DEV: _throwarning('module', name, _dont_use_)
'''Decorator for a DEPRECATED C{property} or C{Property}. ''' '''Decorator for a DEPRECATED C{property} or C{Property} getter. '''
def _fget(inst): # PYCHOK no cover '''Get the C{property} or C{Property} value. ''' q = _qualified(inst, self.name) _throwarning(property.__name__, q, doc) return self.method(inst) # == method
'''Decorator for a DEPRECATED C{property} or C{Property} setter.
@arg method: The callable being decorated as this C{Property}'s C{setter}.
@note: Setting a new property value always clears the previously I{cached} or I{memoized} value I{after} invoking the B{C{method}}. ''' _PropertyBase.setter(self, method) # PYCHOK no cover
if _FOR_DOCS: # XXX force method.__doc__ into epydoc _PropertyBase.__init__(self, self.method, self.method, method) else:
'''Set the C{property} or C{Property} value. ''' # self._update(inst) # un-cache this item
# class Property <https://docs.Python.org/3/howto/descriptor.html>
else: # PYCHOK no cover class deprecated_property(property): # PYCHOK expected '''Decorator for a DEPRECATED C{property} or C{Property}. ''' pass
'''Decorator for a DEPRECATED L{Property_RO}.
@arg method: The C{Property_RO.fget} method (C{callable}).
@return: The B{C{method}} DEPRECATED. '''
'''Decorator for a DEPRECATED L{property_RO}.
@arg method: The C{property_RO.fget} method (C{callable}).
@return: The B{C{method}} DEPRECATED. '''
'''(INTERNAL) Create a DEPRECATED C{property_RO} or C{Property_RO}. '''
def _fget(self, inst): # PYCHOK no cover q = _qualified(inst, self.name) _throwarning(_RO.__name__, q, doc) return self.method(inst)
else: # PYCHOK no cover return _RO(method, doc=doc)
'''Have any C{DeprecationWarning}s been reported or raised?
@return: The number of C{DeprecationWarning}s (C{int}) so far or C{None} if not enabled.
@note: To get C{DeprecationWarning}s if any, run C{python} with env var C{PYGEODESY_WARNINGS} set to a non-empty string I{AND} use C{python[3]} command line option C{-X dev}, C{-W always} or C{-W error}, etc. '''
'''(INTERNAL) Get uniform DEPRECATED __doc__ string. ''' except AttributeError: i = -1
'''(INTERNAL) Fully qualify a name. ''' # _DOT_(inst.classname, name), not _DOT_(inst.named4, name)
'''(INTERNAL) Report or raise a C{DeprecationWarning}. '''
# XXX invoke warn or raise DeprecationWarning(text)
global _Warnings
# **) MIT License # # Copyright (C) 2016-2022 -- mrJean1 at Gmail -- All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. |