Hello community,

here is the log from the commit of package python-py for openSUSE:Factory 
checked in at 2014-01-07 13:59:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-py (Old)
 and      /work/SRC/openSUSE:Factory/.python-py.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-py"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-py/python-py.changes      2013-12-09 
17:01:35.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-py.new/python-py.changes 2014-01-07 
13:59:30.000000000 +0100
@@ -1,0 +2,15 @@
+Fri Jan  3 08:30:42 UTC 2014 - mvysko...@suse.com
+
+- update to 1.4.19:
+  - merge in apipkg fixes
+  - some micro-optimizations in py/_code/code.py for speeding
+    up pytest runs.  Thanks Alex Gaynor for initiative.
+  - check PY_COLORS=1 or PY_COLORS=0 to force coloring/not-coloring
+    for py.io.TerminalWriter() independently from capabilities
+    of the output file.  Thanks Marc Abramowitz for the PR.
+  - some fixes to unicode handling in assertion handling.
+    Thanks for the PR to Floris Bruynooghe.  (This helps
+    to fix pytest issue 319).
+  - depend on setuptools presence, remove distribute_setup
+
+-------------------------------------------------------------------

Old:
----
  py-1.4.18.tar.gz

New:
----
  py-1.4.19.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-py.spec ++++++
--- /var/tmp/diff_new_pack.6eya8i/_old  2014-01-07 13:59:30.000000000 +0100
+++ /var/tmp/diff_new_pack.6eya8i/_new  2014-01-07 13:59:30.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-py
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-py
-Version:        1.4.18
+Version:        1.4.19
 Release:        0
 Summary:        Library with cross-python path, ini-parsing, io, code, log 
facilities
 License:        MIT

++++++ py-1.4.18.tar.gz -> py-1.4.19.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/CHANGELOG new/py-1.4.19/CHANGELOG
--- old/py-1.4.18/CHANGELOG     2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/CHANGELOG     2013-12-12 12:07:15.000000000 +0100
@@ -1,3 +1,21 @@
+Changes between 1.4.18 and 1.4.19
+==================================================
+
+- merge in apipkg fixes
+
+- some micro-optimizations in py/_code/code.py for speeding
+  up pytest runs.  Thanks Alex Gaynor for initiative.
+
+- check PY_COLORS=1 or PY_COLORS=0 to force coloring/not-coloring
+  for py.io.TerminalWriter() independently from capabilities
+  of the output file.  Thanks Marc Abramowitz for the PR.
+
+- some fixes to unicode handling in assertion handling.
+  Thanks for the PR to Floris Bruynooghe.  (This helps
+  to fix pytest issue 319).
+
+- depend on setuptools presence, remove distribute_setup
+
 Changes between 1.4.17 and 1.4.18
 ==================================================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/PKG-INFO new/py-1.4.19/PKG-INFO
--- old/py-1.4.18/PKG-INFO      2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/PKG-INFO      2013-12-12 12:07:15.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py
-Version: 1.4.18
+Version: 1.4.19
 Summary: library with cross-python path, ini-parsing, io, code, log facilities
 Home-page: http://pylib.readthedocs.org/
 Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/distribute_setup.py 
