Hello community, here is the log from the commit of package python-pytools for openSUSE:Factory checked in at 2018-07-10 16:16:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytools (Old) and /work/SRC/openSUSE:Factory/.python-pytools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytools" Tue Jul 10 16:16:02 2018 rev:5 rq:621727 version:2018.5.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytools/python-pytools.changes 2018-04-19 15:27:16.608477039 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytools.new/python-pytools.changes 2018-07-10 16:16:51.213403926 +0200 @@ -1,0 +2,6 @@ +Mon Jul 9 14:09:38 UTC 2018 - mplus...@suse.com + +- Update to version 2018.5.2 + * No changelog available + +------------------------------------------------------------------- Old: ---- pytools-2018.3.tar.gz New: ---- pytools-2018.5.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytools.spec ++++++ --- /var/tmp/diff_new_pack.CTDJUe/_old 2018-07-10 16:16:52.141402489 +0200 +++ /var/tmp/diff_new_pack.CTDJUe/_new 2018-07-10 16:16:52.145402483 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pytools -Version: 2018.3 +Version: 2018.5.2 Release: 0 Summary: A collection of tools for Python License: MIT ++++++ pytools-2018.3.tar.gz -> pytools-2018.5.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2018.3/PKG-INFO new/pytools-2018.5.2/PKG-INFO --- old/pytools-2018.3/PKG-INFO 2018-03-16 21:26:58.000000000 +0100 +++ new/pytools-2018.5.2/PKG-INFO 2018-06-27 08:01:00.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pytools -Version: 2018.3 +Version: 2018.5.2 Summary: A collection of tools for Python Home-page: http://pypi.python.org/pypi/pytools Author: Andreas Kloeckner Author-email: inf...@tiker.net 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-2018.3/pytools/__init__.py new/pytools-2018.5.2/pytools/__init__.py --- old/pytools-2018.3/pytools/__init__.py 2018-03-11 08:49:36.000000000 +0100 +++ new/pytools-2018.5.2/pytools/__init__.py 2018-06-22 18:12:02.000000000 +0200 @@ -31,6 +31,8 @@ from six.moves import range, zip, intern, input from functools import reduce +import logging + try: decorator_module = __import__("decorator", level=0) except TypeError: @@ -123,12 +125,30 @@ .. autofunction:: generate_unique_names .. autofunction:: generate_numbered_unique_names -.. autofunction:: UniqueNameGenerator +.. autoclass:: UniqueNameGenerator Functions for dealing with (large) auxiliary files -------------------------------------------------- .. autofunction:: download_from_web_if_not_present + +Helpers for :mod:`numpy` +------------------------ + +.. autofunction:: reshaped_view + + +Timing data +----------- + +.. autoclass:: ProcessTimer + +Log utilities +------------- + +.. autoclass:: ProcessLogger +.. autoclass:: DebugProcessLogger +.. autoclass:: log_process """ @@ -586,10 +606,9 @@ def clear_cache(obj): delattr(obj, cache_dict_name) - if sys.version_info >= (2, 5): - from functools import update_wrapper - new_wrapper = update_wrapper(wrapper, function) - new_wrapper.clear_cache = clear_cache + from functools import update_wrapper + new_wrapper = update_wrapper(wrapper, function) + new_wrapper.clear_cache = clear_cache return new_wrapper @@ -2032,6 +2051,182 @@ # }}} + +# {{{ create a reshaped view of a numpy array + +def reshaped_view(a, newshape): + """ Create a new view object with shape ``newshape`` without copying the data of + ``a``. This function is different from ``numpy.reshape`` by raising an + exception when data copy is necessary. + + :arg a: a :class:`numpy.ndarray` object. + :arg newshape: an ``int`` object or a tuple of ``int`` objects. + + .. versionadded:: 2018.4 + """ + + newview = a.view() + newview.shape = newshape + return newview + +# }}} + + +# {{{ process timer + +class ProcessTimer(object): + """Measures elapsed wall time and process time. + + .. automethod:: __enter__ + .. automethod:: __exit__ + .. automethod:: done + + Timing data attributes: + + .. attribute:: wall_elapsed + .. attribute:: process_elapsed + + Only available in Python 3.3+. + + .. versionadded:: 2018.5 + """ + + def __init__(self): + import time + if sys.version_info >= (3, 3): + self.perf_counter_start = time.perf_counter() + self.process_time_start = time.process_time() + + else: + import timeit + self.time_start = timeit.default_timer() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.done() + + def done(self): + import time + if sys.version_info >= (3, 3): + self.wall_elapsed = time.perf_counter() - self.perf_counter_start + self.process_elapsed = time.process_time() - self.process_time_start + + else: + import timeit + self.wall_elapsed = timeit.default_timer() - self.time_start + self.process_elapsed = None + +# }}} + + +# {{{ log utilities + +class ProcessLogger(object): + """Logs the completion time of a (presumably) lengthy process to :mod:`logging`. + Only uses a high log level if the process took perceptible time. + + .. automethod:: __init__ + .. automethod:: done + .. automethod:: __enter__ + .. automethod:: __exit__ + """ + + default_noisy_level = logging.INFO + + def __init__(self, logger, description, + silent_level=None, noisy_level=None, long_threshold_seconds=None): + self.logger = logger + self.description = description + self.silent_level = silent_level or logging.DEBUG + self.noisy_level = noisy_level or self.default_noisy_level + self.long_threshold_seconds = ( + # 0 is a valid value that should override the default + 0.3 if long_threshold_seconds is None else long_threshold_seconds) + + self.logger.log(self.silent_level, "%s: start", self.description) + self.is_done = False + + import threading + self.late_start_log_thread = threading.Thread(target=self._log_start_if_long) + # Do not delay interpreter exit if thread not finished. + self.late_start_log_thread.daemon = True + self.late_start_log_thread.start() + + self.timer = ProcessTimer() + + def _log_start_if_long(self): + from time import sleep + + sleep_duration = 10*self.long_threshold_seconds + sleep(sleep_duration) + + if not self.is_done: + self.logger.log( + self.noisy_level, "%s: started %.gs ago", + self.description, + sleep_duration) + + def done(self, extra_msg=None, *extra_fmt_args): + self.timer.done() + self.is_done = True + + wall_elapsed = self.timer.wall_elapsed + process_elapsed = self.timer.process_elapsed + + completion_level = ( + self.noisy_level + if wall_elapsed > self.long_threshold_seconds + else self.silent_level) + + if process_elapsed is not None: + msg = "%s: completed (%.2fs wall, %.1fx CPU)" + fmt_args = [self.description, wall_elapsed, process_elapsed/wall_elapsed] + else: + msg = "%s: completed (%f.2s wall)" + fmt_args = [self.description, wall_elapsed] + + if extra_msg: + msg += ": " + extra_msg + fmt_args.extend(extra_fmt_args) + + self.logger.log(completion_level, msg, *fmt_args) + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + self.done() + + +class DebugProcessLogger(ProcessLogger): + default_noisy_level = logging.DEBUG + + +class log_process(object): # noqa: N801 + """A decorator that uses :class:`ProcessLogger` to log data about calls + to the wrapped function. + """ + + def __init__(self, logger, description=None): + self.logger = logger + self.description = description + + def __call__(self, wrapped): + def wrapper(*args, **kwargs): + with ProcessLogger( + self.logger, + self.description or wrapped.__name__): + return wrapped(*args, **kwargs) + + from functools import update_wrapper + new_wrapper = update_wrapper(wrapper, wrapped) + + return new_wrapper + +# }}} + def _test(): import doctest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2018.3/pytools/log.py new/pytools-2018.5.2/pytools/log.py --- old/pytools-2018.3/pytools/log.py 2017-10-29 13:16:10.000000000 +0100 +++ new/pytools-2018.5.2/pytools/log.py 2018-04-20 22:22:24.000000000 +0200 @@ -207,7 +207,7 @@ def _get_unique_id(): try: - from uiid import uuid1 + from uuid import uuid1 except ImportError: try: import hashlib @@ -221,7 +221,7 @@ rng = Random() rng.seed() for i in range(20): - checksum.update(str(rng.randrange(1 << 30))) + checksum.update(str(rng.randrange(1 << 30)).encode('utf-32')) return checksum.hexdigest() else: return uuid1().hex diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2018.3/pytools/obj_array.py new/pytools-2018.5.2/pytools/obj_array.py --- old/pytools-2018.3/pytools/obj_array.py 2017-06-15 00:04:28.000000000 +0200 +++ new/pytools-2018.5.2/pytools/obj_array.py 2018-06-27 05:58:17.000000000 +0200 @@ -59,13 +59,17 @@ return result -def is_field_equal(a, b): +def is_equal(a, b): if is_obj_array(a): return is_obj_array(b) and (a.shape == b.shape) and (a == b).all() else: return not is_obj_array(b) and a == b +# moderately deprecated +is_field_equal = is_equal + + def make_obj_array(res_list): result = np.empty((len(res_list),), dtype=object) for i, v in enumerate(res_list): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2018.3/pytools/version.py new/pytools-2018.5.2/pytools/version.py --- old/pytools-2018.3/pytools/version.py 2018-03-16 21:25:30.000000000 +0100 +++ new/pytools-2018.5.2/pytools/version.py 2018-06-27 08:00:13.000000000 +0200 @@ -1,3 +1,3 @@ -VERSION = (2018, 3) +VERSION = (2018, 5, 2) 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-2018.3/pytools.egg-info/PKG-INFO new/pytools-2018.5.2/pytools.egg-info/PKG-INFO --- old/pytools-2018.3/pytools.egg-info/PKG-INFO 2018-03-16 21:26:58.000000000 +0100 +++ new/pytools-2018.5.2/pytools.egg-info/PKG-INFO 2018-06-27 08:01:00.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pytools -Version: 2018.3 +Version: 2018.5.2 Summary: A collection of tools for Python Home-page: http://pypi.python.org/pypi/pytools Author: Andreas Kloeckner Author-email: inf...@tiker.net 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-2018.3/test/test_pytools.py new/pytools-2018.5.2/test/test_pytools.py --- old/pytools-2018.3/test/test_pytools.py 2018-03-11 07:19:15.000000000 +0100 +++ new/pytools-2018.5.2/test/test_pytools.py 2018-03-28 00:49:01.000000000 +0200 @@ -211,6 +211,18 @@ print(pytools.find_module_git_revision(pytools.__file__, n_levels_up=1)) +def test_reshaped_view(): + import pytools + import numpy as np + + a = np.zeros((10, 2)) + b = a.T + c = pytools.reshaped_view(a, -1) + assert c.shape == (20,) + with pytest.raises(AttributeError): + pytools.reshaped_view(b, -1) + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1])