...
 
Commits (3)
......@@ -37,7 +37,7 @@ For example::
'bar': 'I am bar'}
The :func:`func` can be a function or an awaitable. These 2 examples works the same::
The `func()` can be a function or an awaitable. These 2 examples works the same::
@annotate('foo', 'bar')
......@@ -172,5 +172,17 @@ Closing callback can be registered::
assert foo.closed == True
Partial::
@annotate('foo', 'bar')
def fun(foo, bar):
return {'foo': foo,
'bar': bar}
partial = services.partial(fun)
assert (yield from partial()) == {'foo': 'I am foo',
'bar': 'I am bar'}
.. _asyncio: https://pypi.python.org/pypi/asyncio
.. _jeni: https://pypi.python.org/pypi/jeni
......@@ -7,6 +7,7 @@ from abc import ABCMeta
from collections import ChainMap
from contextlib import contextmanager
from contextvars import ContextVar
from functools import wraps
from inspect import signature, unwrap
from itertools import chain
from types import MappingProxyType
......@@ -168,8 +169,8 @@ class Injector(metaclass=ABCMeta):
def apply(self, *args, **kwargs) -> asyncio.Future:
with self.auto():
func, *args = args # type: ignore
func = unwrap(func)
anno = ANNOTATIONS.get(func)
orig = unwrap(func)
anno = ANNOTATIONS.get(orig)
if anno:
return self.do_apply(func, anno, args, kwargs)
fut: asyncio.Future = asyncio.Future()
......@@ -196,6 +197,18 @@ class Injector(metaclass=ABCMeta):
return asyncio.create_task(run(args, kwargs))
def partial(self, func):
orig = unwrap(func)
anno = ANNOTATIONS.get(orig)
if anno:
@wraps(func)
def parted(*args, **kwargs):
return self.do_apply(func, anno, args, kwargs)
return parted
return func
@contextmanager
def auto(self):
token = current_injector_var.set(self)
......
......@@ -6,6 +6,7 @@ tag_prefix = v
[metadata]
description-file = README.rst
license_file = LICENSE
[flake8]
exclude = _version.py
......
#!/usr/bin/env python
from setuptools import setup, find_packages
import pathlib
import versioneer
here = pathlib.Path(__file__).parent
def read(f):
return (here / f).read_text("utf-8").strip()
setup(
name='knighted',
name="knighted",
version=versioneer.get_version(),
author='Xavier Barbosa',
author_email='clint.northwood@gmail.com',
description='inject dependencies',
author="Xavier Barbosa",
author_email="clint.northwood@gmail.com",
description="inject dependencies",
long_description=read("README.rst"),
packages=find_packages(),
install_requires=[
"cached_property"
],
extras_require={
},
install_requires=["cached_property"],
extras_require={},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
......@@ -22,10 +28,10 @@ setup(
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules"
"Topic :: Software Development :: Libraries :: Python Modules",
],
keywords=['dependency injection', 'composing'],
url='http://lab.errorist.xyz/abc/knighted',
license='MIT',
cmdclass=versioneer.get_cmdclass()
keywords=["dependency injection", "composing"],
url="http://lab.errorist.xyz/abc/knighted",
license="MIT",
cmdclass=versioneer.get_cmdclass(),
)
......@@ -167,3 +167,26 @@ async def test_descriptor_2_not_decorated(services):
toto = Toto()
with pytest.raises(LookupError):
toto.cache
@pytest.mark.asyncio
async def test_partial_sync_async(services):
@services.factory("foo")
def foo_factory():
return "I am foo"
@annotate("foo")
async def fun(foo):
return {"foo": foo}
partial = services.partial(fun)
assert await partial() == {"foo": "I am foo"}
@pytest.mark.asyncio
async def test_partial_outsider(services):
async def fun():
return {"foo": "bar"}
partial = services.partial(fun)
assert await partial() == {"foo": "bar"}