Search code examples
pythonpython-3.xpackagingsetuptoolssetup.py

Include a directory with setuptools installation


I've made a plugin-based program that loads plugins from different directories, one of which being the directory where the module resides (for convenience of running in place inside the source repository for testing).

I'd like the plugins currently in the source repository to be installed with the module so that they will be loaded by default on any installation. This would preferably be stored inside the egg that setup() creates.

Currently the important parts of the source repository are as follows:

/path/to/repo/
    plugins/
        example.py
    myprog.py # the module
    myprog    # the script
    setup.py

setup.py looks something like this:

from setuptools import setup

setup(
    name = 'myprog',
    version = '1.0',
    scripts = ['myprog'],
    py_modules = ['myprog'],

    package_data = {
        '': ['plugins/']
    }
)

However, the plugins directory is not included with installation in any way.

How can I include it so that the line

os.path.join(os.path.dirname(os.path.realpath(__file__)), 'plugins')

will properly find that directory after running python3 setup.py install?


Solution

  • Your setup would break things by making a global plugins module that everyone would be able to import, or that everyone would import by mistake. Don’t do that. Instead, do this:

    • Make your myprog.py file into a package. The easiest way: mkdir myprog; mv myprog.py myprog/__init__.py
    • Then, you can move your plugins into a subpackage. touch plugins/__init__.py; mv plugins myprog/
    • With subpackages, you don’t have to use package data at all.
    • To access your plugins, just do import myprog.plugins.foo for a plugin named foo.py.
    • Also: don’t touch __file__, use pkg_resources instead.
    • Bonus points: use entry points for your script.