diff --git a/buildout.cfg b/buildout.cfg index c1538852..6c950948 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -8,6 +8,7 @@ develop = fixture_packages/ns fixture_packages/ns2 fixture_packages/no_mp_ns + fixture_packages/entry-point parts = devpython py.test sphinxpython sphinxbuilder releaser versions = versions show-picked-versions = true @@ -45,6 +46,7 @@ eggs = morepath ns.real ns.real2 no_mp_ns + entry-point [sphinxbuilder] recipe = collective.recipe.sphinxbuilder diff --git a/fixture_packages/entry-point/entrypoint/__init__.py b/fixture_packages/entry-point/entrypoint/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fixture_packages/entry-point/entrypoint/app.py b/fixture_packages/entry-point/entrypoint/app.py new file mode 100644 index 00000000..4a29bf9b --- /dev/null +++ b/fixture_packages/entry-point/entrypoint/app.py @@ -0,0 +1,10 @@ +import morepath + +app = morepath.App() + +class Foo(object): + pass + +@app.path(path='bar', model=Foo) +def get_foo(): + return Foo() diff --git a/fixture_packages/entry-point/setup.py b/fixture_packages/entry-point/setup.py new file mode 100644 index 00000000..705fd9ba --- /dev/null +++ b/fixture_packages/entry-point/setup.py @@ -0,0 +1,19 @@ +from setuptools import setup, find_packages + +setup(name='entry-point', + version='0.1dev', + description="Entry Point Test Fixture", + author="Martijn Faassen", + author_email="faassen@startifact.com", + license="BSD", + packages=find_packages(), + zip_safe=False, + install_requires=[ + 'setuptools', + 'morepath' + ], + entry_points={ + 'morepath': [ + 'autoimport = entrypoint', + ] + }) diff --git a/morepath/autosetup.py b/morepath/autosetup.py index c1f471e9..c8cd59bf 100644 --- a/morepath/autosetup.py +++ b/morepath/autosetup.py @@ -23,6 +23,21 @@ def autoconfig(ignore=None): ``myapp`` the package must be named ``myapp`` as well (not ``my-app`` or ``MyApp``). + * If the setup.py differs from the package name, it's possible + to specify the module morepath should scan using entry points:: + + setup(name='some-package', + ... + install_requires=[ + 'setuptools', + 'morepath' + ], + entry_points={ + 'morepath': [ + 'autoimport = somepackage', + ] + }) + This function creates a :class:`Config` object as with :func:`setup`, but before returning it scans all packages, looking for those that depend on Morepath directly or indirectly. This includes the package that @@ -153,12 +168,32 @@ def morepath_packages(): yield import_package(distribution) +def get_module_name(distribution): + """ Determines the module name to import from the given distribution. + + If an entry point named ``autoimport`` is found in the group ``morepath``, + it's value is used. If not, the project_name is used. + + See :func:`autoconfig` for details and an example. + + """ + if hasattr(distribution, 'get_entry_map'): + entry_points = distribution.get_entry_map('morepath') + else: + entry_points = None + + if entry_points and 'autoimport' in entry_points: + return entry_points['autoimport'].module_name + else: + return distribution.project_name + + def import_package(distribution): """ Takes a pkg_resources distribution and loads the module contained in it, if it matches the rules layed out in :func:`autoconfig`. """ try: - return importlib.import_module(distribution.project_name) + return importlib.import_module(get_module_name(distribution)) except ImportError: raise AutoImportError(distribution.project_name) diff --git a/morepath/tests/test_autosetup.py b/morepath/tests/test_autosetup.py index bba26ed0..56cede8c 100644 --- a/morepath/tests/test_autosetup.py +++ b/morepath/tests/test_autosetup.py @@ -13,11 +13,13 @@ def setup_module(module): def test_import(): import base import sub + import entrypoint from ns import real from ns import real2 + assert sorted(list(morepath_packages()), key=lambda module: module.__name__) == [ - base, real, real2, sub] + base, entrypoint, real, real2, sub] def test_autoconfig(): diff --git a/tox.ini b/tox.ini index 3b584a8f..5cf5f411 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ deps= -e{toxinidir}/fixture_packages/ns -e{toxinidir}/fixture_packages/no_mp_ns -e{toxinidir}/fixture_packages/ns2 + -e{toxinidir}/fixture_packages/entry-point commands=py.test morepath --cov morepath {posargs} [testenv:pep8]