user580777
user580777

Reputation: 55

Moving code out of __init__.py but keeping backwards compatibility

I'm working on a Python project where a previous developer placed a large portion of the code in the base __init__.py file. I would like to be able to move code out of the file to a new file in a subdirectory.

spam/
    __init__.py
    foobar/
        __init__.py
        eggs.py

So importing the spam module would use the code in foobar/eggs.py.

I would like to keep 100% compatibility because the code that current implements spam can't be changed.

Upvotes: 5

Views: 443

Answers (3)

lunixbochs
lunixbochs

Reputation: 22415

in spam's __init__.py, you can import foobar.egg stuff as local, then anyone importing it from spam will still have access to it

from foobar.eggs import apples_newname as apples_oldname
# or (but import * isn't recommended except for extreme cases)
from foobar.eggs import *

you can also write wrapper functions in in spam __init__.py which simply call the eggs equivalent for extended compatibility in specific cases

import foobar.eggs
def apples_newname(*args, **kwargs):
    foobar.eggs.apples_oldname(*args, **kwargs)

Upvotes: 0

SilverbackNet
SilverbackNet

Reputation: 2074

Adding from foobar import * in spam/__init__.py should be sufficient to get everything in the same scope that it was in before. Alternately, you can redefine everything that you need exported in the same file, such as foo = foobar.newfoo if you have any need to change names or restrict what's exported.

Of course, that leaves the problem of having everything still in the global scope, but you can't do much about that if you need it to look identical externally.

Upvotes: 0

Winston Ewert
Winston Ewert

Reputation: 45059

100% compatibility is probably not possible. A few things (like pickle) really care about where something is defined.

You can get most of the compatibility by importing the classses/functions in the __init__.py file.

Upvotes: 3

Related Questions