diff --git a/.gitignore b/.gitignore index efa4a5ca..5000a8dc 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ target/ # Virtualenv venv/ + +# SQLite +*.db diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..8acdd82b --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 diff --git a/examples/concept.py b/examples/concept.py new file mode 100644 index 00000000..f5d861f6 --- /dev/null +++ b/examples/concept.py @@ -0,0 +1,53 @@ +""" +Concept example of objects catalogs. +""" + +import objects +import sqlite3 + + +class A(object): + def __init__(self, db): + self.db = db + + +class B(object): + def __init__(self, a, db): + self.a = a + self.db = db + + +class Catalog(objects.Catalog): + """ + Objects catalog. + """ + + database = objects.Singleton(sqlite3.Connection, + database='example.db') + """ :type: (objects.Provider) -> sqlite3.Connection """ + + object_a = objects.NewInstance(A, + db=database) + """ :type: (objects.Provider) -> A """ + + object_b = objects.NewInstance(B, + a=object_a, + db=database) + """ :type: (objects.Provider) -> B """ + + +catalog = Catalog(Catalog.object_a, + Catalog.object_b) +a1 = catalog.object_a() +b1 = catalog.object_b() + +a2 = Catalog.object_a() +b2 = Catalog.object_b() + +print a1, a1.db +print a2, a2.db +print b1, b1.db +print b2, b2.db + +assert a1 is not a2 +assert b1 is not b2 diff --git a/objects/__init__.py b/objects/__init__.py new file mode 100644 index 00000000..16243060 --- /dev/null +++ b/objects/__init__.py @@ -0,0 +1,49 @@ +""" +`Objects` library. +""" + + +class Catalog(object): + def __init__(self, *args): + args = set(args) + for attribute_name in set(dir(self.__class__)) - set(dir(Catalog)): + provider = getattr(self, attribute_name) + if not isinstance(provider, Provider): + continue + if provider not in args: + setattr(self, attribute_name, None) + + +class Provider(object): + def __call__(self, *args, **kwargs): + raise NotImplementedError() + + +class NewInstance(Provider): + def __init__(self, provides, **dependencies): + self.provides = provides + self.dependencies = dependencies + + def __call__(self, *args, **kwargs): + for name, dependency in self.dependencies.iteritems(): + if name in kwargs: + continue + + if isinstance(dependency, Provider): + value = dependency.__call__() + else: + value = dependency + + kwargs[name] = value + return self.provides(*args, **kwargs) + + +class Singleton(NewInstance): + def __init__(self, *args, **kwargs): + self.instance = None + super(Singleton, self).__init__(*args, **kwargs) + + def __call__(self, *args, **kwargs): + if not self.instance: + self.instance = super(Singleton, self).__call__(*args, **kwargs) + return self.instance diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..e69de29b diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..c8f6c8c2 --- /dev/null +++ b/setup.py @@ -0,0 +1,65 @@ +""" +`Objects` setup script. +""" + +from setuptools import setup + + +# Getting description. +with open('README.md') as readme_file: + description = readme_file.read() + +# Getting requirements. +with open('requirements.txt') as version: + requirements = version.readlines() + + +# Getting version. +with open('VERSION') as version: + version = version.read().strip() + + +setup( + name='Objects', + version=version, + description='Python catalogs of objects providers', + long_description=description, + author='Roman Mogilatov', + author_email='rmogilatov@gmail.com', + maintainer='Roman Mogilatov', + maintainer_email='rmogilatov@gmail.com', + url='https://github.com/rmk135/objects', + license='BSD New', + packages=['objects'], + zip_safe=True, + install_requires=requirements, + # keywords=['Dependency injection', + # 'Dependency injection container', + # 'DI', + # 'DIC', + # 'Dependency injector', + # 'Inversion of Control', + # 'Inversion of Control container', + # 'IoC', + # 'IoC container'], + classifiers=[ + 'Development Status :: 1 - Planning', + # 'Development Status :: 4 - Beta', + # 'Intended Audience :: Developers', + # 'License :: OSI Approved :: BSD License', + # 'Operating System :: OS Independent', + # 'Programming Language :: Python', + # 'Programming Language :: Python :: 2', + # 'Programming Language :: Python :: 2.6', + # 'Programming Language :: Python :: 2.7', + # 'Programming Language :: Python :: 3', + # 'Programming Language :: Python :: 3.2', + # 'Programming Language :: Python :: 3.3', + # 'Programming Language :: Python :: 3.4', + # 'Programming Language :: Python :: Implementation :: CPython', + # 'Programming Language :: Python :: Implementation :: PyPy', + # 'Topic :: Software Development', + # 'Topic :: Software Development :: Libraries', + # 'Topic :: Software Development :: Libraries :: Python Modules', + ] +)