new/py-1.4.19/distribute_setup.py
--- old/py-1.4.18/distribute_setup.py   2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/distribute_setup.py   1970-01-01 01:00:00.000000000 +0100
@@ -1,497 +0,0 @@
-#!python
-"""Bootstrap distribute installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
-    from distribute_setup import use_setuptools
-    use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import os
-import sys
-import time
-import fnmatch
-import tempfile
-import tarfile
-from distutils import log
-
-try:
-    from site import USER_SITE
-except ImportError:
-    USER_SITE = None
-
-try:
-    import subprocess
-
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        return subprocess.call(args) == 0
-
-except ImportError:
-    # will be used for python 2.3
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        # quoting arguments if windows
-        if sys.platform == 'win32':
-            def quote(arg):
-                if ' ' in arg:
-                    return '"%s"' % arg
-                return arg
-            args = [quote(arg) for arg in args]
-        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
-
-DEFAULT_VERSION = "0.6.27"
-DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/";
-SETUPTOOLS_FAKED_VERSION = "0.6c11"
-
-SETUPTOOLS_PKG_INFO = """\
-Metadata-Version: 1.0
-Name: setuptools
-Version: %s
-Summary: xxxx
-Home-page: xxx
-Author: xxx
-Author-email: xxx
-License: xxx
-Description: xxx
-""" % SETUPTOOLS_FAKED_VERSION
-
-
-def _install(tarball, install_args=()):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # installing
-        log.warn('Installing Distribute')
-        if not _python_cmd('setup.py', 'install', *install_args):
-            log.warn('Something went wrong during the installation.')
-            log.warn('See the error message above.')
-    finally:
-        os.chdir(old_wd)
-
-
-def _build_egg(egg, tarball, to_dir):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # building an egg
-        log.warn('Building a Distribute egg in %s', to_dir)
-        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
-
-    finally:
-        os.chdir(old_wd)
-    # returning the result
-    log.warn(egg)
-    if not os.path.exists(egg):
-        raise IOError('Could not build the egg.')
-
-
-def _do_download(version, download_base, to_dir, download_delay):
-    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
-                       % (version, sys.version_info[0], sys.version_info[1]))
-    if not os.path.exists(egg):
-        tarball = download_setuptools(version, download_base,
-                                      to_dir, download_delay)
-        _build_egg(egg, tarball, to_dir)
-    sys.path.insert(0, egg)
-    import setuptools
-    setuptools.bootstrap_install_from = egg
-
-
-def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
-                   to_dir=os.curdir, download_delay=15, no_fake=True):
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    was_imported = 'pkg_resources' in sys.modules or \
-        'setuptools' in sys.modules
-    try:
-        try:
-            import pkg_resources
-            if not hasattr(pkg_resources, '_distribute'):
-                if not no_fake:
-                    _fake_setuptools()
-                raise ImportError
-        except ImportError:
-            return _do_download(version, download_base, to_dir, download_delay)
-        try:
-            pkg_resources.require("distribute>="+version)
-            return
-        except pkg_resources.VersionConflict:
-            e = sys.exc_info()[1]
-            if was_imported:
-                sys.stderr.write(
-                "The required version of distribute (>=%s) is not available,\n"
-                "and can't be installed while this script is running. Please\n"
-                "install a more recent version first, using\n"
-                "'easy_install -U distribute'."
-                "\n\n(Currently using %r)\n" % (version, e.args[0]))
-                sys.exit(2)
-            else:
-                del pkg_resources, sys.modules['pkg_resources']    # reload ok
-                return _do_download(version, download_base, to_dir,
-                                    download_delay)
-        except pkg_resources.DistributionNotFound:
-            return _do_download(version, download_base, to_dir,
-                                download_delay)
-    finally:
-        if not no_fake:
-            _create_fake_setuptools_pkg_info(to_dir)
-
-def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
-                        to_dir=os.curdir, delay=15):
-    """Download distribute from a specified location and return its filename
-
-    `version` should be a valid distribute version number that is available
-    as an egg for download under the `download_base` URL (which should end
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
-    `delay` is the number of seconds to pause before an actual download
-    attempt.
-    """
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    try:
-        from urllib.request import urlopen
-    except ImportError:
-        from urllib2 import urlopen
-    tgz_name = "distribute-%s.tar.gz" % version
-    url = download_base + tgz_name
-    saveto = os.path.join(to_dir, tgz_name)
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            log.warn("Downloading %s", url)
-            src = urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = src.read()
-            dst = open(saveto, "wb")
-            dst.write(data)
-        finally:
-            if src:
-                src.close()
-            if dst:
-                dst.close()
-    return os.path.realpath(saveto)
-
-def _no_sandbox(function):
-    def __no_sandbox(*args, **kw):
-        try:
-            from setuptools.sandbox import DirectorySandbox
-            if not hasattr(DirectorySandbox, '_old'):
-                def violation(*args):
-                    pass
-                DirectorySandbox._old = DirectorySandbox._violation
-                DirectorySandbox._violation = violation
-                patched = True
-            else:
-                patched = False
-        except ImportError:
-            patched = False
-
-        try:
-            return function(*args, **kw)
-        finally:
-            if patched:
-                DirectorySandbox._violation = DirectorySandbox._old
-                del DirectorySandbox._old
-
-    return __no_sandbox
-
-def _patch_file(path, content):
-    """Will backup the file then patch it"""
-    existing_content = open(path).read()
-    if existing_content == content:
-        # already patched
-        log.warn('Already patched.')
-        return False
-    log.warn('Patching...')
-    _rename_path(path)
-    f = open(path, 'w')
-    try:
-        f.write(content)
-    finally:
-        f.close()
-    return True
-
-_patch_file = _no_sandbox(_patch_file)
-
-def _same_content(path, content):
-    return open(path).read() == content
-
-def _rename_path(path):
-    new_name = path + '.OLD.%s' % time.time()
-    log.warn('Renaming %s into %s', path, new_name)
-    os.rename(path, new_name)
-    return new_name
-
-def _remove_flat_installation(placeholder):
-    if not os.path.isdir(placeholder):
-        log.warn('Unkown installation at %s', placeholder)
-        return False
-    found = False
-    for file in os.listdir(placeholder):
-        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
-            found = True
-            break
-    if not found:
-        log.warn('Could not locate setuptools*.egg-info')
-        return
-
-    log.warn('Removing elements out of the way...')
-    pkg_info = os.path.join(placeholder, file)
-    if os.path.isdir(pkg_info):
-        patched = _patch_egg_dir(pkg_info)
-    else:
-        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
-
-    if not patched:
-        log.warn('%s already patched.', pkg_info)
-        return False
-    # now let's move the files out of the way
-    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
-        element = os.path.join(placeholder, element)
-        if os.path.exists(element):
-            _rename_path(element)
-        else:
-            log.warn('Could not find the %s element of the '
-                     'Setuptools distribution', element)
-    return True
-
-_remove_flat_installation = _no_sandbox(_remove_flat_installation)
-
-def _after_install(dist):
-    log.warn('After install bootstrap.')
-    placeholder = dist.get_command_obj('install').install_purelib
-    _create_fake_setuptools_pkg_info(placeholder)
-
-def _create_fake_setuptools_pkg_info(placeholder):
-    if not placeholder or not os.path.exists(placeholder):
-        log.warn('Could not find the install location')
-        return
-    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
-    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
-            (SETUPTOOLS_FAKED_VERSION, pyver)
-    pkg_info = os.path.join(placeholder, setuptools_file)
-    if os.path.exists(pkg_info):
-        log.warn('%s already exists', pkg_info)
-        return
-
-    if not os.access(pkg_info, os.W_OK):
-        log.warn("Don't have permissions to write %s, skipping", pkg_info)
-
-    log.warn('Creating %s', pkg_info)
-    f = open(pkg_info, 'w')
-    try:
-        f.write(SETUPTOOLS_PKG_INFO)
-    finally:
-        f.close()
-
-    pth_file = os.path.join(placeholder, 'setuptools.pth')
-    log.warn('Creating %s', pth_file)
-    f = open(pth_file, 'w')
-    try:
-        f.write(os.path.join(os.curdir, setuptools_file))
-    finally:
-        f.close()
-
-_create_fake_setuptools_pkg_info = 
_no_sandbox(_create_fake_setuptools_pkg_info)
-
-def _patch_egg_dir(path):
-    # let's check if it's already patched
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
-    if os.path.exists(pkg_info):
-        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
-            log.warn('%s already patched.', pkg_info)
-            return False
-    _rename_path(path)
-    os.mkdir(path)
-    os.mkdir(os.path.join(path, 'EGG-INFO'))
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
-    f = open(pkg_info, 'w')
-    try:
-        f.write(SETUPTOOLS_PKG_INFO)
-    finally:
-        f.close()
-    return True
-
-_patch_egg_dir = _no_sandbox(_patch_egg_dir)
-
-def _before_install():
-    log.warn('Before install bootstrap.')
-    _fake_setuptools()
-
-
-def _under_prefix(location):
-    if 'install' not in sys.argv:
-        return True
-    args = sys.argv[sys.argv.index('install')+1:]
-    for index, arg in enumerate(args):
-        for option in ('--root', '--prefix'):
-            if arg.startswith('%s=' % option):
-                top_dir = arg.split('root=')[-1]
-                return location.startswith(top_dir)
-            elif arg == option:
-                if len(args) > index:
-                    top_dir = args[index+1]
-                    return location.startswith(top_dir)
-        if arg == '--user' and USER_SITE is not None:
-            return location.startswith(USER_SITE)
-    return True
-
-
-def _fake_setuptools():
-    log.warn('Scanning installed packages')
-    try:
-        import pkg_resources
-    except ImportError:
-        # we're cool
-        log.warn('Setuptools or Distribute does not seem to be installed.')
-        return
-    ws = pkg_resources.working_set
-    try:
-        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
-                                  replacement=False))
-    except TypeError:
-        # old distribute API
-        setuptools_dist = 
ws.find(pkg_resources.Requirement.parse('setuptools'))
-
-    if setuptools_dist is None:
-        log.warn('No setuptools distribution found')
-        return
-    # detecting if it was already faked
-    setuptools_location = setuptools_dist.location
-    log.warn('Setuptools installation detected at %s', setuptools_location)
-
-    # if --root or --preix was provided, and if
-    # setuptools is not located in them, we don't patch it
-    if not _under_prefix(setuptools_location):
-        log.warn('Not patching, --root or --prefix is installing Distribute'
-                 ' in another location')
-        return
-
-    # let's see if its an egg
-    if not setuptools_location.endswith('.egg'):
-        log.warn('Non-egg installation')
-        res = _remove_flat_installation(setuptools_location)
-        if not res:
-            return
-    else:
-        log.warn('Egg installation')
-        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
-        if (os.path.exists(pkg_info) and
-            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
-            log.warn('Already patched.')
-            return
-        log.warn('Patching...')
-        # let's create a fake egg replacing setuptools one
-        res = _patch_egg_dir(setuptools_location)
-        if not res:
-            return
-    log.warn('Patched done.')
-    _relaunch()
-
-
-def _relaunch():
-    log.warn('Relaunching...')
-    # we have to relaunch the process
-    # pip marker to avoid a relaunch bug
-    if sys.argv[:3] == ['-c', 'install', 
'--single-version-externally-managed']:
-        sys.argv[0] = 'setup.py'
-    args = [sys.executable] + sys.argv
-    sys.exit(subprocess.call(args))
-
-
-def _extractall(self, path=".", members=None):
-    """Extract all members from the archive to the current working
-       directory and set owner, modification time and permissions on
-       directories afterwards. `path' specifies a different directory
-       to extract to. `members' is optional and must be a subset of the
-       list returned by getmembers().
-    """
-    import copy
-    import operator
-    from tarfile import ExtractError
-    directories = []
-
-    if members is None:
-        members = self
-
-    for tarinfo in members:
-        if tarinfo.isdir():
-            # Extract directories with a safe mode.
-            directories.append(tarinfo)
-            tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 448 # decimal for oct 0700
-        self.extract(tarinfo, path)
-
-    # Reverse sort directories.
-    if sys.version_info < (2, 4):
-        def sorter(dir1, dir2):
-            return cmp(dir1.name, dir2.name)
-        directories.sort(sorter)
-        directories.reverse()
-    else:
-        directories.sort(key=operator.attrgetter('name'), reverse=True)
-
-    # Set correct owner, mtime and filemode on directories.
-    for tarinfo in directories:
-        dirpath = os.path.join(path, tarinfo.name)
-        try:
-            self.chown(tarinfo, dirpath)
-            self.utime(tarinfo, dirpath)
-            self.chmod(tarinfo, dirpath)
-        except ExtractError:
-            e = sys.exc_info()[1]
-            if self.errorlevel > 1:
-                raise
-            else:
-                self._dbg(1, "tarfile: %s" % e)
-
-def _build_install_args(argv):
-    install_args = []
-    user_install = '--user' in argv
-    if user_install and sys.version_info < (2,6):
-        log.warn("--user requires Python 2.6 or later")
-        raise SystemExit(1)
-    if user_install:
-        install_args.append('--user')
-    return install_args
-
-def main(argv, version=DEFAULT_VERSION):
-    """Install or upgrade setuptools and EasyInstall"""
-    tarball = download_setuptools()
-    _install(tarball, _build_install_args(argv))
-
-
-if __name__ == '__main__':
-    main(sys.argv[1:])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/__init__.py new/py-1.4.19/py/__init__.py
--- old/py-1.4.18/py/__init__.py        2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py/__init__.py        2013-12-12 12:07:15.000000000 +0100
@@ -8,7 +8,7 @@
 
 (c) Holger Krekel and others, 2004-2013
 """
-__version__ = '1.4.18'
+__version__ = '1.4.19'
 
 from py import _apipkg
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/_apipkg.py new/py-1.4.19/py/_apipkg.py
--- old/py-1.4.18/py/_apipkg.py 2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py/_apipkg.py 2013-12-12 12:07:15.000000000 +0100
@@ -9,7 +9,17 @@
 import sys
 from types import ModuleType
 
-__version__ = '1.2'
+__version__ = '1.3.dev'
+
+def _py_abspath(path):
+    """
+    special version of abspath
+    that will leave paths from jython jars alone
+    """
+    if path.startswith('__pyclasspath__'):
+        return path
+    else:
+        return os.path.abspath(path)
 
 def initpkg(pkgname, exportdefs, attr=dict()):
     """ initialize given package from the export definitions. """
@@ -17,14 +27,14 @@
     d = {}
     f = getattr(oldmod, '__file__', None)
     if f:
-        f = os.path.abspath(f)
+        f = _py_abspath(f)
     d['__file__'] = f
     if hasattr(oldmod, '__version__'):
         d['__version__'] = oldmod.__version__
     if hasattr(oldmod, '__loader__'):
         d['__loader__'] = oldmod.__loader__
     if hasattr(oldmod, '__path__'):
-        d['__path__'] = [os.path.abspath(p) for p in oldmod.__path__]
+        d['__path__'] = [_py_abspath(p) for p in oldmod.__path__]
     if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None):
         d['__doc__'] = oldmod.__doc__
     d.update(attr)
