What is the proper way to work with shared modules in Python development? What is the proper way to work with shared modules in Python development? python-3.x python-3.x

What is the proper way to work with shared modules in Python development?


If you have common code that you want to share across multiple projects, it may be worth thinking about storing this code in a physically separate project, which is then imported as a dependency into your other projects. This is easily achieved if you host your common code project in github or bitbucket, where you can use pip to install it in any other project. This approach not only helps you to easily share common code across multiple projects, but it also helps protect you from inadvertently creating bad dependencies (i.e. those directed from your common code to your non common code).

The link below provides a good introduction to using pip and virtualenv to manage dependencies, definitely worth a read if you and your team are fairly new to working with python as this is a very common toolchain used for just this kind of problem:

http://dabapps.com/blog/introduction-to-pip-and-virtualenv-python/

And the link below shows you how to pull in dependencies from github using pip:

How to use Python Pip install software, to pull packages from Github?


The must-read-first on this kind of stuff is here:

What is the best project structure for a Python application?

in case you haven't seen it (and follow the link in the second answer).

The key is that each major package be importable as if "." was the top level directory, which means that it will also work correctly when installed in a site-packages. What this implies is that major packages should all be flat within the top directory, as in:

myproject-0.1/    myproject/        framework/    packageA/        sub_package_in_A/            module.py    packageB/        ...

Then both you (within your other packages) and your users can import as:

import myprojectimport packageA.sub_package_in_A.module

etc

Which means you should think hard about @MattAnderson's comment, but if you want it to appear as a separately-distributable package, it needs to be in the top directory.

Note this doesn't stop you (or your users) from doing an:

import packageA.sub_package_in_A as sub_package_in_A

but it does stop you from allowing:

import sub_package_in_A

directly.


...it seems that there is an assumption that all referenced packages are below the top-level project folder, not collateral to it.

That's mainly because the current working directory is the first entry in sys.path by default, which makes it very convenient to import modules and packages below that directory.

If you remove it, you can't even import stuff from the current working directory...

$ touch foo.py$ python>>> import sys>>> del sys.path[0]>>> import fooTraceback (most recent call last):  File "<stdin>", line 1, in <module>ImportError: No module named foo

The thought also occurred to me that perhaps the correct approach is to develop common/framework modules in a separate project, and once tested, deploy those to each developer's environment by installing to the site-packages folder.

It's not really a major issue for development. If you're using version control, and all developers check out the source tree in the same structure, you can easily employ relative path hacks to ensure the code works correctly without having to mess around with environment variables or symbolic links.

However, that also raises questions re distribution.

This is where things can get a bit more complicated, but only if you're planning to release libraries independently of the projects which use them, and/or having multiple project installers share the same libraries. It that's the case, take a look at distutils.

If not, you can simply employ the same relative path hacks used in development to ensure you project works "out of the box".