Skip to content

Commit 53f60d6

Browse files
authored
Merge pull request #136 from ets-labs/deprecate_inject_decorator
Deprecate inject decorator
2 parents d9f4aed + 38c9d2f commit 53f60d6

File tree

28 files changed

+309
-192
lines changed

28 files changed

+309
-192
lines changed

README.rst

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ system that consists from several business and platform services:
6262
6363
import sqlite3
6464
import boto.s3.connection
65+
66+
import example.main
6567
import example.services
6668
6769
import dependency_injector.containers as containers
@@ -92,29 +94,38 @@ system that consists from several business and platform services:
9294
db=Platform.database,
9395
s3=Platform.s3)
9496
95-
Next example demonstrates usage of ``@inject`` decorator with IoC containers
96-
defined above:
9797
98-
.. code-block:: python
98+
class Application(containers.DeclarativeContainer):
99+
"""IoC container of application component providers."""
99100
100-
"""Dependency Injector @inject decorator example."""
101+
main = providers.Callable(example.main.main,
102+
users_service=Services.users,
103+
auth_service=Services.auth,
104+
photos_service=Services.photos)
101105
102-
import application
103-
import dependency_injector.injections as injections
106+
Next example demonstrates usage of IoC containers & providers defined above:
104107

108+
.. code-block:: python
105109
106-
@injections.inject(users_service=application.Services.users)
107-
@injections.inject(auth_service=application.Services.auth)
108-
@injections.inject(photos_service=application.Services.photos)
109-
def main(users_service, auth_service, photos_service):
110-
"""Main function."""
111-
user = users_service.get_user('user')
112-
auth_service.authenticate(user, 'secret')
113-
photos_service.upload_photo(user['id'], 'photo.jpg')
110+
"""Run example application."""
111+
112+
import containers
114113
115114
116115
if __name__ == '__main__':
117-
main()
116+
containers.Application.main()
117+
118+
# Previous call is an equivalent of next operations:
119+
#
120+
# database = sqlite3.connect(':memory:')
121+
# s3 = boto.s3.connection.S3Connection(aws_access_key_id='KEY',
122+
# aws_secret_access_key='SECRET')
123+
#
124+
# example.main.main(users_service=example.services.Users(db=database),
125+
# auth_service=example.services.Auth(db=database,
126+
# token_ttl=3600),
127+
# photos_service=example.services.Photos(db=database,
128+
# s3=s3))
118129
119130
Alternative definition styles
120131
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -136,21 +147,6 @@ IoC containers from previous example could look like these:
136147
.add_kwargs(aws_access_key_id='KEY',
137148
aws_secret_access_key='SECRET')
138149
139-
140-
class Services(containers.DeclarativeContainer):
141-
"""IoC container of business service providers."""
142-
143-
users = providers.Factory(example.services.Users) \
144-
.add_kwargs(db=Platform.database)
145-
146-
auth = providers.Factory(example.services.Auth) \
147-
.add_kwargs(db=Platform.database,
148-
token_ttl=3600)
149-
150-
photos = providers.Factory(example.services.Photos) \
151-
.add_kwargs(db=Platform.database,
152-
s3=Platform.s3)
153-
154150
or like this these:
155151

156152
.. code-block:: python
@@ -165,21 +161,6 @@ or like this these:
165161
s3.add_kwargs(aws_access_key_id='KEY',
166162
aws_secret_access_key='SECRET')
167163
168-
169-
class Services(containers.DeclarativeContainer):
170-
"""IoC container of business service providers."""
171-
172-
users = providers.Factory(example.services.Users)
173-
users.add_kwargs(db=Platform.database)
174-
175-
auth = providers.Factory(example.services.Auth)
176-
auth.add_kwargs(db=Platform.database,
177-
token_ttl=3600)
178-
179-
photos = providers.Factory(example.services.Photos)
180-
photos.add_kwargs(db=Platform.database,
181-
s3=Platform.s3)
182-
183164
You can get more *Dependency Injector* examples in ``/examples`` directory on
184165
GitHub:
185166