@@ -164,4 +174,4 @@
         def __delattr__(self, name):
             delattr(getmod(), name)
 
-    return AliasModule(modname)
+    return AliasModule(str(modname))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/_code/code.py 
new/py-1.4.19/py/_code/code.py
--- old/py-1.4.18/py/_code/code.py      2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py/_code/code.py      2013-12-12 12:07:15.000000000 +0100
@@ -9,14 +9,15 @@
 class Code(object):
     """ wrapper around Python code objects """
     def __init__(self, rawcode):
-        rawcode = py.code.getrawcode(rawcode)
-        self.raw = rawcode
+        if not hasattr(rawcode, "co_filename"):
+            rawcode = py.code.getrawcode(rawcode)
         try:
             self.filename = rawcode.co_filename
             self.firstlineno = rawcode.co_firstlineno - 1
             self.name = rawcode.co_name
         except AttributeError:
             raise TypeError("not a code object: %r" %(rawcode,))
+        self.raw = rawcode
 
     def __eq__(self, other):
         return self.raw == other.raw
@@ -24,25 +25,25 @@
     def __ne__(self, other):
         return not self == other
 
+    @property
     def path(self):
-        """ return a path object pointing to source code"""
+        """ return a path object pointing to source code (note that it
+        might not point to an actually existing file). """
         p = py.path.local(self.raw.co_filename)
