From 81072832e4e392508856772ab68d82ffe74f5459 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Fri, 16 Sep 2016 16:02:59 +0300 Subject: [PATCH 1/4] Add deprecation warning when @inject is used --- dependency_injector/injections.py | 11 +++++++++++ tests/test_injections.py | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index 84ba1f0a..ac52dc9c 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -1,5 +1,7 @@ """Dependency injector injections module.""" +import warnings + import six from dependency_injector.providers.base import ( @@ -41,6 +43,10 @@ def inject(*args, **kwargs): def __init__(self, arg1, arg2): pass + .. deprecated:: 2.2.0 + Usage of :py:func:`inject` decorator can lead to bad design and could + be considered as anti-pattern. + :param args: Tuple of context positional arguments. :type args: tuple[object] @@ -50,6 +56,11 @@ def inject(*args, **kwargs): :return: Class / callable decorator :rtype: (callable) -> (type | callable) """ + warnings.warn(message='Call to a deprecated decorator - @{0}.{1}' + .format(inject.__module__, inject.__name__), + category=DeprecationWarning, + stacklevel=2) + arg_injections = _parse_positional_injections(args) kwarg_injections = _parse_keyword_injections(kwargs) diff --git a/tests/test_injections.py b/tests/test_injections.py index 03cffad0..302ea8de 100644 --- a/tests/test_injections.py +++ b/tests/test_injections.py @@ -1,5 +1,7 @@ """Dependency injector injections unittests.""" +import warnings + import unittest2 as unittest from dependency_injector import injections @@ -176,3 +178,25 @@ class InjectTests(unittest.TestCase): @injections.inject(arg1=123) class Test(object): """Test class.""" + + +class InjectDeprecationTests(unittest.TestCase): + """Deprecation of `@inject()` tests.""" + + def test_deprecation_warning_on_usage(self): + """Test that DeprecationWarning is produced when `@inject` is used.""" + with warnings.catch_warnings(record=True) as caught_warnings: + warnings.simplefilter('always') + + @injections.inject(1) + def _example(arg): + pass + + warnings.simplefilter('default') + + self.assertEquals(len(caught_warnings), 1) + self.assertEquals(caught_warnings[-1].category, DeprecationWarning) + self.assertIn('Call to a deprecated decorator', + str(caught_warnings[-1].message)) + self.assertIn('@dependency_injector.injections.inject', + str(caught_warnings[-1].message)) From bff0e58f7f6b485c7877f478d56fe296b4dfd8cc Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Sun, 18 Sep 2016 23:00:10 +0300 Subject: [PATCH 2/4] Update miniapps/services example --- README.rst | 73 +++++++------------ examples/miniapps/services/README.rst | 2 +- .../{application.py => containers.py} | 11 +++ ...syntax_1.py => containers_alt_syntax_1.py} | 11 +++ ...syntax_2.py => containers_alt_syntax_2.py} | 11 +++ examples/miniapps/services/example/main.py | 8 ++ examples/miniapps/services/main.py | 18 ----- examples/miniapps/services/run.py | 19 +++++ 8 files changed, 88 insertions(+), 65 deletions(-) rename examples/miniapps/services/{application.py => containers.py} (75%) rename examples/miniapps/services/{application_alt_syntax_1.py => containers_alt_syntax_1.py} (76%) rename examples/miniapps/services/{application_alt_syntax_2.py => containers_alt_syntax_2.py} (76%) create mode 100644 examples/miniapps/services/example/main.py delete mode 100644 examples/miniapps/services/main.py create mode 100644 examples/miniapps/services/run.py diff --git a/README.rst b/README.rst index 57ea6719..5df70f81 100644 --- a/README.rst +++ b/README.rst @@ -62,6 +62,8 @@ system that consists from several business and platform services: import sqlite3 import boto.s3.connection + + import example.main import example.services import dependency_injector.containers as containers @@ -92,29 +94,38 @@ system that consists from several business and platform services: db=Platform.database, s3=Platform.s3) -Next example demonstrates usage of ``@inject`` decorator with IoC containers -defined above: + + class Application(containers.DeclarativeContainer): + """IoC container of application component providers.""" + + main = providers.Callable(example.main.main, + users_service=Services.users, + auth_service=Services.auth, + photos_service=Services.photos) + +Next example demonstrates usage of IoC containers & providers defined above: .. code-block:: python - """Dependency Injector @inject decorator example.""" + """Run example application.""" - import application - import dependency_injector.injections as injections - - - @injections.inject(users_service=application.Services.users) - @injections.inject(auth_service=application.Services.auth) - @injections.inject(photos_service=application.Services.photos) - def main(users_service, auth_service, photos_service): - """Main function.""" - user = users_service.get_user('user') - auth_service.authenticate(user, 'secret') - photos_service.upload_photo(user['id'], 'photo.jpg') + import containers if __name__ == '__main__': - main() + containers.Application.main() + + # Previous call is an equivalent of next operations: + # + # database = sqlite3.connect(':memory:') + # s3 = boto.s3.connection.S3Connection(aws_access_key_id='KEY', + # aws_secret_access_key='SECRET') + # + # example.main.main(users_service=example.services.Users(db=database), + # auth_service=example.services.Auth(db=database, + # token_ttl=3600), + # photos_service=example.services.Photos(db=database, + # s3=s3)) Alternative definition styles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -136,21 +147,6 @@ IoC containers from previous example could look like these: .add_kwargs(aws_access_key_id='KEY', aws_secret_access_key='SECRET') - - class Services(containers.DeclarativeContainer): - """IoC container of business service providers.""" - - users = providers.Factory(example.services.Users) \ - .add_kwargs(db=Platform.database) - - auth = providers.Factory(example.services.Auth) \ - .add_kwargs(db=Platform.database, - token_ttl=3600) - - photos = providers.Factory(example.services.Photos) \ - .add_kwargs(db=Platform.database, - s3=Platform.s3) - or like this these: .. code-block:: python @@ -165,21 +161,6 @@ or like this these: s3.add_kwargs(aws_access_key_id='KEY', aws_secret_access_key='SECRET') - - class Services(containers.DeclarativeContainer): - """IoC container of business service providers.""" - - users = providers.Factory(example.services.Users) - users.add_kwargs(db=Platform.database) - - auth = providers.Factory(example.services.Auth) - auth.add_kwargs(db=Platform.database, - token_ttl=3600) - - photos = providers.Factory(example.services.Photos) - photos.add_kwargs(db=Platform.database, - s3=Platform.s3) - You can get more *Dependency Injector* examples in ``/examples`` directory on GitHub: diff --git a/examples/miniapps/services/README.rst b/examples/miniapps/services/README.rst index 833bd44e..9fa352ae 100644 --- a/examples/miniapps/services/README.rst +++ b/examples/miniapps/services/README.rst @@ -5,4 +5,4 @@ Instructions for running .. code-block:: bash - python main.py + python run.py diff --git a/examples/miniapps/services/application.py b/examples/miniapps/services/containers.py similarity index 75% rename from examples/miniapps/services/application.py rename to examples/miniapps/services/containers.py index aa64bf1d..e12f1436 100644 --- a/examples/miniapps/services/application.py +++ b/examples/miniapps/services/containers.py @@ -2,6 +2,8 @@ import sqlite3 import boto.s3.connection + +import example.main import example.services import dependency_injector.containers as containers @@ -31,3 +33,12 @@ class Services(containers.DeclarativeContainer): photos = providers.Factory(example.services.Photos, db=Platform.database, s3=Platform.s3) + + +class Application(containers.DeclarativeContainer): + """IoC container of application component providers.""" + + main = providers.Callable(example.main.main, + users_service=Services.users, + auth_service=Services.auth, + photos_service=Services.photos) diff --git a/examples/miniapps/services/application_alt_syntax_1.py b/examples/miniapps/services/containers_alt_syntax_1.py similarity index 76% rename from examples/miniapps/services/application_alt_syntax_1.py rename to examples/miniapps/services/containers_alt_syntax_1.py index 41c82a6e..11803302 100644 --- a/examples/miniapps/services/application_alt_syntax_1.py +++ b/examples/miniapps/services/containers_alt_syntax_1.py @@ -5,6 +5,8 @@ Alternative injections definition style #1. import sqlite3 import boto.s3.connection + +import example.main import example.services import dependency_injector.containers as containers @@ -35,3 +37,12 @@ class Services(containers.DeclarativeContainer): photos = providers.Factory(example.services.Photos) \ .add_kwargs(db=Platform.database, s3=Platform.s3) + + +class Application(containers.DeclarativeContainer): + """IoC container of application component providers.""" + + main = providers.Callable(example.main.main) \ + .add_kwargs(users_service=Services.users, + auth_service=Services.auth, + photos_service=Services.photos) diff --git a/examples/miniapps/services/application_alt_syntax_2.py b/examples/miniapps/services/containers_alt_syntax_2.py similarity index 76% rename from examples/miniapps/services/application_alt_syntax_2.py rename to examples/miniapps/services/containers_alt_syntax_2.py index d3ca39a1..8e196e62 100644 --- a/examples/miniapps/services/application_alt_syntax_2.py +++ b/examples/miniapps/services/containers_alt_syntax_2.py @@ -5,6 +5,8 @@ Alternative injections definition style #2. import sqlite3 import boto.s3.connection + +import example.main import example.services import dependency_injector.containers as containers @@ -35,3 +37,12 @@ class Services(containers.DeclarativeContainer): photos = providers.Factory(example.services.Photos) photos.add_kwargs(db=Platform.database, s3=Platform.s3) + + +class Application(containers.DeclarativeContainer): + """IoC container of application component providers.""" + + main = providers.Callable(example.main.main) + main.add_kwargs(users_service=Services.users, + auth_service=Services.auth, + photos_service=Services.photos) diff --git a/examples/miniapps/services/example/main.py b/examples/miniapps/services/example/main.py new file mode 100644 index 00000000..49de9e0f --- /dev/null +++ b/examples/miniapps/services/example/main.py @@ -0,0 +1,8 @@ +"""Example main module.""" + + +def main(users_service, auth_service, photos_service): + """Example main function.""" + user = users_service.get_user('user') + auth_service.authenticate(user, 'secret') + photos_service.upload_photo(user['id'], 'photo.jpg') diff --git a/examples/miniapps/services/main.py b/examples/miniapps/services/main.py deleted file mode 100644 index cab655cc..00000000 --- a/examples/miniapps/services/main.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Dependency Injector @inject decorator example.""" - -import application -import dependency_injector.injections as injections - - -@injections.inject(users_service=application.Services.users) -@injections.inject(auth_service=application.Services.auth) -@injections.inject(photos_service=application.Services.photos) -def main(users_service, auth_service, photos_service): - """Main function.""" - user = users_service.get_user('user') - auth_service.authenticate(user, 'secret') - photos_service.upload_photo(user['id'], 'photo.jpg') - - -if __name__ == '__main__': - main() diff --git a/examples/miniapps/services/run.py b/examples/miniapps/services/run.py new file mode 100644 index 00000000..5c854202 --- /dev/null +++ b/examples/miniapps/services/run.py @@ -0,0 +1,19 @@ +"""Run example application.""" + +import containers + + +if __name__ == '__main__': + containers.Application.main() + + # Previous call is an equivalent of next operations: + # + # database = sqlite3.connect(':memory:') + # s3 = boto.s3.connection.S3Connection(aws_access_key_id='KEY', + # aws_secret_access_key='SECRET') + # + # example.main.main(users_service=example.services.Users(db=database), + # auth_service=example.services.Auth(db=database, + # token_ttl=3600), + # photos_service=example.services.Photos(db=database, + # s3=s3)) From 4e66c47f59ac8965a484f24307c8af8ee6542257 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Thu, 22 Sep 2016 14:40:45 +0300 Subject: [PATCH 3/4] Update movie lister example --- examples/miniapps/movie_lister/README.rst | 2 - examples/miniapps/movie_lister/app_csv.py | 38 ++++++------ examples/miniapps/movie_lister/app_db.py | 39 ++++++------ examples/miniapps/movie_lister/app_db_csv.py | 59 +++++++++++-------- examples/miniapps/movie_lister/create_db.py | 33 ----------- .../miniapps/movie_lister/data/.gitignore | 5 ++ .../miniapps/movie_lister/example/__init__.py | 1 + examples/miniapps/movie_lister/example/db.py | 35 +++++++++++ .../miniapps/movie_lister/example/main.py | 17 ++++++ .../miniapps/movie_lister/movies/__init__.py | 6 +- .../miniapps/movie_lister/movies/finders.py | 20 +++---- examples/miniapps/movie_lister/settings.py | 9 ++- 12 files changed, 146 insertions(+), 118 deletions(-) delete mode 100644 examples/miniapps/movie_lister/create_db.py create mode 100644 examples/miniapps/movie_lister/data/.gitignore create mode 100644 examples/miniapps/movie_lister/example/__init__.py create mode 100644 examples/miniapps/movie_lister/example/db.py create mode 100644 examples/miniapps/movie_lister/example/main.py diff --git a/examples/miniapps/movie_lister/README.rst b/examples/miniapps/movie_lister/README.rst index e81aa815..616b9106 100644 --- a/examples/miniapps/movie_lister/README.rst +++ b/examples/miniapps/movie_lister/README.rst @@ -11,8 +11,6 @@ Instructions for running: .. code-block:: bash - python create_db.py - python app_csv.py python app_db.py python app_db_csv.py diff --git a/examples/miniapps/movie_lister/app_csv.py b/examples/miniapps/movie_lister/app_csv.py index e54f27ad..75dfef42 100644 --- a/examples/miniapps/movie_lister/app_csv.py +++ b/examples/miniapps/movie_lister/app_csv.py @@ -9,42 +9,40 @@ This mini application uses ``movies`` library, that is configured to work with csv file movies database. """ -import dependency_injector.containers as containers -import dependency_injector.providers as providers -import dependency_injector.injections as injections - import movies import movies.finders +import example.main +import example.db + import settings +import dependency_injector.containers as containers +import dependency_injector.providers as providers + @containers.override(movies.MoviesModule) class MyMoviesModule(containers.DeclarativeContainer): """IoC container for overriding movies module component providers.""" movie_finder = providers.Factory(movies.finders.CsvMovieFinder, - csv_file=settings.MOVIES_CSV_PATH, - delimeter=',', + csv_file_path=settings.MOVIES_CSV_PATH, + delimiter=',', **movies.MoviesModule.movie_finder.kwargs) -@injections.inject(movies.MoviesModule.movie_lister) -def main(movie_lister): - """Main function. +class CsvApplication(containers.DeclarativeContainer): + """IoC container of csv application component providers.""" - This program prints info about all movies that were directed by different - persons and then prints all movies that were released in 2015. + main = providers.Callable(example.main.main, + movie_lister=movies.MoviesModule.movie_lister) - :param movie_lister: Movie lister instance - :type movie_lister: movies.listers.MovieLister - """ - print movie_lister.movies_directed_by('Francis Lawrence') - print movie_lister.movies_directed_by('Patricia Riggen') - print movie_lister.movies_directed_by('JJ Abrams') - - print movie_lister.movies_released_in(2015) + init_db = providers.Callable(example.db.init_csv, + movies_data=settings.MOVIES_SAMPLE_DATA, + csv_file_path=settings.MOVIES_CSV_PATH, + delimiter=',') if __name__ == '__main__': - main() + CsvApplication.init_db() + CsvApplication.main() diff --git a/examples/miniapps/movie_lister/app_db.py b/examples/miniapps/movie_lister/app_db.py index 9c762fe8..8f15e524 100644 --- a/examples/miniapps/movie_lister/app_db.py +++ b/examples/miniapps/movie_lister/app_db.py @@ -11,18 +11,20 @@ sqlite movies database. import sqlite3 -import dependency_injector.containers as containers -import dependency_injector.providers as providers -import dependency_injector.injections as injections - import movies import movies.finders +import example.main +import example.db + import settings +import dependency_injector.containers as containers +import dependency_injector.providers as providers -class ApplicationModule(containers.DeclarativeContainer): - """IoC container of application component providers.""" + +class ResourcesModule(containers.DeclarativeContainer): + """IoC container of application resource providers.""" database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH) @@ -32,26 +34,21 @@ class MyMoviesModule(containers.DeclarativeContainer): """IoC container for overriding movies module component providers.""" movie_finder = providers.Factory(movies.finders.SqliteMovieFinder, - database=ApplicationModule.database, + database=ResourcesModule.database, **movies.MoviesModule.movie_finder.kwargs) -@injections.inject(movies.MoviesModule.movie_lister) -def main(movie_lister): - """Main function. +class DbApplication(containers.DeclarativeContainer): + """IoC container of database application component providers.""" - This program prints info about all movies that were directed by different - persons and then prints all movies that were released in 2015. + main = providers.Callable(example.main.main, + movie_lister=movies.MoviesModule.movie_lister) - :param movie_lister: Movie lister instance - :type movie_lister: movies.listers.MovieLister - """ - print movie_lister.movies_directed_by('Francis Lawrence') - print movie_lister.movies_directed_by('Patricia Riggen') - print movie_lister.movies_directed_by('JJ Abrams') - - print movie_lister.movies_released_in(2015) + init_db = providers.Callable(example.db.init_sqlite, + movies_data=settings.MOVIES_SAMPLE_DATA, + database=ResourcesModule.database) if __name__ == '__main__': - main() + DbApplication.init_db() + DbApplication.main() diff --git a/examples/miniapps/movie_lister/app_db_csv.py b/examples/miniapps/movie_lister/app_db_csv.py index a8b40eed..b7461430 100644 --- a/examples/miniapps/movie_lister/app_db_csv.py +++ b/examples/miniapps/movie_lister/app_db_csv.py @@ -11,18 +11,20 @@ sqlite movies database and csv file movies database. import sqlite3 -import dependency_injector.containers as containers -import dependency_injector.providers as providers -import dependency_injector.injections as injections - import movies import movies.finders +import example.main +import example.db + import settings +import dependency_injector.containers as containers +import dependency_injector.providers as providers -class ApplicationModule(containers.DeclarativeContainer): - """IoC container of application component providers.""" + +class ResourcesModule(containers.DeclarativeContainer): + """IoC container of application resource providers.""" database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH) @@ -32,7 +34,7 @@ class DbMoviesModule(movies.MoviesModule): """IoC container for overriding movies module component providers.""" movie_finder = providers.Factory(movies.finders.SqliteMovieFinder, - database=ApplicationModule.database, + database=ResourcesModule.database, **movies.MoviesModule.movie_finder.kwargs) @@ -41,31 +43,36 @@ class CsvMoviesModule(movies.MoviesModule): """IoC container for overriding movies module component providers.""" movie_finder = providers.Factory(movies.finders.CsvMovieFinder, - csv_file=settings.MOVIES_CSV_PATH, - delimeter=',', + csv_file_path=settings.MOVIES_CSV_PATH, + delimiter=',', **movies.MoviesModule.movie_finder.kwargs) -@injections.inject(db_movie_lister=DbMoviesModule.movie_lister) -@injections.inject(csv_movie_lister=CsvMoviesModule.movie_lister) -def main(db_movie_lister, csv_movie_lister): - """Main function. +class DbApplication(containers.DeclarativeContainer): + """IoC container of database application component providers.""" - This program prints info about all movies that were directed by different - persons and then prints all movies that were released in 2015. + main = providers.Callable(example.main.main, + movie_lister=DbMoviesModule.movie_lister) - :param db_movie_lister: Movie lister, configured to work with database - :type db_movie_lister: movies.listers.MovieLister + init_db = providers.Callable(example.db.init_sqlite, + movies_data=settings.MOVIES_SAMPLE_DATA, + database=ResourcesModule.database) - :param csv_movie_lister: Movie lister, configured to work with csv file - :type csv_movie_lister: movies.listers.MovieLister - """ - for movie_lister in (db_movie_lister, csv_movie_lister): - print movie_lister.movies_directed_by('Francis Lawrence') - print movie_lister.movies_directed_by('Patricia Riggen') - print movie_lister.movies_directed_by('JJ Abrams') - print movie_lister.movies_released_in(2015) +class CsvApplication(containers.DeclarativeContainer): + """IoC container of csv application component providers.""" + + main = providers.Callable(example.main.main, + movie_lister=CsvMoviesModule.movie_lister) + + init_db = providers.Callable(example.db.init_csv, + movies_data=settings.MOVIES_SAMPLE_DATA, + csv_file_path=settings.MOVIES_CSV_PATH, + delimiter=',') if __name__ == '__main__': - main() + DbApplication.init_db() + DbApplication.main() + + CsvApplication.init_db() + CsvApplication.main() diff --git a/examples/miniapps/movie_lister/create_db.py b/examples/miniapps/movie_lister/create_db.py deleted file mode 100644 index 5482afdc..00000000 --- a/examples/miniapps/movie_lister/create_db.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Script for initializing movie databases.""" - -import os -import csv -import sqlite3 -import shutil - -from settings import DATA_DIR -from settings import MOVIES_CSV_PATH -from settings import MOVIES_DB_PATH - - -MOVIES = (('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'), - ('The 33', 2015, 'Patricia Riggen'), - ('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams')) - - -if __name__ == '__main__': - # (Re)create data directory: - if os.path.exists(DATA_DIR): - shutil.rmtree(DATA_DIR) - os.makedirs(DATA_DIR) - - # Initialize sqlite database: - connection = sqlite3.connect(MOVIES_DB_PATH) - with connection: - connection.execute('CREATE TABLE movies ' - '(name text, year int, director text)') - connection.executemany('INSERT INTO movies VALUES (?,?,?)', MOVIES) - - # Initialize csv database: - with open(MOVIES_CSV_PATH, 'w') as csv_file: - csv.writer(csv_file).writerows(MOVIES) diff --git a/examples/miniapps/movie_lister/data/.gitignore b/examples/miniapps/movie_lister/data/.gitignore new file mode 100644 index 00000000..bc208b8f --- /dev/null +++ b/examples/miniapps/movie_lister/data/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* + +# Except this file: +!.gitignore diff --git a/examples/miniapps/movie_lister/example/__init__.py b/examples/miniapps/movie_lister/example/__init__.py new file mode 100644 index 00000000..bfa99aa2 --- /dev/null +++ b/examples/miniapps/movie_lister/example/__init__.py @@ -0,0 +1 @@ +"""Example top-level package.""" diff --git a/examples/miniapps/movie_lister/example/db.py b/examples/miniapps/movie_lister/example/db.py new file mode 100644 index 00000000..d519fb03 --- /dev/null +++ b/examples/miniapps/movie_lister/example/db.py @@ -0,0 +1,35 @@ +"""Example database module.""" + +import csv + + +def init_sqlite(movies_data, database): + """Initialize sqlite3 movies database. + + :param movies_data: Data about movies + :type movies_data: tuple[tuple] + + :param database: Connection to sqlite database with movies data + :type database: sqlite3.Connection + """ + with database: + database.execute('CREATE TABLE IF NOT EXISTS movies ' + '(name text, year int, director text)') + database.execute('DELETE FROM movies') + database.executemany('INSERT INTO movies VALUES (?,?,?)', movies_data) + + +def init_csv(movies_data, csv_file_path, delimiter): + """Initialize csv movies database. + + :param movies_data: Data about movies + :type movies_data: tuple[tuple] + + :param csv_file_path: Path to csv file with movies data + :type csv_file_path: str + + :param delimiter: Csv file's delimiter + :type delimiter: str + """ + with open(csv_file_path, 'w') as csv_file: + csv.writer(csv_file, delimiter=delimiter).writerows(movies_data) diff --git a/examples/miniapps/movie_lister/example/main.py b/examples/miniapps/movie_lister/example/main.py new file mode 100644 index 00000000..26a51f63 --- /dev/null +++ b/examples/miniapps/movie_lister/example/main.py @@ -0,0 +1,17 @@ +"""Example main module.""" + + +def main(movie_lister): + """Main function. + + This program prints info about all movies that were directed by different + persons and then prints all movies that were released in 2015. + + :param movie_lister: Movie lister instance + :type movie_lister: movies.listers.MovieLister + """ + print(movie_lister.movies_directed_by('Francis Lawrence')) + print(movie_lister.movies_directed_by('Patricia Riggen')) + print(movie_lister.movies_directed_by('JJ Abrams')) + + print(movie_lister.movies_released_in(2015)) diff --git a/examples/miniapps/movie_lister/movies/__init__.py b/examples/miniapps/movie_lister/movies/__init__.py index 2f6bd185..45930056 100644 --- a/examples/miniapps/movie_lister/movies/__init__.py +++ b/examples/miniapps/movie_lister/movies/__init__.py @@ -12,13 +12,13 @@ concrete finder implementation in terms of library configuration. Each of ``MoviesModule`` providers could be overridden. """ -import dependency_injector.containers as containers -import dependency_injector.providers as providers - import movies.finders import movies.listers import movies.models +import dependency_injector.containers as containers +import dependency_injector.providers as providers + class MoviesModule(containers.DeclarativeContainer): """IoC container of movies module component providers.""" diff --git a/examples/miniapps/movie_lister/movies/finders.py b/examples/miniapps/movie_lister/movies/finders.py index 9d3cbc27..b9b8f42a 100644 --- a/examples/miniapps/movie_lister/movies/finders.py +++ b/examples/miniapps/movie_lister/movies/finders.py @@ -33,20 +33,20 @@ class MovieFinder(object): class CsvMovieFinder(MovieFinder): """Movie finder that fetches movies data from csv file.""" - def __init__(self, movie_model, csv_file, delimeter): + def __init__(self, movie_model, csv_file_path, delimiter): """Initializer. :param movie_model: Movie model's factory :type movie_model: movies.models.Movie - :param csv_file: Path to csv file with movies data - :type csv_file: str + :param csv_file_path: Path to csv file with movies data + :type csv_file_path: str - :param delimeter: Csv file's delimeter - :type delimeter: str + :param delimiter: Csv file's delimiter + :type delimiter: str """ - self._csv_file = csv_file - self._delimeter = delimeter + self._csv_file_path = csv_file_path + self._delimiter = delimiter super(CsvMovieFinder, self).__init__(movie_model) def find_all(self): @@ -55,9 +55,9 @@ class CsvMovieFinder(MovieFinder): :rtype: list[movies.models.Movie] :return: List of movie instances. """ - with open(self._csv_file) as csv_file: - reader = csv.reader(csv_file, delimiter=self._delimeter) - return [self._movie_model(*row) for row in reader] + with open(self._csv_file_path) as csv_file: + csv_reader = csv.reader(csv_file, delimiter=self._delimiter) + return [self._movie_model(*row) for row in csv_reader] class SqliteMovieFinder(MovieFinder): diff --git a/examples/miniapps/movie_lister/settings.py b/examples/miniapps/movie_lister/settings.py index f318b9e1..0a9916f8 100644 --- a/examples/miniapps/movie_lister/settings.py +++ b/examples/miniapps/movie_lister/settings.py @@ -7,8 +7,11 @@ import os DATA_DIR = os.path.abspath(os.path.dirname(__file__) + '/data') - MOVIES_CSV_PATH = DATA_DIR + '/movies.csv' -MOVIES_CSV_DELIMETER = ',' - MOVIES_DB_PATH = DATA_DIR + '/movies.db' + +MOVIES_SAMPLE_DATA = ( + ('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'), + ('The 33', 2015, 'Patricia Riggen'), + ('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'), +) From 38c9d2f18ad95738c7a14906cb53d2ca86c5e6b9 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Fri, 23 Sep 2016 00:24:45 +0300 Subject: [PATCH 4/4] Update docs --- dependency_injector/injections.py | 7 +++++ docs/advanced_usage/index.rst | 4 +++ docs/api/index.rst | 1 - docs/examples/index.rst | 4 +-- docs/examples/movie_lister.rst | 32 +++++++++++++++++--- docs/index.rst | 1 - docs/main/changelog.rst | 2 +- examples/miniapps/movie_lister/app_csv.py | 2 +- examples/miniapps/movie_lister/app_db.py | 2 +- examples/miniapps/movie_lister/app_db_csv.py | 2 +- 10 files changed, 44 insertions(+), 13 deletions(-) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index ac52dc9c..14c9bd68 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -15,6 +15,13 @@ from dependency_injector import errors def inject(*args, **kwargs): """Dependency injection decorator. + .. warning:: + + :py:func:`inject` decorator has been deprecated since version 2.2.0. + + Usage of :py:func:`inject` decorator can lead to bad design and could + be considered as anti-pattern. + :py:func:`inject` decorator can be used for making inline dependency injections. It patches decorated callable in such way that dependency injection will be done during every call of decorated callable. diff --git a/docs/advanced_usage/index.rst b/docs/advanced_usage/index.rst index 2f5f7176..cd4ce33a 100644 --- a/docs/advanced_usage/index.rst +++ b/docs/advanced_usage/index.rst @@ -9,6 +9,10 @@ Current section of documentation describes advanced usage of .. currentmodule:: dependency_injector.injections +.. warning:: + + :py:func:`inject` decorator has been deprecated since version 2.2.0. + :py:func:`inject` decorator is a part of :py:mod:`dependency_injector.injections` module. diff --git a/docs/api/index.rst b/docs/api/index.rst index ad06c9d9..1f1df940 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -7,6 +7,5 @@ API Documentation top_level providers containers - injections utils errors diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 907553f5..89d623fb 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -9,8 +9,8 @@ Examples "Dependency Injector" framework. Current section of documentation is designed to provide several example mini -applications that are built on the top of inversion of control principle and -powered by *Dependency Injector* framework. +applications that are built according to the inversion of control principle +and powered by *Dependency Injector* framework. .. toctree:: :maxdepth: 2 diff --git a/docs/examples/movie_lister.rst b/docs/examples/movie_lister.rst index 2fbd4635..c982746d 100644 --- a/docs/examples/movie_lister.rst +++ b/docs/examples/movie_lister.rst @@ -20,14 +20,14 @@ Like Martin says: While original Martin's MovieLister example was a bit modified here, it makes sense to provide some description. So, the idea of this example is to -create ``movies`` library that can be configurable to work with different -movie databases (csv, sqlite) and provide 2 main features: +create ``movies`` library that can be configured to work with different +movie databases (csv, sqlite, etc...) and provide 2 main features: 1. List all movies that were directed by certain person. 2. List all movies that were released in certain year. Also this example contains 3 mini applications that are based on ``movies`` -library : +library: 1. ``app_csv.py`` - list movies by certain criteria from csv file database. 2. ``app_db.py`` - list movies by certain criteria from sqlite database. @@ -38,8 +38,6 @@ Instructions for running: .. code-block:: bash - python create_db.py - python app_csv.py python app_db.py python app_db_csv.py @@ -74,6 +72,30 @@ Listing of ``movies/__init__.py``: :language: python :linenos: +Example application +~~~~~~~~~~~~~~~~~~~ + +Example application structure: + +.. code-block:: bash + + /example + /__init__.py + /db.py + /main.py + +Listing of ``examples/main.py``: + +.. literalinclude:: ../../examples/miniapps/movie_lister/example/main.py + :language: python + :linenos: + +Listing of ``examples/db.py``: + +.. literalinclude:: ../../examples/miniapps/movie_lister/example/db.py + :language: python + :linenos: + Csv application ~~~~~~~~~~~~~~~ diff --git a/docs/index.rst b/docs/index.rst index 7eefdb52..9ac141f1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -59,7 +59,6 @@ Contents main/installation providers/index containers/index - advanced_usage/index examples/index api/index main/feedback diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 3366a0ee..6d04874d 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -9,7 +9,7 @@ follows `Semantic versioning`_ Development version ------------------- -- No features. +- Deprecate ``inject`` decorator. 2.1.1 ----- diff --git a/examples/miniapps/movie_lister/app_csv.py b/examples/miniapps/movie_lister/app_csv.py index 75dfef42..e7aaa310 100644 --- a/examples/miniapps/movie_lister/app_csv.py +++ b/examples/miniapps/movie_lister/app_csv.py @@ -12,8 +12,8 @@ csv file movies database. import movies import movies.finders -import example.main import example.db +import example.main import settings diff --git a/examples/miniapps/movie_lister/app_db.py b/examples/miniapps/movie_lister/app_db.py index 8f15e524..708ba287 100644 --- a/examples/miniapps/movie_lister/app_db.py +++ b/examples/miniapps/movie_lister/app_db.py @@ -14,8 +14,8 @@ import sqlite3 import movies import movies.finders -import example.main import example.db +import example.main import settings diff --git a/examples/miniapps/movie_lister/app_db_csv.py b/examples/miniapps/movie_lister/app_db_csv.py index b7461430..de83e12f 100644 --- a/examples/miniapps/movie_lister/app_db_csv.py +++ b/examples/miniapps/movie_lister/app_db_csv.py @@ -14,8 +14,8 @@ import sqlite3 import movies import movies.finders -import example.main import example.db +import example.main import settings