dependency_injector/injections.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Dependency injector injections module."""
22

3+
import warnings
4+
35
import six
46

57
from dependency_injector.providers.base import (
@@ -13,6 +15,13 @@
1315
def inject(*args, **kwargs):
1416
"""Dependency injection decorator.
1517
18+
.. warning::
19+
20+
:py:func:`inject` decorator has been deprecated since version 2.2.0.
21+
22+
Usage of :py:func:`inject` decorator can lead to bad design and could
23+
be considered as anti-pattern.
24+
1625
:py:func:`inject` decorator can be used for making inline dependency
1726
injections. It patches decorated callable in such way that dependency
1827
injection will be done during every call of decorated callable.
@@ -41,6 +50,10 @@ class SomeClass(object):
4150
def __init__(self, arg1, arg2):
4251
pass
4352
53+
.. deprecated:: 2.2.0
54+
Usage of :py:func:`inject` decorator can lead to bad design and could
55+
be considered as anti-pattern.
56+
4457
:param args: Tuple of context positional arguments.
4558
:type args: tuple[object]
4659
@@ -50,6 +63,11 @@ def __init__(self, arg1, arg2):
5063
:return: Class / callable decorator
5164
:rtype: (callable) -> (type | callable)
5265
"""
66+
warnings.warn(message='Call to a deprecated decorator - @{0}.{1}'
67+
.format(inject.__module__, inject.__name__),
68+
category=DeprecationWarning,
69+
stacklevel=2)
70+
5371
arg_injections = _parse_positional_injections(args)
5472
kwarg_injections = _parse_keyword_injections(kwargs)
5573

docs/advanced_usage/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Current section of documentation describes advanced usage of
99

1010
.. currentmodule:: dependency_injector.injections
1111

12+
.. warning::
13+
14+
:py:func:`inject` decorator has been deprecated since version 2.2.0.
15+
1216
:py:func:`inject` decorator is a part of
1317
:py:mod:`dependency_injector.injections` module.
1418

docs/api/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ API Documentation
77
top_level
88
providers
99
containers
10-
injections
1110
utils
1211
errors

docs/examples/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Examples
99
"Dependency Injector" framework.
1010

1111
Current section of documentation is designed to provide several example mini
12-
applications that are built on the top of inversion of control principle and
13-
powered by *Dependency Injector* framework.
12+
applications that are built according to the inversion of control principle
13+
and powered by *Dependency Injector* framework.
1414

1515
.. toctree::
1616
:maxdepth: 2

docs/examples/movie_lister.rst

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ Like Martin says:
2020

2121
While original Martin's MovieLister example was a bit modified here, it
2222
makes sense to provide some description. So, the idea of this example is to
23-
create ``movies`` library that can be configurable to work with different
24-
movie databases (csv, sqlite) and provide 2 main features:
23+
create ``movies`` library that can be configured to work with different
24+
movie databases (csv, sqlite, etc...) and provide 2 main features:
2525

2626
1. List all movies that were directed by certain person.
2727
2. List all movies that were released in certain year.
2828

2929
Also this example contains 3 mini applications that are based on ``movies``
30-
library :
30+
library:
3131

3232
1. ``app_csv.py`` - list movies by certain criteria from csv file database.
3333
2. ``app_db.py`` - list movies by certain criteria from sqlite database.
@@ -38,8 +38,6 @@ Instructions for running:
3838

3939
.. code-block:: bash
4040
41-
python create_db.py
42-
4341
python app_csv.py
4442
python app_db.py
4543
python app_db_csv.py
@@ -74,6 +72,30 @@ Listing of ``movies/__init__.py``:
7472
:language: python
7573
:linenos:
7674

75+
Example application
76+
~~~~~~~~~~~~~~~~~~~
77+
78+
Example application structure:
79+
80+
.. code-block:: bash
81+
82+
/example
83+
/__init__.py
84+
/db.py
85+
/main.py
86+
87+
Listing of ``examples/main.py``:
88+
89+
.. literalinclude:: ../../examples/miniapps/movie_lister/example/main.py
90+
:language: python
91+
:linenos:
92+
93+
Listing of ``examples/db.py``:
94+
95+
.. literalinclude:: ../../examples/miniapps/movie_lister/example/db.py
96+
:language: python
97+
:linenos:
98+
7799
Csv application
78100
~~~~~~~~~~~~~~~
79101

docs/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ Contents
5959
main/installation
6060
providers/index
6161
containers/index
62-
advanced_usage/index
6362
examples/index
6463
api/index
6564
main/feedback

docs/main/changelog.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ follows `Semantic versioning`_
99

1010
Development version
1111
-------------------
12-
- No features.
12+
- Deprecate ``inject`` decorator.
1313

1414
2.1.1
1515
-----

examples/miniapps/movie_lister/README.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ Instructions for running:
1111

1212
.. code-block:: bash
1313
14-
python create_db.py
15-
1614
python app_csv.py
1715
python app_db.py
1816
python app_db_csv.py

examples/miniapps/movie_lister/app_csv.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,40 @@
99
csv file movies database.
1010
"""
1111

12-
import dependency_injector.containers as containers
13-
import dependency_injector.providers as providers
14-
import dependency_injector.injections as injections
15-
1612
import movies
1713
import movies.finders
1814

15+
import example.db
16+
import example.main
17+
1918
import settings
2019

20+
import dependency_injector.containers as containers
21+
import dependency_injector.providers as providers
22+
2123

2224
@containers.override(movies.MoviesModule)
2325
class MyMoviesModule(containers.DeclarativeContainer):
2426
"""IoC container for overriding movies module component providers."""
2527

2628
movie_finder = providers.Factory(movies.finders.CsvMovieFinder,
27-
csv_file=settings.MOVIES_CSV_PATH,
28-
delimeter=',',
29+
csv_file_path=settings.MOVIES_CSV_PATH,
30+
delimiter=',',
2931
**movies.MoviesModule.movie_finder.kwargs)
3032

3133

32-
@injections.inject(movies.MoviesModule.movie_lister)
33-
def main(movie_lister):
34-
"""Main function.
35-
36-
This program prints info about all movies that were directed by different
37-
persons and then prints all movies that were released in 2015.
34+
class CsvApplication(containers.DeclarativeContainer):
35+
"""IoC container of csv application component providers."""
3836

39-
:param movie_lister: Movie lister instance
40-
:type movie_lister: movies.listers.MovieLister
41-
"""
42-
print movie_lister.movies_directed_by('Francis Lawrence')
43-
print movie_lister.movies_directed_by('Patricia Riggen')
44-
print movie_lister.movies_directed_by('JJ Abrams')
37+
main = providers.Callable(example.main.main,
38+
movie_lister=movies.MoviesModule.movie_lister)
4539

46-
print movie_lister.movies_released_in(2015)
40+
init_db = providers.Callable(example.db.init_csv,
41+
movies_data=settings.MOVIES_SAMPLE_DATA,
42+
csv_file_path=settings.MOVIES_CSV_PATH,
43+
delimiter=',')
4744

4845

4946
if __name__ == '__main__':
50-
main()
47+
CsvApplication.init_db()
48+
CsvApplication.main()

0 commit comments

Comments
 (0)