+        # maybe don't try this checking
         if not p.check():
             # XXX maybe try harder like the weird logic
             # in the standard lib [linecache.updatecache] does?
             p = self.raw.co_filename
         return p
 
-    path = property(path, None, None, "path of this code object")
-
+    @property
     def fullsource(self):
         """ return a py.code.Source object for the full source file of the code
         """
         from py._code import source
         full, _ = source.findsource(self.raw)
         return full
-    fullsource = property(fullsource, None, None,
-                          "full source containing this code object")
 
     def source(self):
         """ return a py.code.Source object for the code object's source only
@@ -69,18 +70,18 @@
     in which expressions can be evaluated."""
 
     def __init__(self, frame):
-        self.code = py.code.Code(frame.f_code)
         self.lineno = frame.f_lineno - 1
         self.f_globals = frame.f_globals
         self.f_locals = frame.f_locals
         self.raw = frame
+        self.code = py.code.Code(frame.f_code)
 
+    @property
     def statement(self):
+        """ statement this frame is at """
         if self.code.fullsource is None:
             return py.code.Source("")
         return self.code.fullsource.getstatement(self.lineno)
-    statement = property(statement, None, None,
-                         "statement this frame is at")
 
     def eval(self, code, **vars):
         """ evaluate 'code' in the frame
@@ -131,26 +132,29 @@
 
     def __init__(self, rawentry):
         self._rawentry = rawentry
-        self.frame = py.code.Frame(rawentry.tb_frame)
-        # Ugh. 2.4 and 2.5 differs here when encountering
-        # multi-line statements. Not sure about the solution, but
-        # should be portable
         self.lineno = rawentry.tb_lineno - 1
-        self.relline = self.lineno - self.frame.code.firstlineno
+
+    @property
+    def frame(self):
+        return py.code.Frame(self._rawentry.tb_frame)
+
+    @property
+    def relline(self):
+        return self.lineno - self.frame.code.firstlineno
 
     def __repr__(self):
         return "<TracebackEntry %s:%d>" %(self.frame.code.path, self.lineno+1)
 
+    @property
     def statement(self):
-        """ return a py.code.Source object for the current statement """
+        """ py.code.Source object for the current statement """
         source = self.frame.code.fullsource
         return source.getstatement(self.lineno)
-    statement = property(statement, None, None,
-                         "statement of this traceback entry.")
 
+    @property
     def path(self):
+        """ path to the source code """
         return self.frame.code.path
-    path = property(path, None, None, "path to the full source code")
 
     def getlocals(self):
         return self.frame.f_locals
@@ -204,11 +208,12 @@
             mostly for internal use
         """
         try:
