Skip to content

Commit f0a6426

Browse files
author
Andrew William Borba
committed
Merge type-hints (in .pyi stub) into implementation
Test Plan: - Ran all unit tests for inject library in Python 2.7/3.6 -> pass - Only ran autoparams test on 3.6 since that requires Python 3 type-hints. - Ran all unit tests in my own project which uses these new changes -> pass
1 parent 785d90b commit f0a6426

File tree

4 files changed

+29
-98
lines changed

4 files changed

+29
-98
lines changed

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ matrix:
33
include:
44
- python: '2.7'
55
env: EXTRA_ARGS='-I test_autoparams.py'
6-
- python: '3.3'
7-
env: EXTRA_ARGS='-I test_autoparams.py'
86
- python: '3.4'
97
env: EXTRA_ARGS='-I test_autoparams.py'
108
- python: '3.5'

setup.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
from distutils.core import setup
2+
from setuptools import setup
33

44

55
def read_description():
@@ -9,7 +9,7 @@ def read_description():
99

1010
setup(
1111
name='Inject',
12-
version='3.5.1-dev',
12+
version='3.5.1.dev0',
1313
url='https://github.com/ivankorobkov/python-inject',
1414
license='Apache License 2.0',
1515

@@ -25,22 +25,19 @@ def read_description():
2525
data_files=[
2626
(
2727
'lib/python{}.{}/site-packages'.format(*sys.version_info[:2]),
28-
['src/inject.pyi']
29-
),
30-
(
31-
'shared/typehints/python{}.{}'.format(*sys.version_info[:2]),
32-
['src/inject.pyi']
28+
['src/inject.py']
3329
)
3430
],
3531

32+
install_requires=['typing'],
33+
3634
classifiers=[
3735
'Development Status :: 5 - Production/Stable',
3836
'Intended Audience :: Developers',
3937
'License :: OSI Approved :: Apache Software License',
4038
'Operating System :: OS Independent',
4139
'Programming Language :: Python',
4240
'Programming Language :: Python :: 2.7',
43-
'Programming Language :: Python :: 3.3',
4441
'Programming Language :: Python :: 3.4',
4542
'Programming Language :: Python :: 3.5',
4643
'Programming Language :: Python :: 3.6',

src/inject.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,22 @@ def my_config(binder):
8383
import logging
8484
import sys
8585
import threading
86-
86+
from typing import Optional, Type, Hashable, Callable, TypeVar, Union
8787

8888
logger = logging.getLogger('inject')
8989

9090
_INJECTOR = None # Shared injector instance.
9191
_INJECTOR_LOCK = threading.RLock() # Guards injector initialization.
9292
_BINDING_LOCK = threading.RLock() # Guards runtime bindings.
9393

94+
T = TypeVar('T')
95+
Binding = Union[Type[T], Hashable]
96+
Constructor = Provider = Callable[[], T]
97+
BinderCallable = Callable[['Binder'], None]
98+
9499

95100
def configure(config=None, bind_in_runtime=True):
101+
# type: (Optional[BinderCallable], bool) -> Injector
96102
"""Create an injector with a callable config or raise an exception when already configured."""
97103
global _INJECTOR
98104

@@ -106,6 +112,7 @@ def configure(config=None, bind_in_runtime=True):
106112

107113

108114
def configure_once(config=None, bind_in_runtime=True):
115+
# type: (Optional[BinderCallable], bool) -> Injector
109116
"""Create an injector with a callable config if not present, otherwise, do nothing."""
110117
with _INJECTOR_LOCK:
111118
if _INJECTOR:
@@ -115,19 +122,22 @@ def configure_once(config=None, bind_in_runtime=True):
115122

116123

117124
def clear_and_configure(config=None, bind_in_runtime=True):
125+
# type: (Optional[BinderCallable], bool) -> Injector
118126
"""Clear an existing injector and create another one with a callable config."""
119127
with _INJECTOR_LOCK:
120128
clear()
121129
return configure(config, bind_in_runtime=bind_in_runtime)
122130

123131

124132
def is_configured():
133+
# type: () -> bool
125134
"""Return true if an injector is already configured."""
126135
with _INJECTOR_LOCK:
127136
return _INJECTOR is not None
128137

129138

130139
def clear():
140+
# type: () -> None
131141
"""Clear an existing injector if present."""
132142
global _INJECTOR
133143

@@ -140,21 +150,25 @@ def clear():
140150

141151

142152
def instance(cls):
153+
# type: (Binding) -> T
143154
"""Inject an instance of a class."""
144155
return get_injector_or_die().get_instance(cls)
145156

146157

147158
def attr(cls):
159+
# type: (Binding) -> T
148160
"""Return a attribute injection (descriptor)."""
149161
return _AttributeInjection(cls)
150162

151163

152164
def param(name, cls=None):
165+
# type: (str, Binding) -> Callable
153166
"""Deprecated, use @inject.params. Return a decorator which injects an arg into a function."""
154167
return _ParameterInjection(name, cls)
155168

156169

157170
def params(**args_to_classes):
171+
# type: (Binding) -> Callable
158172
"""Return a decorator which injects args into a function.
159173
160174
For example::
@@ -167,6 +181,7 @@ def sign_up(name, email, cache, db):
167181

168182

169183
def autoparams(*selected_args):
184+
# type: (str) -> Callable
170185
"""Return a decorator that will inject args into a function using type annotations, Python >= 3.5 only.
171186
172187
For example::
@@ -201,11 +216,13 @@ def autoparams_decorator(func):
201216

202217

203218
def get_injector():
219+
# type: () -> Injector
204220
"""Return the current injector or None."""
205221
return _INJECTOR
206222

207223

208224
def get_injector_or_die():
225+
# type: () -> Injector
209226
"""Return the current injector or raise an InjectorException."""
210227
injector = _INJECTOR
211228
if not injector:
@@ -219,18 +236,21 @@ def __init__(self):
219236
self._bindings = {}
220237

221238
def install(self, config):
239+
# type: (BinderCallable) -> Binder
222240
"""Install another callable configuration."""
223241
config(self)
224242
return self
225243

226244
def bind(self, cls, instance):
245+
# type: (Binding, T) -> Binder
227246
"""Bind a class to an instance."""
228247
self._check_class(cls)
229248
self._bindings[cls] = lambda: instance
230249
logger.debug('Bound %s to an instance %s', cls, instance)
231250
return self
232251

233252
def bind_to_constructor(self, cls, constructor):
253+
# type: (Binding, Constructor) -> Binder
234254
"""Bind a class to a callable singleton constructor."""
235255
self._check_class(cls)
236256
if constructor is None:
@@ -241,6 +261,7 @@ def bind_to_constructor(self, cls, constructor):
241261
return self
242262

243263
def bind_to_provider(self, cls, provider):
264+
# type: (Binding, Provider) -> Binder
244265
"""Bind a class to a callable instance provider executed for each injection."""
245266
self._check_class(cls)
246267
if provider is None:
@@ -251,6 +272,7 @@ def bind_to_provider(self, cls, provider):
251272
return self
252273

253274
def _check_class(self, cls):
275+
# type: (Binding) -> None
254276
if cls is None:
255277
raise InjectorException('Binding key cannot be None')
256278

@@ -269,6 +291,7 @@ def __init__(self, config=None, bind_in_runtime=True):
269291
self._bindings = {}
270292

271293
def get_instance(self, cls):
294+
# type: (Binding) -> T
272295
"""Return an instance for a class."""
273296
binding = self._bindings.get(cls)
274297
if binding:

src/inject.pyi

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)