Rev 5316: Make decorators importable in Python 3 - needed a helper function which the py library already supplied (Thanks Benjamin Peterson for the pointer). in http://bazaar.launchpad.net/~lifeless/bzr/py3
Robert Collins
robertc at robertcollins.net
Tue Jun 22 20:34:32 BST 2010
At http://bazaar.launchpad.net/~lifeless/bzr/py3
------------------------------------------------------------
revno: 5316
revision-id: robertc at robertcollins.net-20100622193430-atz2o7lrwfilttid
parent: robertc at robertcollins.net-20100622190553-ry6w5n3ji2pex0no
committer: Robert Collins <robertc at robertcollins.net>
branch nick: py3
timestamp: Wed 2010-06-23 07:34:30 +1200
message:
Make decorators importable in Python 3 - needed a helper function which the py library already supplied (Thanks Benjamin Peterson for the pointer).
=== modified file 'NEWS'
--- a/NEWS 2010-06-21 04:16:16 +0000
+++ b/NEWS 2010-06-22 19:34:30 +0000
@@ -163,6 +163,9 @@
* Improved ``bzrlib.urlutils`` to handle lp:foo/bar URLs. (Gordon Tyler)
+* A copy of the ``py`` library ``_builtin`` module has been included for
+ its python version compatibility support. (Robert Collins)
+
Testing
*******
=== modified file 'bzrlib/decorators.py'
--- a/bzrlib/decorators.py 2010-02-17 17:11:16 +0000
+++ b/bzrlib/decorators.py 2010-06-22 19:34:30 +0000
@@ -24,6 +24,7 @@
import sys
+from bzrlib.util.py._builtin import _reraise
from bzrlib import trace
@@ -114,7 +115,7 @@
}
func_def = template % variables
- exec func_def in locals()
+ exec(func_def, locals=locals())
read_locked.__doc__ = unbound.__doc__
read_locked.__name__ = unbound.__name__
@@ -144,7 +145,7 @@
try:
self.unlock()
finally:
- raise exc_info[0], exc_info[1], exc_info[2]
+ _reraise(*exc_info)
else:
self.unlock()
return result
@@ -179,7 +180,7 @@
}
func_def = template % variables
- exec func_def in locals()
+ exec(func_def, locals=locals())
write_locked.__doc__ = unbound.__doc__
write_locked.__name__ = unbound.__name__
@@ -197,7 +198,7 @@
try:
self.unlock()
finally:
- raise exc_info[0], exc_info[1], exc_info[2]
+ _reraise(*exc_info)
else:
self.unlock()
return result
=== modified file 'bzrlib/util/__init__.py'
--- a/bzrlib/util/__init__.py 2005-09-19 06:05:19 +0000
+++ b/bzrlib/util/__init__.py 2010-06-22 19:34:30 +0000
@@ -0,0 +1,1 @@
+"""Helper libraries bzr has included - they have their own licences."""
=== added directory 'bzrlib/util/py'
=== added file 'bzrlib/util/py/__init__.py'
--- a/bzrlib/util/py/__init__.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/util/py/__init__.py 2010-06-22 19:34:30 +0000
@@ -0,0 +1,15 @@
+"""
+py.test and pylib: rapid testing and development utils
+
+this module uses apipkg.py for lazy-loading sub modules
+and classes. The initpkg-dictionary below specifies
+name->value mappings where value can be another namespace
+dictionary or an import path.
+
+(c) Holger Krekel and others, 2004-2010
+
+MIT licenced at the time of inclusion (2010623).
+
+Included in bzrlib for the _builtin module (which supplies python2<->3
+compatibility glue.
+"""
=== added file 'bzrlib/util/py/_builtin.py'
--- a/bzrlib/util/py/_builtin.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/util/py/_builtin.py 2010-06-22 19:34:30 +0000
@@ -0,0 +1,234 @@
+"""
+py.test and pylib: rapid testing and development utils
+
+this module uses apipkg.py for lazy-loading sub modules
+and classes. The initpkg-dictionary below specifies
+name->value mappings where value can be another namespace
+dictionary or an import path.
+
+(c) Holger Krekel and others, 2004-2010
+
+MIT licenced at the time of inclusion (2010623).
+
+Included in bzrlib for the _builtin module (which supplies python2<->3
+compatibility glue.
+
+Copied at revision r1797:5c9a85575454 and not modified beyond this docstring.
+"""
+
+import sys
+
+try:
+ reversed = reversed
+except NameError:
+ def reversed(sequence):
+ """reversed(sequence) -> reverse iterator over values of the sequence
+
+ Return a reverse iterator
+ """
+ if hasattr(sequence, '__reversed__'):
+ return sequence.__reversed__()
+ if not hasattr(sequence, '__getitem__'):
+ raise TypeError("argument to reversed() must be a sequence")
+ return reversed_iterator(sequence)
+
+ class reversed_iterator(object):
+
+ def __init__(self, seq):
+ self.seq = seq
+ self.remaining = len(seq)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ i = self.remaining
+ if i > 0:
+ i -= 1
+ item = self.seq[i]
+ self.remaining = i
+ return item
+ raise StopIteration
+
+ def __length_hint__(self):
+ return self.remaining
+
+try:
+ sorted = sorted
+except NameError:
+ builtin_cmp = cmp # need to use cmp as keyword arg
+
+ def sorted(iterable, cmp=None, key=None, reverse=0):
+ use_cmp = None
+ if key is not None:
+ if cmp is None:
+ def use_cmp(x, y):
+ return builtin_cmp(x[0], y[0])
+ else:
+ def use_cmp(x, y):
+ return cmp(x[0], y[0])
+ l = [(key(element), element) for element in iterable]
+ else:
+ if cmp is not None:
+ use_cmp = cmp
+ l = list(iterable)
+ if use_cmp is not None:
+ l.sort(use_cmp)
+ else:
+ l.sort()
+ if reverse:
+ l.reverse()
+ if key is not None:
+ return [element for (_, element) in l]
+ return l
+
+try:
+ set, frozenset = set, frozenset
+except NameError:
+ from sets import set, frozenset
+
+# pass through
+enumerate = enumerate
+
+try:
+ BaseException = BaseException
+except NameError:
+ BaseException = Exception
+
+try:
+ GeneratorExit = GeneratorExit
+except NameError:
+ class GeneratorExit(Exception):
+ """ This exception is never raised, it is there to make it possible to
+ write code compatible with CPython 2.5 even in lower CPython
+ versions."""
+ pass
+ GeneratorExit.__module__ = 'exceptions'
+
+if sys.version_info >= (3, 0):
+ exec ("print_ = print ; exec_=exec")
+ import builtins
+
+ # some backward compatibility helpers
+ _basestring = str
+ def _totext(obj, encoding=None):
+ if isinstance(obj, bytes):
+ obj = obj.decode(encoding)
+ elif not isinstance(obj, str):
+ obj = str(obj)
+ return obj
+
+ def _isbytes(x):
+ return isinstance(x, bytes)
+ def _istext(x):
+ return isinstance(x, str)
+
+ def _getimself(function):
+ return getattr(function, '__self__', None)
+
+ def _getfuncdict(function):
+ return getattr(function, "__dict__", None)
+
+ def _getcode(function):
+ return getattr(function, "__code__", None)
+
+ def execfile(fn, globs=None, locs=None):
+ if globs is None:
+ back = sys._getframe(1)
+ globs = back.f_globals
+ locs = back.f_locals
+ del back
+ elif locs is None:
+ locs = globs
+ fp = open(fn, "rb")
+ try:
+ source = fp.read()
+ finally:
+ fp.close()
+ co = compile(source, fn, "exec", dont_inherit=True)
+ exec_(co, globs, locs)
+
+ def callable(obj):
+ return hasattr(obj, "__call__")
+
+else:
+ import __builtin__ as builtins
+ _totext = unicode
+ _basestring = basestring
+ execfile = execfile
+ callable = callable
+ def _isbytes(x):
+ return isinstance(x, str)
+ def _istext(x):
+ return isinstance(x, unicode)
+
+ def _getimself(function):
+ return getattr(function, 'im_self', None)
+
+ def _getfuncdict(function):
+ return getattr(function, "__dict__", None)
+
+ def _getcode(function):
+ try:
+ return getattr(function, "__code__")
+ except AttributeError:
+ return getattr(function, "func_code", None)
+
+ def print_(*args, **kwargs):
+ """ minimal backport of py3k print statement. """
+ sep = ' '
+ if 'sep' in kwargs:
+ sep = kwargs.pop('sep')
+ end = '\n'
+ if 'end' in kwargs:
+ end = kwargs.pop('end')
+ file = 'file' in kwargs and kwargs.pop('file') or sys.stdout
+ if kwargs:
+ args = ", ".join([str(x) for x in kwargs])
+ raise TypeError("invalid keyword arguments: %s" % args)
+ at_start = True
+ for x in args:
+ if not at_start:
+ file.write(sep)
+ file.write(str(x))
+ at_start = False
+ file.write(end)
+
+ def exec_(obj, globals=None, locals=None):
+ """ minimal backport of py3k exec statement. """
+ __tracebackhide__ = True
+ if globals is None:
+ frame = sys._getframe(1)
+ globals = frame.f_globals
+ if locals is None:
+ locals = frame.f_locals
+ elif locals is None:
+ locals = globals
+ exec2(obj, globals, locals)
+
+if sys.version_info >= (3,0):
+ exec ("""
+def _reraise(cls, val, tb):
+ __tracebackhide__ = True
+ assert hasattr(val, '__traceback__')
+ raise val
+""")
+else:
+ exec ("""
+def _reraise(cls, val, tb):
+ __tracebackhide__ = True
+ raise cls, val, tb
+def exec2(obj, globals, locals):
+ __tracebackhide__ = True
+ exec obj in globals, locals
+""")
+
+def _tryimport(*names):
+ """ return the first successfully imported module. """
+ assert names
+ for name in names:
+ try:
+ return __import__(name, None, None, '__doc__')
+ except ImportError:
+ excinfo = sys.exc_info()
+ _reraise(*excinfo)
More information about the bazaar-commits
mailing list