-            return self.frame.eval("__tracebackhide__")
-        except py.builtin._sysex:
-            raise
-        except:
-            return False
+            return self.frame.f_locals['__tracebackhide__']
+        except KeyError:
+            try:
+                return self.frame.f_globals['__tracebackhide__']
+            except KeyError:
+                return False
 
     def __str__(self):
         try:
@@ -287,10 +292,11 @@
         """ return last non-hidden traceback entry that lead
         to the exception of a traceback.
         """
-        tb = self.filter()
-        if not tb:
-            tb = self
-        return tb[-1]
+        for i in range(-1, -len(self)-1, -1):
+            entry = self[i]
+            if not entry.ishidden():
+                return entry
+        return self[-1]
 
     def recursionindex(self):
         """ return the index of the frame/TracebackItem where recursion
@@ -336,7 +342,7 @@
                 if exprinfo and exprinfo.startswith('assert '):
                     self._striptext = 'AssertionError: '
         self._excinfo = tup
-        self.type, self.value, tb = self._excinfo
+        self.type, self.value, tb = tup
         self.typename = self.type.__name__
         self.traceback = py.code.Traceback(tb)
 
@@ -351,7 +357,7 @@
             the exception representation is returned (so 'AssertionError: ' is
             removed from the beginning)
         """
-        lines = py.std.traceback.format_exception_only(self.type, self.value)
+        lines = self._format_exception_only(self.type, self.value)
         text = ''.join(lines)
         text = text.rstrip()
         if tryshort:
