Importing from builtin library when module with same name exists Importing from builtin library when module with same name exists python python

Importing from builtin library when module with same name exists


Changing the name of your module is not necessary. Rather, you can use absolute_import to change the importing behavior. For example with stem/socket.py I import the socket module as follows:

from __future__ import absolute_importimport socket

This only works with Python 2.5 and above; it's enabling behavior that is the default in Python 3.0 and higher. Pylint will complain about the code but it's perfectly valid.


Actually, solving this is rather easy, but the implementation will always be a bit fragile, because it depends python import mechanism's internals and they are subject to change in future versions.

(the following code shows how to load both local and non-local modules and how they may coexist)

def import_non_local(name, custom_name=None):    import imp, sys    custom_name = custom_name or name    f, pathname, desc = imp.find_module(name, sys.path[1:])    module = imp.load_module(custom_name, f, pathname, desc)    f.close()    return module# Import non-local module, use a custom name to differentiate it from local# This name is only used internally for identifying the module. We decide# the name in the local scope by assigning it to the variable calendar.calendar = import_non_local('calendar','std_calendar')# import local module normally, as calendar_localimport calendar as calendar_localprint calendar.Calendarprint calendar_local

The best solution, if possible, is to avoid naming your modules with the same name as standard-library or built-in module names.


The only way to solve this problem is to hijack the internal import machinery yourself. This is not easy, and fraught with peril. You should avoid the grail shaped beacon at all costs because the peril is too perilous.

Rename your module instead.

If you want to learn how to hijack the internal import machinery, here is where you would go about finding out how to do this:

There are sometimes good reasons to get into this peril. The reason you give is not among them. Rename your module.

If you take the perilous path, one problem you will encounter is that when you load a module it ends up with an 'official name' so that Python can avoid ever having to parse the contents of that module ever again. A mapping of the 'official name' of a module to the module object itself can be found in sys.modules.

This means that if you import calendar in one place, whatever module is imported will be thought of as the module with the official name calendar and all other attempts to import calendar anywhere else, including in other code that's part of the main Python library, will get that calendar.

It might be possible to design a customer importer using the imputil module in Python 2.x that caused modules loaded from certain paths to look up the modules they were importing in something other than sys.modules first or something like that. But that's an extremely hairy thing to be doing, and it won't work in Python 3.x anyway.

There is an extremely ugly and horrible thing you can do that does not involve hooking the import mechanism. This is something you should probably not do, but it will likely work. It turns your calendar module into a hybrid of the system calendar module and your calendar module. Thanks to Boaz Yaniv for the skeleton of the function I use. Put this at the beginning of your calendar.py file:

import sysdef copy_in_standard_module_symbols(name, local_module):    import imp    for i in range(0, 100):        random_name = 'random_name_%d' % (i,)        if random_name not in sys.modules:            break        else:            random_name = None    if random_name is None:        raise RuntimeError("Couldn't manufacture an unused module name.")    f, pathname, desc = imp.find_module(name, sys.path[1:])    module = imp.load_module(random_name, f, pathname, desc)    f.close()    del sys.modules[random_name]    for key in module.__dict__:        if not hasattr(local_module, key):            setattr(local_module, key, getattr(module, key))copy_in_standard_module_symbols('calendar', sys.modules[copy_in_standard_module_symbols.__module__])