[Fixed]-Python: How can I override one module in a package with a modified version that lives outside the package?

21👍

Just set the entry in sys.modules before anything else imports it:

import sys
import myreplacement
sys.modules["original"] = myreplacement

Then, when someone does “import original”, they’ll get your version instead.

If you want to replace a submodule, you can do it like this:

import sys
import thepackage
sys.modules["thepackage"].submodule = myreplacement
sys.modules["thepackage.submodule"] = myreplacement

Then “from thepackage import submodule” or “import thepackage.submodule” will give “myreplacement”.

1👍

Perhaps you can make use of the django-values project, which provides a dbsettings app, which …

… allows placeholders for settings to be
defined in Python, while their values
are set by staff using an editor while
the server is up and running. Many
value types are available, and they
each map to a native Python type, so
model methods and other Python code
can access them as standard class
attributes.

Much effort has also been made to
reduce the overhead of this feature,
so that the database is only queried
once during each server restart, and
only updated when the values
themselves are updated.

NOTE: This is not intended as a
replacement for settings.py. This is
designed for values that are expected
to change based on the needs of the
site or its users, so that such
changes don’t require so much as a
restart. settings.py is still the
place to go for settings that will
only vary by project.

One way of looking at it is that
settings.py is for those things that
are required from a technical
perspective (database connections,
installed applications, avaialble
middleware, etc), while dbsettings is
best for those things that are
required due to organizational policy
(quotas, minimum requirements, etc).
That way, programmers maintain the
technical requirements, while
administrators maintain organizational
policy.

The project is by Marty Alchin (who wrote the Pro Django book) and does not require any changes to Django code – it’s a standard Django application.

1👍

import local_django.conf
import django.conf
django.conf.settings = local_django.conf.settings

Modules are singletons. Modules are only initialized/loaded once. You need to do this before importing the modules that use django.conf.settings for them to pick up the change.

Read this link for more info to see if there is a more standard approach with django as the docs specifically recommend against doing it the way I show above for the settings object.
http://docs.djangoproject.com/en/dev/topics/settings/
It should work fine for other objects and modules.

0👍

In this particular case, ‘twould be best to follow the prescribed mechanism for creating your own settings.

In the general case, mucking with imports is guaranteed to confuse your reader (who may be you). The pythonic way to alter class behavior is to sub-class and override.

👤msw

0👍

I was introduced to this about two or three days ago, but one technique of doing this very thing is to use a Python Virtual Environment. This allows you to designate the version of Python you are using, as well as the versions of the modules you want to install, and to be able to swap between different versions and projects relatively easy; it also allows you to install a Python system where you might not otherwise have the permissions needed to install something.

You can learn more about virtualenv from virtualenv info.

There’s also a “virtualenvwrapper” package, that provides tools to more easily swap between environments.

Admittedly, I don’t have much experience with this, and I found this question in an attempt to understand how to override a Python Standard Library with a custom-built version–so it’s not perfect. But I am nonetheless impressed with its ability to specify what you install, down to the version of an individual module!

Leave a comment