Hello community, here is the log from the commit of package python-pytools for openSUSE:Factory checked in at 2018-04-19 15:27:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytools (Old) and /work/SRC/openSUSE:Factory/.python-pytools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytools" Thu Apr 19 15:27:15 2018 rev:4 rq:593929 version:2018.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytools/python-pytools.changes 2017-10-18 10:54:17.878131936 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytools.new/python-pytools.changes 2018-04-19 15:27:16.608477039 +0200 @@ -1,0 +2,6 @@ +Fri Apr 6 08:49:05 UTC 2018 - [email protected] + +- Update to version 2018.2 + * No changelog available + +------------------------------------------------------------------- @@ -4 +10 @@ -- Update to version 17.6 +- Update to version 2017.6 Old: ---- pytools-2017.6.tar.gz New: ---- pytools-2018.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytools.spec ++++++ --- /var/tmp/diff_new_pack.BVQTox/_old 2018-04-19 15:27:17.208452582 +0200 +++ /var/tmp/diff_new_pack.BVQTox/_new 2018-04-19 15:27:17.208452582 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-pytools # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,20 +18,20 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pytools -Version: 2017.6 +Version: 2018.3 Release: 0 Summary: A collection of tools for Python License: MIT Group: Development/Languages/Python -Url: https://pypi.python.org/pypi/pytools +URL: https://pypi.python.org/pypi/pytools Source0: https://files.pythonhosted.org/packages/source/p/pytools/pytools-%{version}.tar.gz -BuildRequires: %{python_module appdirs} +BuildRequires: %{python_module appdirs} >= 1.4.0 BuildRequires: %{python_module base} -BuildRequires: %{python_module decorator} +BuildRequires: %{python_module decorator} >= 3.2.0 BuildRequires: %{python_module devel} -BuildRequires: %{python_module numpy} +BuildRequires: %{python_module numpy} >= 1.6.0 BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module six} +BuildRequires: %{python_module six} >= 1.8.0 BuildRequires: fdupes BuildRequires: python-rpm-macros BuildArch: noarch @@ -64,8 +64,8 @@ python2 setup.py test %files %{python_files} -%defattr(-,root,root,-) -%doc README.rst LICENSE +%license LICENSE +%doc README.rst %{python_sitelib}/* %changelog ++++++ pytools-2017.6.tar.gz -> pytools-2018.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/PKG-INFO new/pytools-2018.3/PKG-INFO --- old/pytools-2017.6/PKG-INFO 2017-09-26 02:09:29.000000000 +0200 +++ new/pytools-2018.3/PKG-INFO 2018-03-16 21:26:58.000000000 +0100 @@ -1,11 +1,12 @@ Metadata-Version: 1.1 Name: pytools -Version: 2017.6 +Version: 2018.3 Summary: A collection of tools for Python Home-page: http://pypi.python.org/pypi/pytools Author: Andreas Kloeckner Author-email: [email protected] License: MIT +Description-Content-Type: UNKNOWN Description: Pytools is a big bag of things that are "missing" from the Python standard library. This is mainly a dependency of my other software packages, and is probably of little interest to you unless you use those. If you're curious diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/__init__.py new/pytools-2018.3/pytools/__init__.py --- old/pytools-2017.6/pytools/__init__.py 2017-09-25 05:04:33.000000000 +0200 +++ new/pytools-2018.3/pytools/__init__.py 2018-03-11 08:49:36.000000000 +0100 @@ -1466,7 +1466,7 @@ bin_nr = bisect(bin_starts, value)-1 try: bins[bin_nr] += 1 - except: + except Exception: print(value, bin_nr, bin_starts) raise @@ -1855,10 +1855,9 @@ def generate_numbered_unique_names(prefix, num=None): - orig_num = num - num = 0 - if orig_num is None: - yield (num, prefix) + if num is None: + yield (0, prefix) + num = 0 while True: name = "%s_%d" % (prefix, num) @@ -1940,7 +1939,17 @@ sys.setrecursionlimit(new_limit) def __exit__(self, exc_type, exc_val, exc_tb): - sys.setrecursionlimit(self.prev_recursion_limit) + # Deep recursion can produce deeply nested data structures + # (or long chains of to-be gc'd generators) that cannot be + # undergo garbage collection with a lower recursion limit. + # + # As a result, it doesn't seem possible to lower the recursion limit + # again after it has been raised without causing reliability issues. + # + # See https://gitlab.tiker.net/inducer/sumpy/issues/31 for + # context. + + pass # }}} @@ -1966,6 +1975,63 @@ # }}} + +# {{{ find git revisions + +def find_git_revision(tree_root): + # Keep this routine self-contained so that it can be copy-pasted into + # setup.py. + + from os.path import join, exists, abspath + tree_root = abspath(tree_root) + + if not exists(join(tree_root, ".git")): + return None + + # construct minimal environment + # stolen from + # https://github.com/numpy/numpy/blob/055ce3e90b50b5f9ef8cf1b8641c42e391f10735/setup.py#L70-L92 + import os + env = {} + for k in ['SYSTEMROOT', 'PATH', 'HOME']: + v = os.environ.get(k) + if v is not None: + env[k] = v + # LANGUAGE is used on win32 + env['LANGUAGE'] = 'C' + env['LANG'] = 'C' + env['LC_ALL'] = 'C' + + from subprocess import Popen, PIPE, STDOUT + p = Popen(["git", "rev-parse", "HEAD"], shell=False, + stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True, + cwd=tree_root, env=env) + (git_rev, _) = p.communicate() + + import sys + if sys.version_info >= (3,): + git_rev = git_rev.decode() + + git_rev = git_rev.rstrip() + + retcode = p.returncode + assert retcode is not None + if retcode != 0: + from warnings import warn + warn("unable to find git revision") + return None + + return git_rev + + +def find_module_git_revision(module_file, n_levels_up): + from os.path import dirname, join + tree_root = join(*([dirname(module_file)] + [".." * n_levels_up])) + + return find_git_revision(tree_root) + +# }}} + def _test(): import doctest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/debug.py new/pytools-2018.3/pytools/debug.py --- old/pytools-2017.6/pytools/debug.py 2016-12-06 02:09:53.000000000 +0100 +++ new/pytools-2018.3/pytools/debug.py 2017-10-29 13:17:25.000000000 +0100 @@ -122,7 +122,7 @@ expr_str = input() try: res = eval(expr_str, {"obj": r}) - except: + except Exception: from traceback import print_exc print_exc() print(res) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/importlib_backport.py new/pytools-2018.3/pytools/importlib_backport.py --- old/pytools-2017.6/pytools/importlib_backport.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pytools-2018.3/pytools/importlib_backport.py 2018-03-16 21:25:30.000000000 +0100 @@ -0,0 +1,94 @@ +"""Backport of importlib.import_module from 3.x. + +Downloaded from: https://github.com/sprintly/importlib + +This code is based in the implementation of importlib.import_module() +in Python 2.7. The license is below. + +======================================================================== + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python +alone or in any derivative version, provided, however, that PSF's +License Agreement and PSF's notice of copyright, i.e., "Copyright (c) +2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights +Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + +""" + +# While not critical (and in no way guaranteed!), it would be nice to keep this +# code compatible with Python 2.3. +import sys +import six + + +def _resolve_name(name, package, level): + """Return the absolute name of the module to be imported.""" + if not hasattr(package, 'rindex'): + raise ValueError("'package' not set to a string") + dot = len(package) + for x in six.moves.xrange(level, 1, -1): + try: + dot = package.rindex('.', 0, dot) + except ValueError: + raise ValueError("attempted relative import beyond top-level " + "package") + return "%s.%s" % (package[:dot], name) + + +def import_module(name, package=None): + """Import a module. + The 'package' argument is required when performing a relative import. It + specifies the package to use as the anchor point from which to resolve the + relative import to an absolute import. + """ + if name.startswith('.'): + if not package: + raise TypeError("relative imports require the 'package' argument") + level = 0 + for character in name: + if character != '.': + break + level += 1 + name = _resolve_name(name[level:], package, level) + __import__(name) + return sys.modules[name] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/log.py new/pytools-2018.3/pytools/log.py --- old/pytools-2017.6/pytools/log.py 2016-12-06 02:09:53.000000000 +0100 +++ new/pytools-2018.3/pytools/log.py 2017-10-29 13:16:10.000000000 +0100 @@ -558,7 +558,7 @@ try: self.db_conn.execute("insert into %s values (?,?,?)" % name, (self.tick_count, self.rank, float(value))) - except: + except Exception: print("while adding datapoint for '%s':" % name) raise diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/persistent_dict.py new/pytools-2018.3/pytools/persistent_dict.py --- old/pytools-2017.6/pytools/persistent_dict.py 2017-09-26 02:09:20.000000000 +0200 +++ new/pytools-2018.3/pytools/persistent_dict.py 2017-11-22 04:13:02.000000000 +0100 @@ -32,6 +32,7 @@ import collections +import functools import six import sys import os @@ -39,15 +40,19 @@ import errno __doc__ = """ -Persistent Hashing -================== +Persistent Hashing and Persistent Dictionaries +============================================== This module contains functionality that allows hashing with keys that remain valid across interpreter invocations, unlike Python's built-in hashes. +This module also provides a disk-backed dictionary that uses persistent hashing. + .. autoexception:: NoSuchEntryError .. autoexception:: ReadOnlyEntryError +.. autoexception:: CollisionWarning + .. autoclass:: KeyBuilder .. autoclass:: PersistentDict .. autoclass:: WriteOncePersistentDict @@ -78,6 +83,37 @@ checksum.update(obj) +def _tracks_stacklevel(cls, exclude=frozenset(["__init__"])): + """Changes all the methods of `cls` to track the call stack level in a member + called `_stacklevel`. + """ + def make_wrapper(f): + @functools.wraps(f) + def wrapper(obj, *args, **kwargs): + assert obj._stacklevel >= 0, obj._stacklevel + # Increment by 2 because the method is wrapped. + obj._stacklevel += 2 + try: + return f(obj, *args, **kwargs) + finally: + obj._stacklevel -= 2 + + return wrapper + + for member in cls.__dict__: + f = getattr(cls, member) + + if member in exclude: + continue + + if not six.callable(f): + continue + + setattr(cls, member, make_wrapper(f)) + + return cls + + # {{{ cleanup managers class CleanupBase(object): @@ -101,7 +137,7 @@ class LockManager(CleanupBase): - def __init__(self, cleanup_m, lock_file): + def __init__(self, cleanup_m, lock_file, _stacklevel=1): self.lock_file = lock_file attempts = 0 @@ -121,7 +157,8 @@ if attempts > 10: from warnings import warn warn("could not obtain lock--delete '%s' if necessary" - % self.lock_file) + % self.lock_file, + stacklevel=1 + _stacklevel) if attempts > 3 * 60: raise RuntimeError("waited more than three minutes " "on the lock file '%s'" @@ -395,8 +432,16 @@ pass +class CollisionWarning(UserWarning): + pass + + +@_tracks_stacklevel class _PersistentDictBase(object): def __init__(self, identifier, key_builder=None, container_dir=None): + # for issuing warnings + self._stacklevel = 0 + self.identifier = identifier if key_builder is None: @@ -417,6 +462,10 @@ self._make_container_dir() + def _warn(self, msg, category=UserWarning): + from warnings import warn + warn(msg, category, stacklevel=1 + self._stacklevel) + def store_if_not_present(self, key, value): self.store(key, value, _skip_if_present=True) @@ -458,13 +507,16 @@ def _collision_check(self, key, stored_key): if stored_key != key: # Key collision, oh well. - from warnings import warn - warn("%s: key collision in cache at '%s' -- these are " + self._warn("%s: key collision in cache at '%s' -- these are " "sufficiently unlikely that they're often " - "indicative of a broken implementation " - "of equality comparison" - % (self.identifier, self.container_dir)) - # This is here so we can debug the equality comparison + "indicative of a broken hash key implementation " + "(that is not considering some elements relevant " + "for equality comparison)" + % (self.identifier, self.container_dir), + CollisionWarning) + + # This is here so we can step through equality comparison to + # see what is actually non-equal. stored_key == key raise NoSuchEntryError(key) @@ -487,7 +539,21 @@ self._make_container_dir() +@_tracks_stacklevel class WriteOncePersistentDict(_PersistentDictBase): + """A concurrent disk-backed dictionary that disallows overwriting/deletion. + + Compared with :class:`PersistentDict`, this class has faster + retrieval times. + + .. automethod:: __init__ + .. automethod:: __getitem__ + .. automethod:: __setitem__ + .. automethod:: clear + .. automethod:: store + .. automethod:: store_if_not_present + .. automethod:: fetch + """ def __init__(self, identifier, key_builder=None, container_dir=None, in_mem_cache_size=256): """ @@ -496,11 +562,6 @@ :arg key_builder: a subclass of :class:`KeyBuilder` :arg in_mem_cache_size: retain an in-memory cache of up to *in_mem_cache_size* items - - .. automethod:: __getitem__ - .. automethod:: __setitem__ - .. automethod:: clear - .. automethod:: store_if_not_present """ _PersistentDictBase.__init__(self, identifier, key_builder, container_dir) self._cache = _LRUCache(in_mem_cache_size) @@ -516,8 +577,7 @@ attempts += 1 if attempts > 10: - from warnings import warn - warn("waiting until unlocked--delete '%s' if necessary" + self._warn("waiting until unlocked--delete '%s' if necessary" % lock_file) if attempts > 3 * 60: @@ -551,7 +611,7 @@ logger.debug("%s: disk cache store [key=%s]" % ( self.identifier, hexdigest_key)) - except: + except Exception: cleanup_m.error_clean_up() raise finally: @@ -599,13 +659,12 @@ try: read_key = self._read(key_file) - except: - from warnings import warn - warn("pytools.persistent_dict.WriteOncePersistentDict(%s) " + except Exception as e: + self._warn("pytools.persistent_dict.WriteOncePersistentDict(%s) " "encountered an invalid " "key file for key %s. Remove the directory " - "'%s' if necessary." - % (self.identifier, hexdigest_key, item_dir)) + "'%s' if necessary. (caught: %s)" + % (self.identifier, hexdigest_key, item_dir, str(e))) raise NoSuchEntryError(key) self._collision_check(key, read_key) @@ -619,8 +678,8 @@ try: read_contents = self._read(contents_file) - except: - warn("pytools.persistent_dict.WriteOncePersistentDict(%s) " + except Exception: + self._warn("pytools.persistent_dict.WriteOncePersistentDict(%s) " "encountered an invalid " "key file for key %s. Remove the directory " "'%s' if necessary." @@ -637,18 +696,23 @@ self._cache.clear() +@_tracks_stacklevel class PersistentDict(_PersistentDictBase): + """A concurrent disk-backed dictionary. + + .. automethod:: __init__ + .. automethod:: __getitem__ + .. automethod:: __setitem__ + .. automethod:: clear + .. automethod:: store + .. automethod:: store_if_not_present + .. automethod:: fetch + """ def __init__(self, identifier, key_builder=None, container_dir=None): """ :arg identifier: a file-name-compatible string identifying this dictionary :arg key_builder: a subclass of :class:`KeyBuilder` - - .. automethod:: __getitem__ - .. automethod:: __setitem__ - .. automethod:: __delitem__ - .. automethod:: clear - .. automethod:: store_if_not_present """ _PersistentDictBase.__init__(self, identifier, key_builder, container_dir) @@ -658,7 +722,8 @@ cleanup_m = CleanupManager() try: try: - LockManager(cleanup_m, self._lock_file(hexdigest_key)) + LockManager(cleanup_m, self._lock_file(hexdigest_key), + 1 + self._stacklevel) item_dir_m = ItemDirManager( cleanup_m, self._item_dir(hexdigest_key), delete_on_error=True) @@ -678,7 +743,7 @@ logger.debug("%s: cache store [key=%s]" % ( self.identifier, hexdigest_key)) - except: + except Exception: cleanup_m.error_clean_up() raise finally: @@ -697,7 +762,8 @@ cleanup_m = CleanupManager() try: try: - LockManager(cleanup_m, self._lock_file(hexdigest_key)) + LockManager(cleanup_m, self._lock_file(hexdigest_key), + 1 + self._stacklevel) item_dir_m = ItemDirManager( cleanup_m, item_dir, delete_on_error=False) @@ -708,10 +774,9 @@ try: read_key = self._read(key_path) - except: + except Exception: item_dir_m.reset() - from warnings import warn - warn("pytools.persistent_dict.PersistentDict(%s) " + self._warn("pytools.persistent_dict.PersistentDict(%s) " "encountered an invalid " "key file for key %s. Entry deleted." % (self.identifier, hexdigest_key)) @@ -728,10 +793,9 @@ try: read_contents = self._read(value_path) - except: + except Exception: item_dir_m.reset() - from warnings import warn - warn("pytools.persistent_dict.PersistentDict(%s) " + self._warn("pytools.persistent_dict.PersistentDict(%s) " "encountered an invalid " "key file for key %s. Entry deleted." % (self.identifier, hexdigest_key)) @@ -741,7 +805,7 @@ # }}} - except: + except Exception: cleanup_m.error_clean_up() raise finally: @@ -758,7 +822,8 @@ cleanup_m = CleanupManager() try: try: - LockManager(cleanup_m, self._lock_file(hexdigest_key)) + LockManager(cleanup_m, self._lock_file(hexdigest_key), + 1 + self._stacklevel) item_dir_m = ItemDirManager( cleanup_m, item_dir, delete_on_error=False) key_file = self._key_file(hexdigest_key) @@ -767,10 +832,9 @@ try: read_key = self._read(key_file) - except: + except Exception: item_dir_m.reset() - from warnings import warn - warn("pytools.persistent_dict.PersistentDict(%s) " + self._warn("pytools.persistent_dict.PersistentDict(%s) " "encountered an invalid " "key file for key %s. Entry deleted." % (self.identifier, hexdigest_key)) @@ -782,7 +846,7 @@ item_dir_m.reset() - except: + except Exception: cleanup_m.error_clean_up() raise finally: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/py_codegen.py new/pytools-2018.3/pytools/py_codegen.py --- old/pytools-2017.6/pytools/py_codegen.py 2017-06-03 00:36:37.000000000 +0200 +++ new/pytools-2018.3/pytools/py_codegen.py 2018-03-16 21:25:30.000000000 +0100 @@ -100,6 +100,10 @@ def get_function(self): return self.get_module()[self.name] + def get_picklable_function(self): + module = self.get_picklable_module() + return PicklableFunction(module, self.name) + # {{{ pickling of binaries for generated code @@ -121,27 +125,32 @@ nondefault_globals = {} functions = {} + modules = {} - from types import FunctionType + from types import FunctionType, ModuleType for k, v in six.iteritems(self.mod_globals): if isinstance(v, FunctionType): functions[k] = ( v.__name__, marshal.dumps(v.__code__), v.__defaults__) - + elif isinstance(v, ModuleType): + modules[k] = v.__name__ elif k not in _empty_module_dict: nondefault_globals[k] = v import imp - return (0, imp.get_magic(), functions, nondefault_globals) + return (1, imp.get_magic(), functions, modules, nondefault_globals) def __setstate__(self, obj): v = obj[0] if v == 0: magic, functions, nondefault_globals = obj[1:] + modules = {} + elif v == 1: + magic, functions, modules, nondefault_globals = obj[1:] else: - raise ValueError("unknown version of PicklableGeneratedFunction") + raise ValueError("unknown version of PicklableModule") import imp if magic != imp.get_magic(): @@ -155,6 +164,11 @@ mod_globals.update(nondefault_globals) self.mod_globals = mod_globals + from pytools.importlib_backport import import_module + + for k, mod_name in six.iteritems(modules): + mod_globals[k] = import_module(mod_name) + from types import FunctionType for k, v in six.iteritems(functions): name, code_bytes, argdefs = v @@ -164,6 +178,32 @@ # }}} + +# {{{ picklable function + +class PicklableFunction(object): + """Convience class wrapping a function in a :class:`PicklableModule`. + """ + + def __init__(self, module, name): + self._initialize(module, name) + + def _initialize(self, module, name): + self.module = module + self.name = name + self.func = module.mod_globals[name] + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + def __getstate__(self): + return {"module": self.module, "name": self.name} + + def __setstate__(self, obj): + self._initialize(obj["module"], obj["name"]) + +# }}} + # {{{ remove common indentation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools/version.py new/pytools-2018.3/pytools/version.py --- old/pytools-2017.6/pytools/version.py 2017-09-26 02:09:20.000000000 +0200 +++ new/pytools-2018.3/pytools/version.py 2018-03-16 21:25:30.000000000 +0100 @@ -1,3 +1,3 @@ -VERSION = (2017, 6) +VERSION = (2018, 3) VERSION_STATUS = "" VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools.egg-info/PKG-INFO new/pytools-2018.3/pytools.egg-info/PKG-INFO --- old/pytools-2017.6/pytools.egg-info/PKG-INFO 2017-09-26 02:09:29.000000000 +0200 +++ new/pytools-2018.3/pytools.egg-info/PKG-INFO 2018-03-16 21:26:58.000000000 +0100 @@ -1,11 +1,12 @@ Metadata-Version: 1.1 Name: pytools -Version: 2017.6 +Version: 2018.3 Summary: A collection of tools for Python Home-page: http://pypi.python.org/pypi/pytools Author: Andreas Kloeckner Author-email: [email protected] License: MIT +Description-Content-Type: UNKNOWN Description: Pytools is a big bag of things that are "missing" from the Python standard library. This is mainly a dependency of my other software packages, and is probably of little interest to you unless you use those. If you're curious diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/pytools.egg-info/SOURCES.txt new/pytools-2018.3/pytools.egg-info/SOURCES.txt --- old/pytools-2017.6/pytools.egg-info/SOURCES.txt 2017-09-26 02:09:29.000000000 +0200 +++ new/pytools-2018.3/pytools.egg-info/SOURCES.txt 2018-03-16 21:26:58.000000000 +0100 @@ -11,6 +11,7 @@ pytools/debug.py pytools/decorator.py pytools/diskdict.py +pytools/importlib_backport.py pytools/lex.py pytools/log.py pytools/mpi.py @@ -31,4 +32,5 @@ test/test_data_table.py test/test_math_stuff.py test/test_persistent_dict.py +test/test_py_codegen.py test/test_pytools.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/test/test_persistent_dict.py new/pytools-2018.3/test/test_persistent_dict.py --- old/pytools-2017.6/test/test_persistent_dict.py 2017-09-26 02:09:20.000000000 +0200 +++ new/pytools-2018.3/test/test_persistent_dict.py 2018-02-27 07:06:00.000000000 +0100 @@ -10,7 +10,7 @@ from pytools.persistent_dict import ( PersistentDict, WriteOncePersistentDict, NoSuchEntryError, - ReadOnlyEntryError) + ReadOnlyEntryError, CollisionWarning) # {{{ type for testing @@ -155,12 +155,12 @@ pdict[key1] = 1 # check lookup - with pytest.warns(UserWarning): + with pytest.warns(CollisionWarning): with pytest.raises(NoSuchEntryError): pdict[key2] # check deletion - with pytest.warns(UserWarning): + with pytest.warns(CollisionWarning): with pytest.raises(NoSuchEntryError): del pdict[key2] @@ -283,7 +283,7 @@ pdict[key1] = 1 # check lookup - with pytest.warns(UserWarning): + with pytest.warns(CollisionWarning): with pytest.raises(NoSuchEntryError): pdict[key2] @@ -292,7 +292,7 @@ pdict[key2] = 1 # check store_if_not_present - pdict.store_if_not_present(key2, 1) + pdict.store_if_not_present(key2, 2) assert pdict[key1] == 1 finally: @@ -318,5 +318,5 @@ if len(sys.argv) > 1: exec(sys.argv[1]) else: - from py.test.cmdline import main + from pytest import main main([__file__]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/test/test_py_codegen.py new/pytools-2018.3/test/test_py_codegen.py --- old/pytools-2017.6/test/test_py_codegen.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pytools-2018.3/test/test_py_codegen.py 2018-03-16 21:25:30.000000000 +0100 @@ -0,0 +1,38 @@ +from __future__ import division, with_statement, absolute_import + +import pytest # noqa +import pytools +import pytools.py_codegen as codegen +import sys + + +def test_pickling_with_module_import(): + cg = codegen.PythonCodeGenerator() + cg("import pytools") + cg("import math as m") + + import pickle + mod = pickle.loads(pickle.dumps(cg.get_picklable_module())) + + assert mod.mod_globals["pytools"] is pytools + + import math + assert mod.mod_globals["m"] is math + + +def test_picklable_function(): + cg = codegen.PythonFunctionGenerator("f", args=()) + cg("return 1") + + import pickle + f = pickle.loads(pickle.dumps(cg.get_picklable_function())) + + assert f() == 1 + + +if __name__ == "__main__": + if len(sys.argv) > 1: + exec(sys.argv[1]) + else: + from py.test import main + main([__file__]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2017.6/test/test_pytools.py new/pytools-2018.3/test/test_pytools.py --- old/pytools-2017.6/test/test_pytools.py 2017-03-29 22:05:55.000000000 +0200 +++ new/pytools-2018.3/test/test_pytools.py 2018-03-11 07:19:15.000000000 +0100 @@ -195,9 +195,25 @@ del d +def test_generate_numbered_unique_names(): + from pytools import generate_numbered_unique_names + + gen = generate_numbered_unique_names("a") + assert next(gen) == (0, "a") + assert next(gen) == (1, "a_0") + + gen = generate_numbered_unique_names("b", 6) + assert next(gen) == (7, "b_6") + + +def test_find_module_git_revision(): + import pytools + print(pytools.find_module_git_revision(pytools.__file__, n_levels_up=1)) + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) else: - from py.test.cmdline import main + from pytest import main main([__file__])
