Hello community, here is the log from the commit of package python-param for openSUSE:Factory checked in at 2017-08-18 15:06:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-param (Old) and /work/SRC/openSUSE:Factory/.python-param.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-param" Fri Aug 18 15:06:02 2017 rev:2 rq:517422 version:1.5.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-param/python-param.changes 2016-11-20 18:18:10.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python-param.new/python-param.changes 2017-08-18 15:06:06.751716657 +0200 @@ -1,0 +2,12 @@ +Thu Aug 17 15:39:13 UTC 2017 - [email protected] + +- Implement single-spec version +- Update to version 1.5.1 + * Fixed error messages for ClassSelector with tuple of classes + * Added get and contains methods for ParamOverrides +- Update to version 1.5.0 + * Added Range, Color, and Date parameters + * Improved ObjectSelector error messages + * Minor bugfixes + +------------------------------------------------------------------- Old: ---- param-1.4.2.tar.gz New: ---- param-1.5.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-param.spec ++++++ --- /var/tmp/diff_new_pack.HonNLZ/_old 2017-08-18 15:06:07.275642866 +0200 +++ /var/tmp/diff_new_pack.HonNLZ/_new 2017-08-18 15:06:07.275642866 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-param # -# Copyright (c) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2017 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 @@ -16,21 +16,22 @@ # +%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-param -Version: 1.4.2 +Version: 1.5.1 Release: 0 Summary: Declarative Python programming using Parameters License: BSD-3-Clause Group: Development/Languages/Python Url: http://ioam.github.com/param/ Source: https://files.pythonhosted.org/packages/source/p/param/param-%{version}.tar.gz -BuildRequires: python-devel -BuildRoot: %{_tmppath}/%{name}-%{version}-build -%if 0%{?suse_version} && 0%{?suse_version} <= 1110 -%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} -%else -BuildArch: noarch -%endif +BuildRequires: fdupes +BuildRequires: python-rpm-macros +BuildRequires: %{python_module Cython} +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +Recommends: python-jupyter_ipython +%python_subpackages %description Param is a library providing Parameters: Python attributes extended to @@ -47,16 +48,17 @@ %setup -q -n param-%{version} %build -python setup.py build +%python_build %install -python setup.py install --prefix=%{_prefix} --root=%{buildroot} +%python_install +%python_expand %fdupes %{buildroot}%{$python_sitearch} -%files +%files %{python_files} %defattr(-,root,root,-) %doc LICENSE.txt README.rst -%{python_sitelib}/param/ -%{python_sitelib}/numbergen/ -%{python_sitelib}/param-%{version}-py*.egg-info +%{python_sitearch}/param/ +%{python_sitearch}/numbergen/ +%{python_sitearch}/param-%{version}-py*.egg-info %changelog ++++++ param-1.4.2.tar.gz -> param-1.5.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/PKG-INFO new/param-1.5.1/PKG-INFO --- old/param-1.4.2/PKG-INFO 2016-10-14 22:44:37.000000000 +0200 +++ new/param-1.5.1/PKG-INFO 2017-04-26 15:48:48.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: param -Version: 1.4.2 +Version: 1.5.1 Summary: Declarative Python programming using Parameters. Home-page: http://ioam.github.com/param/ Author: IOAM diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/numbergen/__init__.py new/param-1.5.1/numbergen/__init__.py --- old/param-1.4.2/numbergen/__init__.py 2016-10-14 22:37:41.000000000 +0200 +++ new/param-1.5.1/numbergen/__init__.py 2017-04-26 15:16:31.000000000 +0200 @@ -14,7 +14,7 @@ from param.version import Version -__version__ = Version(release=(1,4,2), fpath=__file__, +__version__ = Version(release=(1,5,1), fpath=__file__, commit="$Format:%h$", reponame="param") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/param/__init__.py new/param-1.5.1/param/__init__.py --- old/param-1.4.2/param/__init__.py 2016-10-14 22:37:50.000000000 +0200 +++ new/param-1.5.1/param/__init__.py 2017-04-26 12:39:28.000000000 +0200 @@ -17,7 +17,10 @@ """ import os.path +import sys import glob +import re +import datetime as dt from .parameterized import Parameterized, Parameter, String, \ descendents, ParameterizedFunction, ParamOverrides @@ -25,7 +28,7 @@ from .parameterized import logging_level # pyflakes:ignore (needed for eval) from .parameterized import shared_parameters # pyflakes:ignore (needed for eval) -try: +try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict @@ -38,11 +41,22 @@ # only two required files. try: from .version import Version - __version__ = Version(release=(1,4,2), fpath=__file__, + __version__ = Version(release=(1,5,1), fpath=__file__, commit="$Format:%h$", reponame="param") except: - __version__ = '1.4.2-unknown' + __version__ = '1.5.1-unknown' + +dt_types = (dt.datetime,) + +try: + import numpy as np + dt_types = dt_types + (np.datetime64,) +except: + pass + +if sys.version_info[0] >= 3: + unicode = str #: Top-level object to allow messaging not tied to a particular #: Parameterized object, as in 'param.main.warning("Invalid option")'. @@ -66,6 +80,34 @@ return value_obj +def as_unicode(obj): + """ + Safely casts any object to unicode including regular string + (i.e. bytes) types in python 2. + """ + if sys.version_info.major < 3 and isinstance(obj, str): + obj = obj.decode('utf-8') + return unicode(obj) + + +def named_objs(objlist): + """ + Given a list of objects, returns a dictionary mapping from + string name for the object to the object itself. + """ + objs = OrderedDict() + for obj in objlist: + if hasattr(obj, "name"): + k = obj.name + elif hasattr(obj, '__name__'): + k = obj.__name__ + else: + k = as_unicode(obj) + objs[k] = obj + return objs + + + class Infinity(object): """ An instance of this class represents an infinite value. Unlike @@ -573,7 +615,7 @@ super(Number,self).__set__(obj,val) - # Allow softbounds to be used like a normal attribute, as it + # Allow softbounds to be used like a normal attribute, as it # probably should have been already (not _softbounds) @property def softbounds(self): return self._softbounds @@ -987,14 +1029,38 @@ attrib_name = self._attrib_name except AttributeError: attrib_name = "" - raise ValueError("%s not in Parameter %s's list of possible objects" \ - %(val,attrib_name)) + + items = [] + limiter = ']' + length = 0 + for item in self.objects: + string = str(item) + length += len(string) + if length < 200: + items.append(string) + else: + limiter = ', ...]' + break + items = '[' + ', '.join(items) + limiter + raise ValueError("%s not in Parameter %s's list of possible objects, " + "valid options include %s"%(val,attrib_name, items)) + + def _ensure_value_is_in_objects(self,val): + """ + Make sure that the provided value is present on the objects list. + Subclasses can override if they support multiple items on a list, + to check each item instead. + """ + + if not (val in self.objects): + self.objects.append(val) def __set__(self,obj,val): if self.check_on_set: self._check_value(val,obj) - elif not (val in self.objects): - self.objects.append(val) + else: + self._ensure_value_is_in_objects(val) + super(ObjectSelector,self).__set__(obj,val) @@ -1004,9 +1070,7 @@ (Returns the dictionary {object.name:object}.) """ - return OrderedDict((obj.name if hasattr(obj,"name") \ - else obj.__name__ if hasattr(obj,"__name__") \ - else str(obj), obj) for obj in self.objects) + return named_objs(self.objects) class ClassSelector(Selector): @@ -1028,16 +1092,20 @@ def _check_value(self,val,obj=None): """val must be None, an instance of self.class_ if self.is_instance=True or a subclass of self_class if self.is_instance=False""" + if isinstance(self.class_, tuple): + class_name = ('(%s)' % ', '.join(cl.__name__ for cl in self.class_)) + else: + class_name = self.class_.__name__ if self.is_instance: if not (isinstance(val,self.class_)) and not (val is None and self.allow_None): raise ValueError( "Parameter '%s' value must be an instance of %s, not '%s'" % - (self._attrib_name, self.class_.__name__, val)) + (self._attrib_name, class_name, val)) else: if not (val is None and self.allow_None) and not (issubclass(val,self.class_)): raise ValueError( "Parameter '%s' must be a subclass of %s, not '%s'" % - (val.__name__, self.class_.__name__, val.__class__.__name__)) + (val.__name__, class_name, val.__class__.__name__)) def __set__(self,obj,val): @@ -1417,6 +1485,9 @@ for o in val: super(ListSelector, self)._check_value(o, obj) + def _ensure_value_is_in_objects(self,val): + for o in val: + super(ListSelector, self)._ensure_value_is_in_objects(o) class MultiFileSelector(ListSelector): @@ -1440,3 +1511,119 @@ return abbreviate_paths(self.path,super(MultiFileSelector, self).get_range()) +class Date(Number): + """ + Date parameter of datetime type. + """ + + def __init__(self, default=None, **kwargs): + super(Date, self).__init__(default=default, **kwargs) + + def _check_value(self,val): + """ + Checks that the value is numeric and that it is within the hard + bounds; if not, an exception is raised. + """ + if self.allow_None and val is None: + return + + if not isinstance(val, dt_types) and not (self.allow_None and val is None): + raise ValueError("Date '%s' only takes datetime types."%self._attrib_name) + + self._checkBounds(val) + + +class Color(Parameter): + """ + Color parameter defined as a hex RGB string with an optional # + prefix. + """ + + def __init__(self, default=None, allow_None=False, **kwargs): + super(Color, self).__init__(default=default, **kwargs) + self._check_value(default) + + def _check_value(self,val): + if (self.allow_None and val is None): + return + if not isinstance(val, String.basestring): + raise ValueError("Color '%s' only takes a string value."%self._attrib_name) + if not re.match('^#?(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$', val): + raise ValueError("Color '%s' only accepts valid RGB hex codes." + % self._attrib_name) + + def __set__(self,obj,val): + self._check_value(val) + super(Color,self).__set__(obj,val) + + + +class Range(NumericTuple): + "A numeric range with optional bounds and softbounds" + + __slots__ = ['bounds', 'inclusive_bounds', 'softbounds'] + + + def __init__(self,default=None, bounds=None, softbounds=None, + inclusive_bounds=(True,True), **params): + self.bounds = bounds + self.inclusive_bounds = inclusive_bounds + self.softbounds = softbounds + super(Range,self).__init__(default=default,length=2,**params) + + + def _check(self,val): + """ + Checks that the value is numeric and that it is within the hard + bounds; if not, an exception is raised. + """ + if self.allow_None and val is None: + return + super(Range, self)._check(val) + + self._checkBounds(val) + + + def get_soft_bounds(self): + """ + For each soft bound (upper and lower), if there is a defined bound (not equal to None) + then it is returned, otherwise it defaults to the hard bound. The hard bound could still be None. + """ + if self.bounds is None: + hl,hu=(None,None) + else: + hl,hu=self.bounds + + if self.softbounds is None: + sl,su=(None,None) + else: + sl,su=self.softbounds + + + if sl is None: l = hl + else: l = sl + + if su is None: u = hu + else: u = su + + return (l,u) + + + def rangestr(self): + vmin, vmax = self.bounds + incmin, incmax = self.inclusive_bounds + incmin = '[' if incmin else '(' + incmax = ']' if incmax else ')' + return '%s%s, %s%s' % (incmin, vmin, vmax, incmax) + + + def _checkBounds(self, val): + if self.bounds is not None: + vmin,vmax = self.bounds + incmin,incmax = self.inclusive_bounds + for bound, v in zip(['lower', 'upper'], val): + too_low = (vmin is not None) and (v < vmin if incmin else v <= vmin) + too_high = (vmax is not None) and (v > vmax if incmax else v >= vmax) + if too_low or too_high: + raise ValueError("Parameter '%s' %s bound must be in range %s" + % (self._attrib_name, bound, self.rangestr())) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/param/parameterized.py new/param-1.5.1/param/parameterized.py --- old/param-1.4.2/param/parameterized.py 2016-10-14 21:23:38.000000000 +0200 +++ new/param-1.5.1/param/parameterized.py 2017-04-26 14:38:21.000000000 +0200 @@ -1351,7 +1351,7 @@ warning_count+=1 self.__db_print(WARNING,msg,*args,**kw) else: - raise Exception(' '.join(["Warning:",]+[str(x) for x in args])) + raise Exception("Warning: " + msg % args) def message(self,msg,*args,**kw): @@ -1802,6 +1802,15 @@ else: dict.__setattr__(self,name,val) + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __contains__(self, key): + return key in self.__dict__ or key in self._overridden.params() + def _check_params(self,params): """ Print a warning if params contains something that is not a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/param/version.py new/param-1.5.1/param/version.py --- old/param-1.4.2/param/version.py 2016-10-14 22:30:18.000000000 +0200 +++ new/param-1.5.1/param/version.py 2017-04-26 15:41:31.000000000 +0200 @@ -197,7 +197,7 @@ output = run_cmd([cmd, 'remote', '-v'], cwd=os.path.dirname(self.fpath)) repo_matches = ['/' + self.reponame + '.git' , - # A remote 'server:reponame.git' can also be referred + # A remote 'server:reponame.git' can also be referred # to (i.e. cloned) as `server:reponame`. '/' + self.reponame + ' '] if not any(m in output for m in repo_matches): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/param.egg-info/PKG-INFO new/param-1.5.1/param.egg-info/PKG-INFO --- old/param-1.4.2/param.egg-info/PKG-INFO 2016-10-14 22:44:37.000000000 +0200 +++ new/param-1.5.1/param.egg-info/PKG-INFO 2017-04-26 15:48:47.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: param -Version: 1.4.2 +Version: 1.5.1 Summary: Declarative Python programming using Parameters. Home-page: http://ioam.github.com/param/ Author: IOAM diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/setup.cfg new/param-1.5.1/setup.cfg --- old/param-1.4.2/setup.cfg 2016-10-14 22:44:37.000000000 +0200 +++ new/param-1.5.1/setup.cfg 2017-04-26 15:48:48.000000000 +0200 @@ -4,5 +4,4 @@ [egg_info] tag_build = tag_date = 0 -tag_svn_revision = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.4.2/setup.py new/param-1.5.1/setup.py --- old/param-1.4.2/setup.py 2016-10-14 22:37:34.000000000 +0200 +++ new/param-1.5.1/setup.py 2017-04-26 15:28:11.000000000 +0200 @@ -20,7 +20,7 @@ setup_args.update(dict( name='param', - version="1.4.2", + version="1.5.1", description='Declarative Python programming using Parameters.', long_description=open('README.rst').read() if os.path.isfile('README.rst') else 'Consult README.rst', author= "IOAM",