@@ -359,6 +365,17 @@
                 text = text[len(self._striptext):]
         return text
 
+    def _format_exception_only(self, etype, value):
+        """Format the exception part of a traceback
+
+        Since traceback.format_exception_only() destroys unicode on
+        python 2 we handle plain AsssertionErrors separately here.
+        """
+        if isinstance(value, AssertionError) and hasattr(value, 'msg'):
+            return ['AssertionError: ' + value.msg]
+        else:
+            return py.std.traceback.format_exception_only(etype, value)
+
     def errisinstance(self, exc):
         """ return True if the exception is an instance of exc """
         return isinstance(self.value, exc)
@@ -366,9 +383,8 @@
     def _getreprcrash(self):
         exconly = self.exconly(tryshort=True)
         entry = self.traceback.getcrashentry()
-        path, lineno = entry.path, entry.lineno
-        reprcrash = ReprFileLocation(path, lineno+1, exconly)
-        return reprcrash
+        path, lineno = entry.frame.code.raw.co_filename, entry.lineno
+        return ReprFileLocation(path, lineno+1, exconly)
 
     def getrepr(self, showlocals=False, style="long",
             abspath=False, tbfilter=True, funcargs=False):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/_io/saferepr.py 
new/py-1.4.19/py/_io/saferepr.py
--- old/py-1.4.18/py/_io/saferepr.py    2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py/_io/saferepr.py    2013-12-12 12:07:15.000000000 +0100
@@ -12,6 +12,23 @@
     def repr(self, x):
         return self._callhelper(reprlib.Repr.repr, self, x)
 
