Skip to content

Commit d6d90e2

Browse files
committed
Version 0.1
1 parent 34ea830 commit d6d90e2

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

README.rst

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,60 @@
22
deps
33
****
44

5-
Python >=3.6 dependency injection based on attrs
5+
Python >=3.6 dependency injection based on attrs. Very simple, yet powerful.
66

77
Inspired by `inject-attrs <https://github.com/dradetsky/inject-attrs/>`_.
88

99

10+
Usage
11+
-----
12+
``deps`` **works only with typing annotations defined as presented below!**
13+
14+
1. First, replace your ``@attr.s(...)`` decorators:
15+
.. code-block:: python
16+
17+
@attr.s(auto_attribs=True, <other args/kwargs...>)
18+
class Thing:
19+
cfg: Config
20+
some_dep: SomeClass
21+
22+
With:
23+
.. code-block:: python
24+
25+
import deps
26+
27+
@deps.s(<other args/kwargs...>)
28+
class Thing:
29+
cfg: IConfig
30+
some_dep: ISomeClass
31+
32+
Notice that ``auto_attribs=True`` is no more needed, it will be forced by this package.
33+
34+
2. Next you have to prepare - somewhere in your codebase - an abstract interfaces classes for your attributes:
35+
.. code-block:: python
36+
37+
import deps
38+
39+
class IConfig(deps.Interface)
40+
# ...
41+
42+
class ISomeClass(deps.Interface)
43+
# ...
44+
45+
3. Now prepare interfaces implementations:
46+
.. code-block:: python
47+
48+
from interfaces import IConfig, ISomeClass
49+
50+
class Config(IConfig)
51+
# ...
52+
53+
class SomeClass(ISomeClass)
54+
# ...
55+
56+
4. Finally, configure dependency injection bindings provided by `Inject <https://pypi.org/project/Inject/>`_ package, using ``bind_to_constructor`` directive.
57+
58+
1059
License
1160
-------
1261
MIT

deps.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from typing import get_type_hints
2+
3+
from attr import attrs as original_attrs, Factory
4+
import inject
5+
6+
__all__ = ('attributes', 'attrs', 's', 'Interface')
7+
__version__ = '0.1'
8+
9+
10+
class Interface:
11+
pass
12+
13+
14+
def attrs(*args, **kwargs):
15+
def wrap(cls):
16+
hints = get_type_hints(cls)
17+
18+
for property_name, property_type in hints.items():
19+
if isinstance(property_type, type) and issubclass(property_type, Interface):
20+
setattr(cls, property_name, Factory(lambda: inject.instance(property_type)))
21+
22+
kwargs['auto_attribs'] = True
23+
return original_attrs(*args, **kwargs)(cls)
24+
25+
return wrap
26+
27+
28+
s = attributes = attrs

setup.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import ast
2+
import os
3+
import re
4+
from setuptools import setup
5+
6+
current_dir = os.path.abspath(os.path.dirname(__file__))
7+
_version_re = re.compile(r'__version__\s+=\s+(?P<version>.*)')
8+
9+
with open(os.path.join(current_dir, 'deps.py'), 'r') as f:
10+
version = _version_re.search(f.read()).group('version')
11+
version = str(ast.literal_eval(version))
12+
13+
14+
setup(
15+
name='deps',
16+
license='MIT',
17+
version=version,
18+
description='Dependency injection based on attrs',
19+
long_description=open('README.rst').read(),
20+
author='Daniel Kuruc',
21+
author_email='[email protected]',
22+
url='https://github.com/danie1k/deps',
23+
py_modules=[
24+
'deps',
25+
],
26+
zip_safe=False,
27+
python_requires='>=3.6',
28+
tests_require=['pytest'],
29+
install_requires=[
30+
'attrs < 19.4',
31+
'Inject < 3.6',
32+
],
33+
classifiers=[
34+
"Development Status :: 4 - Beta",
35+
"Intended Audience :: Developers",
36+
"License :: OSI Approved :: MIT License",
37+
"Operating System :: OS Independent",
38+
"Programming Language :: Python :: 3.6",
39+
"Programming Language :: Python :: 3.7",
40+
"Programming Language :: Python :: 3.8",
41+
"Programming Language :: Python :: 3 :: Only",
42+
"Topic :: Software Development :: Libraries :: Python Modules",
43+
],
44+
)

0 commit comments

Comments
 (0)