[Python-porting] Port of psycopg2

M.-A. Lemburg mal at egenix.com
Fri Dec 12 14:24:22 CET 2008


On 2008-12-12 00:01, Martin v. Löwis wrote:
>> It looks like I'm going to need to abandon the "one timemachine fits
>> all" idea, and use customised ones: timemachine_21, ..._22_26, ..._3x.
>> That leaves me with one distutils-related problem: it insists on
>> compiling all included files when you do "setup.py install"; I don't
>> want it to compile timemachine_21.py with Python 3.0  -- it would barf
>> on "False = 0" :-) -- and vice versa. But I also don't want to have
>> tarballs/installers that depend on the Python version, if possible.
> 
> I recommend to use build_py_2to3. This will convert your 2.x source
> files into 3.x syntax *at installation time*, and thus should solve
> this problem.

Actually, this happens at build time, but for source distributions
that's usually the same as installation time.

The problem with this approach is that 2to3 is a fast moving target
and relying on the version that comes with Python is likely not going
to work out if you need a more recent version of 2to3 for your code.

For source distributions this either means that you have to ship
2to3 with your code or that you ship already converted code.

BTW: Is it possible to extend 2to3 with your own fixers dynamically,
e.g. to work around this problem ?

Is there an overview of how lib2to3 works somewhere ?

>> Another possibility is writing it as b("foo"), with the timemachine
>> defining an appropriate b function:
>>     b = lambda x: x # 2.x
>>     b = lambda x: x.encode('ascii') # 3.x
>> but the runtime overhead could be painful, especially in 3.x.
> 
> You could use interning if you are worried about the runtime overhead:
> 
> _intern = {}
> def b(s):
>   try:
>     return _intern[s]
>   except KeyError:
>     res = _intern[s] = s.encode("ascii")
>     return res
> 
> This will be still somewhat slower, but not much.
> 
> If you are really worried about performance, you could provide an
> addition 2to3 fixer which unwraps the b() calls when converting to
> 3.x code. However, I'd rather make sure they aren't used in tight loops,
> and just stop worrying.

Adding a fixer is probably the better option. The fixer could then
convert b("abc") directly to b"abc" for Python 3.

That still leaves the function call for Python 2. Could 2to3 also
be used for Python 2 to 2 conversions ?

Looking at the code, there
doesn't appear to be anything specifically targeting Python 3 in
the fixer code, so I guess running "2to3 -f b_function_for_2 xyz.py"
could be used to convert b("abc") to "abc" for Python 2.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Dec 12 2008)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________
2008-12-02: Released mxODBC.Connect 1.0.0      http://python.egenix.com/

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/


More information about the Python-porting mailing list