How to move a Python script from one subpackage to another directory/package, maintaining backwards compatibility -


i have shared python code base, , i'm responsible code others depend on. need move modules 1 subpackage directory/package reorganize it. how do in safest way?

if move code, i've got worry others use may not have redirected imports of it. if it's moved , users of code don't change imports, code unexpectedly fail when imports fail.

how can ensure seamless transition? copy code , leave old code in place until imports have been changed? there caveats aware of? if use import * in conjunction __all__? in case have support imports old location indefinitely?

i asked move code 1 subpackage @ work, , approach used didn't seem obvious other developers, i'm documenting here others.

i don't recommend leaving copy @ old place. if have 2 copies of same script, 1 change without other. instead, i recommend following multi-step process.

the first step involves 2 parts can implemented simultaneously if control both locations code.

step one: implement move

  1. first, move file old place new place under version control. use simplified interface cvs version control copy. in other version control systems (like mercurial, subversion, , git), should use mv move file, e.g. git:

    git mv /location/old/script.py /location/new/script.py 

important:

don't forget move unittests too, , move __init__.py's if there's code in old ones need kept. otherwise, make sure commit __init__.py's there if they're not in place or

  1. next, in place of old code, import names new location,

    so in /location/old/script.py:

    from location.new.script import * 

    and leave comment explaining why needed, , commit change version control. if moved __init__.py, make sure commit new empty __init__.py.

there's major caveat here. import * affected __all__. if have __all__ declared, you've got 2 approaches providing missing names. can import them explicitly:

from location.new.script import * # names not in new.script's __all__: location.new.script import foo, bar, baz  

or can delete file , instead import module in __init__.py, , add path sys.modules this:

from location.new import script import sys sys.modules['location.old.script'] = script 

this code initialize package , add module sys.modules in time looked there importer. same way os.path created in python source. people shy away modifying sys.modules, however. in fact, hesitate leave suggestion here, , not if not in python standard library.

these 2 parts can pushed production, , move has been seamlessly implemented. if have no control on users of code, may need remain in place indefinitely backwards compatibility.

optional: delete old script @ head (just @ head, don't push yet!) other developers can see change coming , address change in timely fashion.

step two: implement rereferencing

if can regular expression search of code depends on code, recommend searching code following regular expression:

(import|from).*location\.old.*script 

if on unix (or have cygwin) can regex search it:

grep -ree "(import|from).*location\.old.*script" . 

or ides have regex search.

if have control on code uses it, or have view on others use it, it's straightforward change imports old new, e.g. :

import location.old.script 

to

import location.new.script 

and from

from location.old import script 

to

from location.new import script  

and on.

important:

all of these changes need implemented , released production. if production installations remain without these done, if delete old location, fail.

step three: delete old script in production

this dangerous step. if you've missed users/importers, code fail until import fixes production. may choose postpone step indefinitely, preference done in timely fashion if can prove of changes have been pushed production.

if deleted @ head after making change others see change coming in development, may have less worry about.

still, not delete until can prove no other users referencing old package location in production. if can't prove it, don't delete it.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -