From 36fa4bb0ccae60ecdab089d7cb9a3b481e0d5a7f Mon Sep 17 00:00:00 2001 From: ptmcg Date: Wed, 17 Jul 2013 05:38:18 +0000 Subject: Prep release 2.0.1, to be compatible with Python 2.6 and 2.7, as well as Python 3.x versions. Fix bug in <<= operator, added 'return self'. git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@254 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b --- src/CHANGES | 13 +++++++ src/makeRelease.bat | 2 + src/pyparsing.py | 106 ++++++++++++++++++++++++++++++++++++++++++---------- src/setup.py | 6 +++ 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/src/CHANGES b/src/CHANGES index 6a09338..9fe11a4 100644 --- a/src/CHANGES +++ b/src/CHANGES @@ -2,6 +2,19 @@ Change Log ========== +Version 2.0.1 - July, 2013 +-------------------------- +- Removed use of "nonlocal" that prevented using this version of + pyparsing with Python 2.6 and 2.7. This will make it easier to + install for packages that depend on pyparsing, under Python + versions 2.6 and later. Those using older versions of Python + will have to manually install pyparsing 1.5.7. + +- Fixed implementation of <<= operator to return self; reported by + Luc J. Bourhis, with patch fix by Mathias Mamsch - thanks, Luc + and Mathias! + + Version 2.0.0 - November, 2012 ------------------------------ - Rather than release another combined Python 2.x/3.x release diff --git a/src/makeRelease.bat b/src/makeRelease.bat index 891278d..fcdc013 100644 --- a/src/makeRelease.bat +++ b/src/makeRelease.bat @@ -14,6 +14,8 @@ python setup.py sdist --formats=gztar,zip copy/y MANIFEST.in_bdist MANIFEST.in if exist MANIFEST del MANIFEST +python setup.py bdist_wininst --target-version=2.6 --plat-name=win32 +python setup.py bdist_wininst --target-version=2.7 --plat-name=win32 python setup.py bdist_wininst --target-version=3.0 --plat-name=win32 python setup.py bdist_wininst --target-version=3.1 --plat-name=win32 python setup.py bdist_wininst --target-version=3.2 --plat-name=win32 diff --git a/src/pyparsing.py b/src/pyparsing.py index e6d4c38..a6d16d1 100644 --- a/src/pyparsing.py +++ b/src/pyparsing.py @@ -58,8 +58,8 @@ The pyparsing module handles some of the problems that are typically vexing when - embedded comments """ -__version__ = "2.0.0" -__versionTime__ = "17 November 2012 16:18" +__version__ = "2.0.1" +__versionTime__ = "16 July 2013 22:22" __author__ = "Paul McGuire " import string @@ -92,13 +92,57 @@ __all__ = [ 'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation', ] -_MAX_INT = sys.maxsize -basestring = str -unichr = chr -_ustr = str +PY_3 = sys.version.startswith('3') +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + set = lambda s : dict( [(c,0) for c in s] ) + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # The Python docs (http://docs.python.org/ref/customization.html#l2h-182) + # state that "The return value must be a string object". However, does a + # unicode object (being a subclass of basestring) count as a "string + # object"? + # If so, then return a unicode object: + return unicode(obj) + # Else encode it... but how? There are many choices... :) + # Replace unprintables with escape codes? + #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') + # Replace unprintables with question marks? + #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') + # ... + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue -# build list of single arg builtins, that can be used as parse actions -singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] def _xml_escape(data): """Escape &, <, >, ", ', etc. in a string of data.""" @@ -619,26 +663,47 @@ def nullDebugAction(*args): """'Do-nothing' debug action, to suppress debugging output during parsing.""" pass +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible 'decorator to trim function calls to match the arity of the target' -def _trim_arity(func, maxargs=3): +def _trim_arity(func, maxargs=2): if func in singleArgBuiltins: return lambda s,l,t: func(t) - limit = 0 - foundArity = False + limit = [0] + foundArity = [False] def wrapper(*args): - nonlocal limit,foundArity while 1: try: - ret = func(*args[limit:]) - foundArity = True + ret = func(*args[limit[0]:]) + foundArity[0] = True return ret except TypeError: - if limit == maxargs or foundArity: - raise - limit += 1 - continue + if limit[0] <= maxargs and not foundArity[0]: + limit[0] += 1 + continue + raise return wrapper - + class ParserElement(object): """Abstract base level parser element class.""" DEFAULT_WHITE_CHARS = " \n\t\r" @@ -2783,12 +2848,13 @@ class Forward(ParseElementEnhance): self.skipWhitespace = self.expr.skipWhitespace self.saveAsList = self.expr.saveAsList self.ignoreExprs.extend(self.expr.ignoreExprs) - return None + return self def __lshift__(self, other): warnings.warn("Operator '<<' is deprecated, use '<<=' instead", DeprecationWarning,stacklevel=2) self <<= other + return None def leaveWhitespace( self ): self.skipWhitespace = False diff --git a/src/setup.py b/src/setup.py index 076ab6d..dac3ec7 100644 --- a/src/setup.py +++ b/src/setup.py @@ -27,6 +27,12 @@ setup(# Distribution meta-data 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.0', + 'Programming Language :: Python :: 3.1', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', ] ) -- cgit v1.2.1