[Python-porting] A few questions about the psycopg2 porting to Python 3
Daniele Varrazzo
daniele.varrazzo at gmail.com
Wed Jan 12 18:34:12 CET 2011
On Tue, Jan 11, 2011 at 6:41 PM, Daniele Varrazzo
<daniele.varrazzo at gmail.com> wrote:
> As emerged from the discussion in this ML back in 2008, there is
> somewhere the need for a python function b('literal') that would
> evaluate to 'literal' in Py2 and to b'literal' in py3 (we want to keep
> compatibility with Python 2.4). Currently there is an encode()
> involved in Py3, so it would be great to have the transformation
> b('literal') -> b'literal' performed by 2to3 instead. Looking at the
> other fixers it seems easy, but I haven't found how to register a
> custom fixer for the use of build_py_2to3 in setup.py. Is there any
> reference?
I got in PM the suggestion to use distribute. My answer is that I
would prefer to avoid an extra dependency to solve this problem.
I've tested with some nasting monkeypatching to have the fix_b
injected. This seems working for instance:
diff --git a/setup.py b/setup.py
index 926169c..836d3e6 100644
--- a/setup.py
+++ b/setup.py
@@ -58,6 +58,16 @@ try:
from distutils.command.build_py import build_py_2to3 as build_py
except ImportError:
from distutils.command.build_py import build_py
+else:
+ # Monkeypatch lib2to3 to make it found our custom fixers
+ import lib2to3.refactor
+ from lib2to3.refactor import get_fixers_from_package
+ def get_fixers_from_package_hacked(pkg_name):
+ rv = get_fixers_from_package(pkg_name)
+ return rv + ['fix_b']
+
+ lib2to3.refactor.get_fixers_from_package =
get_fixers_from_package_hacked
+ sys.path.insert(0, 'scripts')
try:
import configparser
Is there a more proper way to use a custom fixer?
As b() fixer I've written the following:
"""Fixer to change b('string') into b'string'."""
# Author: Daniele Varrazzo
import token
from lib2to3 import fixer_base
from lib2to3.pytree import Leaf
class FixB(fixer_base.BaseFix):
PATTERN = """
power< wrapper='b' trailer< '(' arg=[any] ')' > rest=any* >
"""
def transform(self, node, results):
arg = results['arg']
wrapper = results["wrapper"]
if len(arg) == 1 and arg[0].type == token.STRING:
b = Leaf(token.STRING, 'b' + arg[0].value,
prefix=wrapper.prefix)
node.children = [ b ] + results['rest']
It has been obtained by reverse-engineering the other fixers: is it
written as is meant to be?
Thanks
-- Daniele
More information about the Python-porting
mailing list