+    def repr_unicode(self, x, level):
+        # Strictly speaking wrong on narrow builds
+        def repr(u):
+            if "'" not in u:
+                return py.builtin._totext("'%s'") % u
+            elif '"' not in u:
+                return py.builtin._totext('"%s"') % u
+            else:
+                return py.builtin._totext("'%s'") % u.replace("'", r"\'")
+        s = repr(x[:self.maxstring])
+        if len(s) > self.maxstring:
+            i = max(0, (self.maxstring-3)//2)
+            j = max(0, self.maxstring-3-i)
+            s = repr(x[:i] + x[len(x)-j:])
+            s = s[:i] + '...' + s[len(s)-j:]
+        return s
+
     def repr_instance(self, x, level):
         return self._callhelper(builtin_repr, x)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/_io/terminalwriter.py 
new/py-1.4.19/py/_io/terminalwriter.py
--- old/py-1.4.18/py/_io/terminalwriter.py      2013-10-29 11:34:25.000000000 
+0100
+++ new/py-1.4.19/py/_io/terminalwriter.py      2013-12-12 12:07:15.000000000 
+0100
@@ -101,6 +101,10 @@
         file.flush()
 
 def should_do_markup(file):
+    if os.environ.get('PY_COLORS') == '1':
+        return True
+    if os.environ.get('PY_COLORS') == '0':
+        return False
     return hasattr(file, 'isatty') and file.isatty() \
            and os.environ.get('TERM') != 'dumb' \
            and not (sys.platform.startswith('java') and os._name == 'nt')
@@ -184,12 +188,7 @@
                 markupmsg = self.markup(msg, **kw)
             else:
                 markupmsg = msg
-            try:
-                self._file.write(markupmsg)
-            except UnicodeEncodeError:
-                msg = msg.encode("unicode-escape").decode("ascii")
-                self._file.write(msg)
-            self._file.flush()
+            write_out(self._file, markupmsg)
 
     def line(self, s='', **kw):
         self.write(s, **kw)
@@ -235,12 +234,7 @@
                     attr |= oldcolors & 0x0007
 
                 SetConsoleTextAttribute(handle, attr)
-            try:
-                self._file.write(msg)
-            except UnicodeEncodeError:
-                msg = msg.encode("unicode-escape").decode("ascii")
-                self._file.write(msg)
-            self._file.flush()
+            write_out(self._file, msg)
             if oldcolors:
                 SetConsoleTextAttribute(handle, oldcolors)
 
@@ -322,3 +316,26 @@
         # and the ending \n causes an empty line to display.
         return info.dwSize.Y, info.dwSize.X - 1
 
+def write_out(fil, msg):
+    # XXX sometimes "msg" is of type bytes, sometimes text which
+    # complicates the situation.  Should we try to enforce unicode?
+    try:
+        # on py27 and above writing out to sys.stdout with an encoding
+        # should usually work for unicode messages (if the encoding is
+        # capable of it)
+        fil.write(msg)
+    except UnicodeEncodeError:
+        # on py26 it might not work because stdout expects bytes
+        if fil.encoding:
+            try:
+                fil.write(msg.encode(fil.encoding))
+            except UnicodeEncodeError:
+                # it might still fail if the encoding is not capable
+                pass
+            else:
+                fil.flush()
+                return
+        # fallback: escape all unicode characters
+        msg = msg.encode("unicode-escape").decode("ascii")
+        fil.write(msg)
+    fil.flush()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py/_path/local.py 
new/py-1.4.19/py/_path/local.py
--- old/py-1.4.18/py/_path/local.py     2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py/_path/local.py     2013-12-12 12:07:15.000000000 +0100
@@ -7,7 +7,7 @@
 from py._path import common
 from stat import S_ISLNK, S_ISDIR, S_ISREG
 
-from os.path import normpath, isabs, exists, isdir, isfile, islink
+from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink
 
 iswin32 = sys.platform == "win32" or (getattr(os, '_name', False) == 'nt')
 
@@ -151,11 +151,10 @@
         elif isinstance(path, py.builtin._basestring):
             if expanduser:
                 path = os.path.expanduser(path)
-            self.strpath = os.path.abspath(normpath(str(path)))
+            self.strpath = abspath(normpath(path))
         else:
             raise ValueError("can only pass None, Path instances "
                              "or non-empty strings to LocalPath")
-        assert isinstance(self.strpath, py.builtin._basestring)
 
     def __hash__(self):
         return hash(self.strpath)
@@ -184,8 +183,8 @@
         """ return True if 'other' references the same file as 'self'.
         """
         other = getattr(other, "strpath", other)
-        if not os.path.isabs(other):
-            other = os.path.abspath(other)
+        if not isabs(other):
+            other = abspath(other)
         if self == other:
             return True
         if iswin32:
@@ -369,7 +368,7 @@
         if isinstance(fil, py.builtin._basestring):
             if not self._patternchars.intersection(fil):
                 child = self._fastjoin(fil)
-                if os.path.exists(child.strpath):
+                if exists(child.strpath):
                     return [child]
                 return []
             fil = common.FNMatcher(fil)
@@ -682,7 +681,7 @@
             Note: This is probably not working on plain win32 systems
             but may work on cygwin.
         """
-        if os.path.isabs(name):
+        if isabs(name):
             p = py.path.local(name)
             if p.check(file=1):
                 return p
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py.egg-info/PKG-INFO 
new/py-1.4.19/py.egg-info/PKG-INFO
--- old/py-1.4.18/py.egg-info/PKG-INFO  2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/py.egg-info/PKG-INFO  2013-12-12 12:07:15.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py
-Version: 1.4.18
+Version: 1.4.19
 Summary: library with cross-python path, ini-parsing, io, code, log facilities
 Home-page: http://pylib.readthedocs.org/
 Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/py.egg-info/SOURCES.txt 
new/py-1.4.19/py.egg-info/SOURCES.txt
--- old/py-1.4.18/py.egg-info/SOURCES.txt       2013-10-29 11:34:25.000000000 
+0100
+++ new/py-1.4.19/py.egg-info/SOURCES.txt       2013-12-12 12:07:15.000000000 
+0100
@@ -3,7 +3,6 @@
 MANIFEST.in
 README.txt
 conftest.py
-distribute_setup.py
 setup.py
 tox.ini
 doc/Makefile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/setup.py new/py-1.4.19/setup.py
--- old/py-1.4.18/setup.py      2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/setup.py      2013-12-12 12:07:15.000000000 +0100
@@ -1,18 +1,13 @@
 import os, sys
 
-try:
-    from setuptools import setup
-except ImportError:
-    from distribute_setup import use_setuptools
-    use_setuptools()
-    from setuptools import setup
+from setuptools import setup
 
 def main():
     setup(
         name='py',
         description='library with cross-python path, ini-parsing, io, code, 
log facilities',
         long_description = open('README.txt').read(),
-        version='1.4.18',
+        version='1.4.19',
         url='http://pylib.readthedocs.org/',
         license='MIT license',
         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/testing/code/test_excinfo.py 
new/py-1.4.19/testing/code/test_excinfo.py
--- old/py-1.4.18/testing/code/test_excinfo.py  2013-10-29 11:34:25.000000000 
+0100
+++ new/py-1.4.19/testing/code/test_excinfo.py  2013-12-12 12:07:15.000000000 
+0100
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 
 import py
 from py._code.code import FormattedExcinfo, ReprExceptionInfo
@@ -13,6 +14,10 @@
 else:
     invalidate_import_caches = getattr(importlib, "invalidate_caches", None)
 
+import pytest
+pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3]))
+pytest25 = pytest.mark.skipif(pytest_version_info < (2,5), reason="requires 
pytest-2.5")
+
 class TWMock:
     def __init__(self):
         self.lines = []
@@ -239,6 +244,15 @@
     assert msg.startswith('ValueError')
     assert msg.endswith("world")
 
+@pytest25
+def test_excinfo_exconly_unicode_AssertionError():
+    val = py.builtin._totext('£€', 'utf-8')
+    def fail():
+        raise AssertionError(val)
+    excinfo = py.test.raises(Exception, fail)
+    msg = excinfo.exconly(tryshort=True)
+    assert msg == 'AssertionError: ' + val
+
 def test_excinfo_repr():
     excinfo = py.test.raises(ValueError, h)
     s = repr(excinfo)
@@ -385,6 +399,8 @@
         pr = FormattedExcinfo()
 
         class FakeCode(object):
+            class raw:
+                co_filename = '?'
             path = '?'
             firstlineno = 5
 
@@ -395,12 +411,16 @@
         class FakeFrame(object):
             code = FakeCode()
             f_locals = {}
+            f_globals = {}
 
         class FakeTracebackEntry(py.code.Traceback.Entry):
             def __init__(self, tb):
-                self.frame = FakeFrame()
                 self.lineno = 5+3
 
+            @property
+            def frame(self):
+                return FakeFrame()
+
         class Traceback(py.code.Traceback):
             Entry = FakeTracebackEntry
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/testing/io_/test_saferepr.py 
new/py-1.4.19/testing/io_/test_saferepr.py
--- old/py-1.4.18/testing/io_/test_saferepr.py  2013-10-29 11:34:25.000000000 
+0100
+++ new/py-1.4.19/testing/io_/test_saferepr.py  2013-12-12 12:07:15.000000000 
+0100
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 from __future__ import generators
 import py
 import sys
@@ -60,6 +62,11 @@
         except Exception:
             py.test.fail("saferepr failed for newstyle class")
 
+    def test_unicode(self):
+        val = py.builtin._totext('£€', 'utf-8')
+        reprval = py.builtin._totext("'£€'", 'utf-8')
+        assert saferepr(val) == reprval
+
 def test_unicode_handling():
     value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
     def f():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/testing/io_/test_terminalwriter.py 
new/py-1.4.19/testing/io_/test_terminalwriter.py
--- old/py-1.4.18/testing/io_/test_terminalwriter.py    2013-10-29 
11:34:25.000000000 +0100
+++ new/py-1.4.19/testing/io_/test_terminalwriter.py    2013-12-12 
12:07:15.000000000 +0100
@@ -218,14 +218,18 @@
     assert l == set(["2"])
 
 
+@pytest.mark.skipif(sys.platform == "win32", reason="win32 has no native ansi")
 def test_attr_hasmarkup():
     tw = py.io.TerminalWriter(stringio=True)
     assert not tw.hasmarkup
     tw.hasmarkup = True
     tw.line("hello", bold=True)
     s = tw.stringio.getvalue()
-    assert len(s) > len("hello")
+    assert len(s) > len("hello\n")
+    assert '\x1b[1m' in s
+    assert '\x1b[0m' in s
 
+@pytest.mark.skipif(sys.platform == "win32", reason="win32 has no native ansi")
 def test_ansi_print():
     # we have no easy way to construct a file that
     # represents a terminal
@@ -234,4 +238,27 @@
     py.io.ansi_print("hello", 0x32, file=f)
     text2 = f.getvalue()
     assert text2.find("hello") != -1
-    assert len(text2) >= len("hello")
+    assert len(text2) >= len("hello\n")
+    assert '\x1b[50m' in text2
+    assert '\x1b[0m' in text2
+
+def test_should_do_markup_PY_COLORS_eq_1(monkeypatch):
+    monkeypatch.setitem(os.environ, 'PY_COLORS', '1')
+    tw = py.io.TerminalWriter(stringio=True)
+    assert tw.hasmarkup
+    tw.line("hello", bold=True)
+    s = tw.stringio.getvalue()
+    assert len(s) > len("hello\n")
+    assert '\x1b[1m' in s
+    assert '\x1b[0m' in s
+
+def test_should_do_markup_PY_COLORS_eq_0(monkeypatch):
+    monkeypatch.setitem(os.environ, 'PY_COLORS', '0')
+    f = py.io.TextIO()
+    f.isatty = lambda: True
+    tw = py.io.TerminalWriter(file=f)
+    assert not tw.hasmarkup
+    tw.line("hello", bold=True)
+    s = f.getvalue()
+    assert s == "hello\n"
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/py-1.4.18/tox.ini new/py-1.4.19/tox.ini
--- old/py-1.4.18/tox.ini       2013-10-29 11:34:25.000000000 +0100
+++ new/py-1.4.19/tox.ini       2013-12-12 12:07:15.000000000 +0100
@@ -1,5 +1,5 @@
 [tox]
-envlist=py25,py26,py27,py32,py33,external
+envlist=py26,py27,py32,py33,external
 # py27-xdist causes problems with svn, py25 requires virtualenv==1.9.1
 #indexserver=
 #    default=http://pypi.testrun.org

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to