aspect oriented programming helper
Project description
# Concerns
[Python](https://www.python.org/) implementation of the
[Ruby](https://www.ruby-lang.org/)’s
[ActiveSupport::Concern](https://api.rubyonrails.org/v5.1/classes/ActiveSupport/Concern.html)
behavior.
## Use examples
Note: the class context is the fourth argument of the
[metaclass](https://www.python.org/doc/essays/metaclasses/) `__init__` method,
formally “namespace”:
```python
def __init__(cls, name: str, bases: tuple, namespace: dict) -> None:
...
```
It is a dictionary representation of the class body.
### Using a class as mix-in
If the aspect is a class, its context will be merged to the target context on
its factoring.
```python
from typing import NamedTuple
from concerns import concern
class SerialMixin:
def serialize(self) -> str:
return json.dumps(self._asdict(), sort_keys=True)
@classmethod
def deserialize(cls, data: str):
return cls(**json.loads(data))
class PersonBase(NamedTuple):
name: str
surname: str
class Person(PersonBase):
concern(SerialMixin)
```
### Using a mapping as default values map
If the aspect is a mapping (a dictionary, by example), it itself will be merged
to the target context on its factoring.
```python
from concerns import concern
class Animal:
# Too simple use, avoid doing it
concern({voice='grrr'})
def __init__(self, *, voice: str = None):
if voice:
self.voice = voice
def say(self) -> None:
print(self.voice)
```
### Function to change behavior
If the aspect is a callable, the target class context will be passed as
parameter to the aspect for processing before its factoring.
```python
from concerns import concern
from collections.abc import MutableMapping
from datetime import datetime
def make_timed(context: MutableMapping) -> None:
"""
Reusable aspect function to add creating time to objects
"""
def set_created_attr(attr: str) -> None:
context[attr] = None
def new(cls, name: str, bases: tuple, _dict: dict):
self = super().__new__(cls, name, bases, _dict)
setattr(self, attr) = datetime.now()
return self
context['__new__'] = new
context['set_created_attr'] = set_created_attr
class Register:
concern(make_timed)
... # more class attributes
set_created_attr('created_at')
```
[Python](https://www.python.org/) implementation of the
[Ruby](https://www.ruby-lang.org/)’s
[ActiveSupport::Concern](https://api.rubyonrails.org/v5.1/classes/ActiveSupport/Concern.html)
behavior.
## Use examples
Note: the class context is the fourth argument of the
[metaclass](https://www.python.org/doc/essays/metaclasses/) `__init__` method,
formally “namespace”:
```python
def __init__(cls, name: str, bases: tuple, namespace: dict) -> None:
...
```
It is a dictionary representation of the class body.
### Using a class as mix-in
If the aspect is a class, its context will be merged to the target context on
its factoring.
```python
from typing import NamedTuple
from concerns import concern
class SerialMixin:
def serialize(self) -> str:
return json.dumps(self._asdict(), sort_keys=True)
@classmethod
def deserialize(cls, data: str):
return cls(**json.loads(data))
class PersonBase(NamedTuple):
name: str
surname: str
class Person(PersonBase):
concern(SerialMixin)
```
### Using a mapping as default values map
If the aspect is a mapping (a dictionary, by example), it itself will be merged
to the target context on its factoring.
```python
from concerns import concern
class Animal:
# Too simple use, avoid doing it
concern({voice='grrr'})
def __init__(self, *, voice: str = None):
if voice:
self.voice = voice
def say(self) -> None:
print(self.voice)
```
### Function to change behavior
If the aspect is a callable, the target class context will be passed as
parameter to the aspect for processing before its factoring.
```python
from concerns import concern
from collections.abc import MutableMapping
from datetime import datetime
def make_timed(context: MutableMapping) -> None:
"""
Reusable aspect function to add creating time to objects
"""
def set_created_attr(attr: str) -> None:
context[attr] = None
def new(cls, name: str, bases: tuple, _dict: dict):
self = super().__new__(cls, name, bases, _dict)
setattr(self, attr) = datetime.now()
return self
context['__new__'] = new
context['set_created_attr'] = set_created_attr
class Register:
concern(make_timed)
... # more class attributes
set_created_attr('created_at')
```
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 Distributions
No source distribution files available for this release.See tutorial on generating distribution archives.
Built Distribution
File details
Details for the file concerns-1.0-py3-none-any.whl
.
File metadata
- Download URL: concerns-1.0-py3-none-any.whl
- Upload date:
- Size: 2.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/40.0.0 requests-toolbelt/0.8.0 tqdm/4.24.0 CPython/3.6.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 11c8621e42adb2f263a7bfb8c6151c4478df7c78246406936e618d486a350df0 |
|
MD5 | 3817540cc0596fa4b2d8508c592de043 |
|
BLAKE2b-256 | 91b5968af51879e395fb61703ceaaed932f45c881c88355fcddacf69849b55de |