En Thu, 26 Mar 2009 15:23:50 -0300, zopyxfil...@googlemail.com <zopyxfil...@googlemail.com> escribió:
For a while a maintained a Python package 'foo' with a number of modules (including a nested structure of module). Now the package moved into a namespace package 'a.b.foo'. What is the way to approach making old code work with the new package in order that imports like import foo.bar.xxx or from foo.bar import xxx remain working for existing code.
A quick and dirty solution is to have a foo package with an __init__.py that imports *every* single name in the old package, from the new one, and puts it in sys.modules under the old name. C:\temp>tree /f a C:\TEMP\A │ __init__.py │ └───b │ __init__.py │ └───foo one.py three.py two.py __init__.py C:\temp>tree /f foo C:\TEMP\FOO __init__.py C:\temp>type foo\__init__.py import warnings warnings.warn("The 'foo' package is obsolete; use 'a.b.foo' instead", DeprecationWarning, 2) import sys from a.b import foo from a.b.foo import one, two sys.modules['foo.one'] = one sys.modules['foo.two'] = two # very last line! sys.modules['foo'] = foo # now *this* module is gone C:\temp>type a\b\foo\one.py print "This is one.py", __file__, __name__ C:\temp>type a\b\foo\two.py print "This is two.py", __file__, __name__ C:\temp>type a\b\foo\three.py print "This is three.py", __file__, __name__ All other __init__.py files are empty. Now, you can import foo and its contents under the old and new names: py> import foo __main__:1: DeprecationWarning: The 'foo' package is obsolete; use 'a.b.foo' ins tead This is one.py a\b\foo\one.pyc a.b.foo.one This is two.py a\b\foo\two.pyc a.b.foo.two py> import foo.one py> import a.b.foo.one py> a.b.foo.one <module 'a.b.foo.one' from 'a\b\foo\one.pyc'> py> foo.one <module 'a.b.foo.one' from 'a\b\foo\one.pyc'> py> foo.one is a.b.foo.one True py> import foo.two py> import a.b.foo.two Note that one.py and two.py are imported only once. *BUT* notice what happens when you import three.py, that was NOT included in foo\__init__.py: py> import foo.three This is three.py a\b\foo\three.pyc foo.three py> import a.b.foo.three This is three.py a\b\foo\three.pyc a.b.foo.three That module was imported *twice*. So it's important to pre-import (inside foo\__init__.py) *every* name that was present in the old foo package. If this is not feasible (there are many names, or loading all of them would be too slow, or whatever) you may implement a "lazy" importer. See __init__.py in the email package for an example. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list