Advanced descriptors for special cases.
Project description
Advanced descriptors
====================
.. image:: https://travis-ci.org/python-useful-helpers/advanced-descriptors.svg?branch=master
:target: https://travis-ci.org/python-useful-helpers/advanced-descriptors
.. image:: https://coveralls.io/repos/github/python-useful-helpers/advanced-descriptors/badge.svg?branch=master
:target: https://coveralls.io/github/python-useful-helpers/advanced-descriptors?branch=master
.. image:: https://readthedocs.org/projects/advanced-descriptors/badge/?version=latest
:target: http://advanced-descriptors.readthedocs.io/
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/v/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/pypi/pyversions/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/pypi/status/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/github/license/python-useful-helpers/advanced-descriptors.svg
:target: https://raw.githubusercontent.com/python-useful-helpers/advanced-descriptors/master/LICENSE
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black
This package includes helpers for special cases:
* `SeparateClassMethod` - allow to have classmethod and normal method both with the same name.
* `AdvancedProperty` - property with possibility to set class wide getter.
* `LogOnAccess` - property with logging on successful get/set/delete or failure.
SeparateClassMethod
-------------------
This descriptor can be set using standard decorator syntax.
Create instance with arguments:
.. code-block:: python
def imeth(instance):
return instance.value
def cmeth(owner):
return owner.value
class Target(object):
value = 1
def __init__(self):
self.value = 2
getval = advanced_descriptors.SeparateClassMethod(
imeth, cmeth
)
Create instance wrapping as decorator:
.. code-block:: python
class Target(object):
value = 1
def __init__(self):
self.value = 2
@advanced_descriptors.SeparateClassMethod
def getval(self):
return self.value
@getval.class_method
def getval(cls):
return cls.value
Cases with method only and classmethod only is useless:
method as-is and `@classmethod` should be used in corresponding cases.
.. note::
classmethod receives class as argument. IDE's don't know about custom descriptors and substitutes `self` by default.
AdvancedProperty
----------------
This descriptor should be used in cases, when in addition to normal property API, class getter is required.
If class-wide setter and deleter also required - you should use standard propery in metaclass.
Usage examples:
1. In addition to normal property API:
.. code-block:: python
class Target(object):
_value = 777
def __init__(self):
self._value = 42
@advanced_descriptors.AdvancedProperty
def val(self):
return self._value
@val.setter
def val(self, value):
self._value = value
@val.deleter
def val(self):
self._value = 0
@val.cgetter
def val(cls):
return cls._value
2. Use class-wide getter for instance too:
.. code-block:: python
class Target(object):
_value = 1
val = advanced_descriptors.AdvancedProperty()
@val.cgetter
def val(cls):
return cls._value
.. note::
class-wide getter receives class as argument. IDE's don't know about custom descriptors and substitutes `self` by default.
LogOnAccess
-----------
This special case of property is useful in cases, where a lot of properties should be logged by similar way without writing a lot of code.
Basic API is conform with `property`, but in addition it is possible to customize logger, log levels and log conditions.
Usage examples:
1. Simple usage. All by default, logger is re-used from instance if available with names `logger` or `log` else used internal `advanced_descriptors.log_on_access` logger:
.. code-block:: python
import logging
class Target(object):
def init(self, val='ok')
self.val = val
self.logger = logging.get_logger(self.__class__.__name__) # Single for class, follow subclassing
def __repr__(self):
return "{cls}(val={self.val})".format(cls=self.__class__.__name__, self=self)
@advanced_descriptors.LogOnAccess
def ok(self):
return self.val
@ok.setter
def ok(self, val):
self.val = val
@ok.deleter
def ok(self):
self.val = ""
2. Use with global logger for class:
.. code-block:: python
class Target(object):
def init(self, val='ok')
self.val = val
def __repr__(self):
return "{cls}(val={self.val})".format(cls=self.__class__.__name__, self=self)
@advanced_descriptors.LogOnAccess
def ok(self):
return self.val
@ok.setter
def ok(self, val):
self.val = val
@ok.deleter
def ok(self):
self.val = ""
ok.logger = 'test_logger'
ok.log_level = logging.INFO
ok.exc_level = logging.ERROR
ok.log_object_repr = True # As by default
ok.log_success = True # As by default
ok.log_failure = True # As by default
ok.log_traceback = True # As by default
ok.override_name = None # As by default: use original name
Testing
=======
The main test mechanism for the package `advanced-descriptors` is using `tox`.
Available environments can be collected via `tox -l`
CI systems
==========
For code checking several CI systems is used in parallel:
1. `Travis CI: <https://travis-ci.org/python-useful-helpers/advanced-descriptors>`_ is used for checking: PEP8, pylint, bandit, installation possibility and unit tests. Also it's publishes coverage on coveralls.
2. `coveralls: <https://coveralls.io/github/python-useful-helpers/advanced-descriptors>`_ is used for coverage display.
CD system
=========
`Travis CI: <https://travis-ci.org/python-useful-helpers/advanced-descriptors>`_ is used for package delivery on PyPI.
====================
.. image:: https://travis-ci.org/python-useful-helpers/advanced-descriptors.svg?branch=master
:target: https://travis-ci.org/python-useful-helpers/advanced-descriptors
.. image:: https://coveralls.io/repos/github/python-useful-helpers/advanced-descriptors/badge.svg?branch=master
:target: https://coveralls.io/github/python-useful-helpers/advanced-descriptors?branch=master
.. image:: https://readthedocs.org/projects/advanced-descriptors/badge/?version=latest
:target: http://advanced-descriptors.readthedocs.io/
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/v/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/pypi/pyversions/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/pypi/status/advanced-descriptors.svg
:target: https://pypi.python.org/pypi/advanced-descriptors
.. image:: https://img.shields.io/github/license/python-useful-helpers/advanced-descriptors.svg
:target: https://raw.githubusercontent.com/python-useful-helpers/advanced-descriptors/master/LICENSE
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black
This package includes helpers for special cases:
* `SeparateClassMethod` - allow to have classmethod and normal method both with the same name.
* `AdvancedProperty` - property with possibility to set class wide getter.
* `LogOnAccess` - property with logging on successful get/set/delete or failure.
SeparateClassMethod
-------------------
This descriptor can be set using standard decorator syntax.
Create instance with arguments:
.. code-block:: python
def imeth(instance):
return instance.value
def cmeth(owner):
return owner.value
class Target(object):
value = 1
def __init__(self):
self.value = 2
getval = advanced_descriptors.SeparateClassMethod(
imeth, cmeth
)
Create instance wrapping as decorator:
.. code-block:: python
class Target(object):
value = 1
def __init__(self):
self.value = 2
@advanced_descriptors.SeparateClassMethod
def getval(self):
return self.value
@getval.class_method
def getval(cls):
return cls.value
Cases with method only and classmethod only is useless:
method as-is and `@classmethod` should be used in corresponding cases.
.. note::
classmethod receives class as argument. IDE's don't know about custom descriptors and substitutes `self` by default.
AdvancedProperty
----------------
This descriptor should be used in cases, when in addition to normal property API, class getter is required.
If class-wide setter and deleter also required - you should use standard propery in metaclass.
Usage examples:
1. In addition to normal property API:
.. code-block:: python
class Target(object):
_value = 777
def __init__(self):
self._value = 42
@advanced_descriptors.AdvancedProperty
def val(self):
return self._value
@val.setter
def val(self, value):
self._value = value
@val.deleter
def val(self):
self._value = 0
@val.cgetter
def val(cls):
return cls._value
2. Use class-wide getter for instance too:
.. code-block:: python
class Target(object):
_value = 1
val = advanced_descriptors.AdvancedProperty()
@val.cgetter
def val(cls):
return cls._value
.. note::
class-wide getter receives class as argument. IDE's don't know about custom descriptors and substitutes `self` by default.
LogOnAccess
-----------
This special case of property is useful in cases, where a lot of properties should be logged by similar way without writing a lot of code.
Basic API is conform with `property`, but in addition it is possible to customize logger, log levels and log conditions.
Usage examples:
1. Simple usage. All by default, logger is re-used from instance if available with names `logger` or `log` else used internal `advanced_descriptors.log_on_access` logger:
.. code-block:: python
import logging
class Target(object):
def init(self, val='ok')
self.val = val
self.logger = logging.get_logger(self.__class__.__name__) # Single for class, follow subclassing
def __repr__(self):
return "{cls}(val={self.val})".format(cls=self.__class__.__name__, self=self)
@advanced_descriptors.LogOnAccess
def ok(self):
return self.val
@ok.setter
def ok(self, val):
self.val = val
@ok.deleter
def ok(self):
self.val = ""
2. Use with global logger for class:
.. code-block:: python
class Target(object):
def init(self, val='ok')
self.val = val
def __repr__(self):
return "{cls}(val={self.val})".format(cls=self.__class__.__name__, self=self)
@advanced_descriptors.LogOnAccess
def ok(self):
return self.val
@ok.setter
def ok(self, val):
self.val = val
@ok.deleter
def ok(self):
self.val = ""
ok.logger = 'test_logger'
ok.log_level = logging.INFO
ok.exc_level = logging.ERROR
ok.log_object_repr = True # As by default
ok.log_success = True # As by default
ok.log_failure = True # As by default
ok.log_traceback = True # As by default
ok.override_name = None # As by default: use original name
Testing
=======
The main test mechanism for the package `advanced-descriptors` is using `tox`.
Available environments can be collected via `tox -l`
CI systems
==========
For code checking several CI systems is used in parallel:
1. `Travis CI: <https://travis-ci.org/python-useful-helpers/advanced-descriptors>`_ is used for checking: PEP8, pylint, bandit, installation possibility and unit tests. Also it's publishes coverage on coveralls.
2. `coveralls: <https://coveralls.io/github/python-useful-helpers/advanced-descriptors>`_ is used for coverage display.
CD system
=========
`Travis CI: <https://travis-ci.org/python-useful-helpers/advanced-descriptors>`_ is used for package delivery on PyPI.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Advanced-Descriptors-2.2.0.tar.gz
(16.5 kB
view hashes)
Built Distributions
Close
Hashes for Advanced-Descriptors-2.2.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | af7c44323957885e6e9e08b7d50505d03a1468a03ea439940c15817122fb0a43 |
|
MD5 | 4e082edb5ab4449204b4c2a181ea32d8 |
|
BLAKE2b-256 | f2ec5c762b9e414981ba248a08250a7d321e5347a8bb74e8d84e237b719f70b3 |
Close
Hashes for Advanced_Descriptors-2.2.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 67539f14d2a123fbe0fb5da33556d1781b43b9372232f4653fbcf646befa6916 |
|
MD5 | f171f267b47d0b1f7f5ae4ba65da4bc8 |
|
BLAKE2b-256 | 9b43b33d1c553e39cf04ce5e8e9b55d6ebeaf92848f986dc2bde5b5a545e5ae2 |
Close
Hashes for Advanced_Descriptors-2.2.0-cp37-cp37m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8d21e63b4bfb5a5a021f66001d3ebf389279853c96f120852486e2adc2414843 |
|
MD5 | 3bd9fa07911ede897f977a7ee7b3c9fe |
|
BLAKE2b-256 | d99733100e1de7de635b261b89733fe31f33c1bdfcedb6d2da4d980d84cd502b |
Close
Hashes for Advanced_Descriptors-2.2.0-cp37-cp37m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 81511295bfc97869ce02b4ee4c7cf5a4ccedd3805b1da80187aba3d19d5c38fd |
|
MD5 | bbf90e563b41bf345925187feae76d0e |
|
BLAKE2b-256 | 1195eb290bf25d3a8084790888982b83ef9c40963940bcad13aa636b75e7e8d6 |
Close
Hashes for Advanced_Descriptors-2.2.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 58d8d0903b639393699f6d4f87e29b01dd31e4a034bf5935030645f2b8efcfe9 |
|
MD5 | 37dc5585f8c2a15c9f559aecaf6fa383 |
|
BLAKE2b-256 | 6ad1e57f4f6408cafbd622e3569779897cfbcb5df93cfb4eba3d6c524bf1a080 |
Close
Hashes for Advanced_Descriptors-2.2.0-cp36-cp36m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1bd9f182c05865ab3165b2ef42c1a33d4d074f2b80726cce13b99cd2b8e191e0 |
|
MD5 | 2528ee18bd5146ed1ffc5462589e8c75 |
|
BLAKE2b-256 | 548b70ef096bf909847d1c7e6a7e26d5309645e7102e0c19802485db0e521e4a |
Close
Hashes for Advanced_Descriptors-2.2.0-cp35-cp35m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 392f5a7c2bb674690b05eb04056515ce95be3dd9a216bee385173c8e6b7b2fc7 |
|
MD5 | ecb4b31258703f46ea6b503642e973a0 |
|
BLAKE2b-256 | 7f0d23e79d47c139e6793aa73d6d732cafceff78880ea87727eea6d625d75555 |
Close
Hashes for Advanced_Descriptors-2.2.0-cp35-cp35m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 29fea504f86729a8978c554ba59dec55d0bec708244357140e060bb536c26b12 |
|
MD5 | c4168c9208ce46831e7730a721635209 |
|
BLAKE2b-256 | 1795f79c34bf388e10e487fe1258d7138261d0993754f8cdc3c0e3ff4b43281c |
Close
Hashes for Advanced_Descriptors-2.2.0-cp34-cp34m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b07739995fad9ababc4689830a79dce204be7ac8931b168323d815b1ba18fc85 |
|
MD5 | 5a01e127f28332a1a5d84b341bec5ac9 |
|
BLAKE2b-256 | 160cec77174ddcd493e659575a018a289d90675171dfc8a09245cba91ee2e1ca |
Close
Hashes for Advanced_Descriptors-2.2.0-cp34-cp34m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 49ea925155a1279b9eea5903ed6209ca71ddb738562b92639fb41ad533593b81 |
|
MD5 | b3572e9ab508ccf0c1e41462f90685f7 |
|
BLAKE2b-256 | 1f92195b9a364b6955110b11417ec1b0b94083e89f853cbb0a799bb19a70da73 |