"as" keyword woes

J. Cliff Dyer jcd at sdf.lonestar.org
Mon Dec 8 21:07:22 CET 2008


On Wed, 2008-12-03 at 21:42 -0800, Warren DeLano wrote:
> Anyway, it seems obvious that the right decision for our customers (or
> more importantly, for their countless lines of autogenerated-Python
> log,
> state, and code files from the past decade) is to stick with C/Python
> 2.5.x for the time being and plan to make the jump to a
> threads-capable
> and hopefully backwards-compatible Python implementation as soon as
> possible (IronPython perhaps?).   That seems like a sensible path
> around
> the breakage and enduring limitations of C/Python 2.6 or 3.

All that broken code does sound like a hassle.  However, I think the
workaround would be a fairly simple refactor:

1) make 'as_type' (or some other equivalent name like 'as_') a synonym
for 'as':

>>> class Foo(object):
...     def as(self):
...         pass
...     as_type = as

2) Change all references in Foo in your code base to use 'as_type'.

3) Extract class Foo to a separate file (_as_import_file.py), and
replace it in the original file with:

>>> from _as_import_file import Foo

(Note that no other files should import directly from
_as_import_file.py)

4) Now write a second file (_as_import_file_2_6.py), which defines
defines Foo without as, just using as_type:

>>> class Foo(object):
...     def as_type(self):
...         pass

5) Change your import to select the appropriate import:

>>> try:
...     from _as_import_file import Foo
... except SyntaxError:
...     from _as_import_file_2_6 import Foo

6) Now your code base is fully functional with both 2.5 and 2.6.
Everything functions exactly the same as it did before on 2.5, except
now Foo.as_type() (or Foo.as_()) works as a synonym for Foo.as().  Tell
your customers that they can upgrade to 2.6 if they update their own
uses of as_type.  In the meantime, their code is still functional on
2.5.  

By extracting Foo to _as_import_file, you only have to maintain one
class in parallel.  Better yet, have _as_import_file.Foo subclass
_as_import_file_2_6.Foo, like so:

_as_import_file_2_6.py
>>> class Foo(object):
...     def as_type(self,type):
...         pass

_as_import_file.py
>>> import _as_import_file_2_6
>>> class Foo(_as_import_file.Foo):
...     as = _as_import_file.Foo.as_type

That three line file, along with the four line conditional import are
all you need for each import, and best of all, it's completely hidden
from your users, until they want to migrate to python 2.6, and then all
they have to do is change all references to Foo.as to point to
Foo.as_type.  But by observing step 1 above, they can do that at
leisure, without fearing to break their code.

I hope that's a helpful workaround for you and your users.

Cheers,
Cliff





More information about the Python-list mailing list