Hello community, here is the log from the commit of package python-param for openSUSE:Factory checked in at 2018-04-19 15:31:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-param (Old) and /work/SRC/openSUSE:Factory/.python-param.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-param" Thu Apr 19 15:31:22 2018 rev:3 rq:597608 version:1.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-param/python-param.changes 2017-08-18 15:06:06.751716657 +0200 +++ /work/SRC/openSUSE:Factory/.python-param.new/python-param.changes 2018-04-19 15:31:24.946311598 +0200 @@ -1,0 +2,6 @@ +Wed Apr 18 02:07:38 UTC 2018 - toddrme2...@gmail.com + +- Update to version 1.6.0 + * Drop Cython build + +------------------------------------------------------------------- Old: ---- param-1.5.1.tar.gz New: ---- param-1.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-param.spec ++++++ --- /var/tmp/diff_new_pack.2m6d1r/_old 2018-04-19 15:31:25.490289239 +0200 +++ /var/tmp/diff_new_pack.2m6d1r/_new 2018-04-19 15:31:25.490289239 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-param # -# Copyright (c) 2017 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2018 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 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-param -Version: 1.5.1 +Version: 1.6.0 Release: 0 Summary: Declarative Python programming using Parameters License: BSD-3-Clause @@ -27,10 +27,10 @@ Source: https://files.pythonhosted.org/packages/source/p/param/param-%{version}.tar.gz BuildRequires: fdupes BuildRequires: python-rpm-macros -BuildRequires: %{python_module Cython} BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} -Recommends: python-jupyter_ipython +Recommends: python-numpy +BuildArch: noarch %python_subpackages %description @@ -52,13 +52,13 @@ %install %python_install -%python_expand %fdupes %{buildroot}%{$python_sitearch} +%python_expand %fdupes %{buildroot}%{$python_sitelib} %files %{python_files} %defattr(-,root,root,-) %doc LICENSE.txt README.rst -%{python_sitearch}/param/ -%{python_sitearch}/numbergen/ -%{python_sitearch}/param-%{version}-py*.egg-info +%{python_sitelib}/param/ +%{python_sitelib}/numbergen/ +%{python_sitelib}/param-%{version}-py*.egg-info %changelog ++++++ param-1.5.1.tar.gz -> param-1.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/LICENSE.txt new/param-1.6.0/LICENSE.txt --- old/param-1.5.1/LICENSE.txt 2015-10-27 04:15:07.000000000 +0100 +++ new/param-1.6.0/LICENSE.txt 2018-04-05 12:24:35.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright (c) 2005-2015, IOAM (ioam.github.com) +Copyright (c) 2005-2018, IOAM (ioam.github.com) All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/MANIFEST.in new/param-1.6.0/MANIFEST.in --- old/param-1.5.1/MANIFEST.in 2015-10-27 04:15:07.000000000 +0100 +++ new/param-1.6.0/MANIFEST.in 2018-04-05 12:24:35.000000000 +0200 @@ -1,5 +1,6 @@ include README.rst include LICENSE.txt include setup.py +include param/.version recursive-include param *.py recursive-include numbergen *.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/PKG-INFO new/param-1.6.0/PKG-INFO --- old/param-1.5.1/PKG-INFO 2017-04-26 15:48:48.000000000 +0200 +++ new/param-1.6.0/PKG-INFO 2018-04-05 12:25:08.000000000 +0200 @@ -1,12 +1,14 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: param -Version: 1.5.1 +Version: 1.6.0 Summary: Declarative Python programming using Parameters. Home-page: http://ioam.github.com/param/ Author: IOAM Author-email: develop...@topographica.org +Maintainer: IOAM +Maintainer-email: develop...@topographica.org License: BSD -Description: |BuildStatus|_ |PyPIVersion|_ |PyVersion|_ |License|_ +Description: |LinuxTests|_ |WinTests|_ |Coverage|_ |PyPIVersion|_ |PyVersion|_ |License|_ Param ===== @@ -24,8 +26,14 @@ Please see `param's website <http://ioam.github.com/param/>`_ for official releases, installation instructions, documentation, and examples. - .. |BuildStatus| image:: https://travis-ci.org/ioam/param.svg?branch=master - .. _BuildStatus: https://travis-ci.org/ioam/param + .. |LinuxTests| image:: https://travis-ci.org/ioam/param.svg?branch=master + .. _LinuxTests: https://travis-ci.org/ioam/param + + .. |WinTests| image:: https://ci.appveyor.com/api/projects/status/huoiwwamso2or7xw/branch/master?svg=true + .. _WinTests: https://ci.appveyor.com/project/Ioam/param/branch/master + + .. |Coverage| image:: https://img.shields.io/coveralls/ioam/param.svg + .. _Coverage: https://coveralls.io/r/ioam/param?branch=master .. |PyPIVersion| image:: http://img.shields.io/pypi/v/param.svg .. _PyPIVersion: https://pypi.python.org/pypi/param @@ -42,12 +50,12 @@ Classifier: License :: OSI Approved :: BSD License Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Operating System :: OS Independent Classifier: Intended Audience :: Science/Research Classifier: Intended Audience :: Developers @@ -56,3 +64,6 @@ Classifier: Topic :: Software Development :: Libraries Provides: param Provides: numbergen +Requires-Python: >=2.7 +Provides-Extra: tests +Provides-Extra: all diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/README.rst new/param-1.6.0/README.rst --- old/param-1.5.1/README.rst 2016-04-07 01:28:09.000000000 +0200 +++ new/param-1.6.0/README.rst 2018-04-05 12:24:35.000000000 +0200 @@ -1,4 +1,4 @@ -|BuildStatus|_ |PyPIVersion|_ |PyVersion|_ |License|_ +|LinuxTests|_ |WinTests|_ |Coverage|_ |PyPIVersion|_ |PyVersion|_ |License|_ Param ===== @@ -16,8 +16,14 @@ Please see `param's website <http://ioam.github.com/param/>`_ for official releases, installation instructions, documentation, and examples. -.. |BuildStatus| image:: https://travis-ci.org/ioam/param.svg?branch=master -.. _BuildStatus: https://travis-ci.org/ioam/param +.. |LinuxTests| image:: https://travis-ci.org/ioam/param.svg?branch=master +.. _LinuxTests: https://travis-ci.org/ioam/param + +.. |WinTests| image:: https://ci.appveyor.com/api/projects/status/huoiwwamso2or7xw/branch/master?svg=true +.. _WinTests: https://ci.appveyor.com/project/Ioam/param/branch/master + +.. |Coverage| image:: https://img.shields.io/coveralls/ioam/param.svg +.. _Coverage: https://coveralls.io/r/ioam/param?branch=master .. |PyPIVersion| image:: http://img.shields.io/pypi/v/param.svg .. _PyPIVersion: https://pypi.python.org/pypi/param diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/numbergen/__init__.py new/param-1.6.0/numbergen/__init__.py --- old/param-1.5.1/numbergen/__init__.py 2017-04-26 15:16:31.000000000 +0200 +++ new/param-1.6.0/numbergen/__init__.py 2018-04-05 12:24:35.000000000 +0200 @@ -13,10 +13,7 @@ import param -from param.version import Version -__version__ = Version(release=(1,5,1), fpath=__file__, - commit="$Format:%h$", reponame="param") - +from param import __version__ # noqa: API import class TimeAware(param.Parameterized): """ @@ -727,8 +724,8 @@ def __call__(self): val = self.generator() min_, max_ = self.bounds - if min_ != None and val < min_: return min_ - elif max_ != None and val > max_: return max_ + if min_ is not None and val < min_: return min_ + elif max_ is not None and val > max_: return max_ else: return val diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param/.version new/param-1.6.0/param/.version --- old/param-1.5.1/param/.version 1970-01-01 01:00:00.000000000 +0100 +++ new/param-1.6.0/param/.version 2018-04-05 12:25:07.000000000 +0200 @@ -0,0 +1 @@ +{"git_describe": "v1.6.0-0-g445d051", "version_string": "1.6.0"} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param/__init__.py new/param-1.6.0/param/__init__.py --- old/param-1.5.1/param/__init__.py 2017-04-26 12:39:28.000000000 +0200 +++ new/param-1.6.0/param/__init__.py 2018-04-05 12:24:35.000000000 +0200 @@ -25,15 +25,10 @@ from .parameterized import Parameterized, Parameter, String, \ descendents, ParameterizedFunction, ParamOverrides -from .parameterized import logging_level # pyflakes:ignore (needed for eval) -from .parameterized import shared_parameters # pyflakes:ignore (needed for eval) +from .parameterized import logging_level # noqa: api import +from .parameterized import shared_parameters # noqa: api import -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict -except ImportError as e: - raise ImportError("Requires ordereddict package on Python 2.6") +from collections import OrderedDict # Determine up-to-date version information, if possible, but with a @@ -41,10 +36,9 @@ # only two required files. try: from .version import Version - __version__ = Version(release=(1,5,1), fpath=__file__, - commit="$Format:%h$", reponame="param") + __version__ = str(Version(fpath=__file__, archive_commit="$Format:%h$", reponame="param")) except: - __version__ = '1.5.1-unknown' + __version__ = "0.0.0+unknown" dt_types = (dt.datetime,) @@ -449,7 +443,7 @@ dynamic = callable(val) if dynamic: self._initialize_generator(val,obj) - if not obj: self._set_instantiate(dynamic) + if obj is None: self._set_instantiate(dynamic) def _produce_value(self,gen,force=False): @@ -744,6 +738,9 @@ class Integer(Number): """Numeric Parameter required to be an Integer""" + def __init__(self,default=0,**params): + Number.__init__(self,default=default,**params) + def _check_value(self,val): if self.allow_None and val is None: return @@ -927,7 +924,7 @@ """ Return the values of all the attribs, as a list. """ - if not obj: + if obj is None: return [getattr(objtype,a) for a in self.attribs] else: return [getattr(obj,a) for a in self.attribs] @@ -938,7 +935,7 @@ """ assert len(val) == len(self.attribs),"Compound parameter '%s' got the wrong number of values (needed %d, but got %d)." % (self._attrib_name,len(self.attribs),len(val)) - if not obj: + if obj is None: for a,v in zip(self.attribs,val): setattr(self.objtype,a,v) else: @@ -1478,8 +1475,8 @@ if self.default is None and callable(self.compute_default_fn): self.default = self.compute_default_fn() for o in self.default: - if self.default not in self.objects: - self.objects.append(self.default) + if o not in self.objects: + self.objects.append(o) def _check_value(self, val, obj=None): for o in val: @@ -1627,3 +1624,28 @@ if too_low or too_high: raise ValueError("Parameter '%s' %s bound must be in range %s" % (self._attrib_name, bound, self.rangestr())) + + +class DateRange(Range): + """ + A date range specified as (start_date, end_date). + + Dates must be specified as datetime-like types (see + param.dt_types). + """ + def _check(self,val): + if self.allow_None and val is None: + return + + for n in val: + if not isinstance(n, dt_types): + raise ValueError("DateRange '%s' only takes datetime types: %s"%(self._attrib_name,val)) + + start, end = val + if not end >= start: + raise ValueError("DateRange '%s': end date %s is before start date %s."%(self._attrib_name,val[1],val[0])) + + # Calling super(DateRange, self)._check(val) would also check + # values are numeric, which is redundant, so just call + # _checkBounds(). + self._checkBounds(val) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param/parameterized.py new/param-1.6.0/param/parameterized.py --- old/param-1.5.1/param/parameterized.py 2017-04-26 14:38:21.000000000 +0200 +++ new/param-1.6.0/param/parameterized.py 2018-04-05 12:24:35.000000000 +0200 @@ -522,12 +522,12 @@ A simple String parameter. """ - basestring = basestring if sys.version_info[0]==2 else str + basestring = basestring if sys.version_info[0]==2 else str # noqa: it is defined def __init__(self, default="", allow_None=False, **kwargs): super(String, self).__init__(default=default, allow_None=allow_None, **kwargs) self._check_value(default) - self.allow_None = allow_None + self.allow_None = (default is None or allow_None) def _check_value(self,val): if not isinstance(val, self.basestring) and not (self.allow_None and val is None): @@ -1441,21 +1441,24 @@ setattr(self,name,val) - def get_param_values(self,onlychanged=False): + @bothmethod + def get_param_values(self_or_cls,onlychanged=False): """ Return a list of name,value pairs for all Parameters of this object. - If onlychanged is True, will only return values that are not - equal to the default value. + When called on an instance with onlychanged set to True, will + only return values that are not equal to the default value + (onlychanged has no effect when called on a class). """ # CEB: we'd actually like to know whether a value has been # explicitly set on the instance, but I'm not sure that's easy # (would need to distinguish instantiation of default from # user setting of value). vals = [] - for name,val in self.params().items(): - value = self.get_value_generator(name) + for name,val in self_or_cls.params().items(): + value = self_or_cls.get_value_generator(name) + # (this is pointless for cls) if not onlychanged or not all_equal(value,val.default): vals.append((name,value)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param/version.py new/param-1.6.0/param/version.py --- old/param-1.5.1/param/version.py 2017-04-26 15:41:31.000000000 +0200 +++ new/param-1.6.0/param/version.py 2018-04-05 12:24:35.000000000 +0200 @@ -1,4 +1,14 @@ -""" +"""Apart from this first paragraph, this version.py file is an exact +copy of https://github.com/ioam/autover/blob/59c207db70da6f41b689e8be5c5f6abb1e062c8e/autover/version.py. +Autover's version.py is included inside the param package only to make +version.py available to various other projects that use version.py and +already depend on param, thus saving them from bundling version.py or +dependending on autover. Otherwise, version.py would only be in the +root of param's git repository, and would not be part of the param +package. + +----- + Provide consistent and up-to-date ``__version__`` strings for Python packages. @@ -8,14 +18,14 @@ especially if releases are infrequent. This file provides a Version class that addresses both problems. -Version is meant to be a simple, bare-bones approach that focuses on -(a) ensuring that all declared version information matches for a -release, and (b) providing fine-grained version information via a -version control system (VCS) in between releases. Other approaches -like versioneer.py can automate more of the process of making -releases, but they require more complex self-modifying code and code -generation techniques than the simple Python class declaration used -here. +Version is meant to be a simple, bare-bones approach that focuses on (a) +ensuring that all declared version information matches for a release if +supplied, and (b) providing fine-grained version information via a +version control system (VCS) in between releases (c) allowing versions +to be specified with tags alone. Other approaches like versioneer.py +can automate more of the process of making releases, but they require +more complex self-modifying code and code generation techniques than the +simple Python class declaration used here. Currently, the only VCS supported is git, but others could be added easily. @@ -24,24 +34,36 @@ ``package`` maintained in a git repository named ``packagegit``: 1. Make the Version class available for import from your package, - either by adding the PyPI package "param" as a dependency for your - package, or by simply copying this file into ``package/version.py``. + either by adding the PyPI package "autover" as a dependency for your + package, or by simply copying this file into ``package/autover.py``. -2. Assuming that the current version of your package is 1.0.0, add the - following lines to your ``package/__init__.py``:: +2. Assuming that the current version of your package is 1.0.0 (and you + want to enforce this), add the following lines to your + ``package/__init__.py``:: - from param import Version + from autover import Version __version__ = Version(release=(1,0,0), fpath=__file__, commit="$Format:%h$", reponame="packagegit") (or ``from .version import Version`` if you copied the file directly.) + You can supply release=None if you want to set the version purely via a tag. + 3. Declare the version as a string in your package's setup.py file, e.g.:: setup_args["version"]="1.0.0" -4. In your package's setup.py script code for making a release, add a - call to the Version.verify method. E.g.:: + This acts as an explicit check you can verify against. You can also set this + up against the tag using: + + setup_args["version"]=get_setup_version("autover") # Your package name here + + To use this, adapt the get_setup_version function in autover/setup.py for use + in your package's setup.py. + + +4. (Optional) In your package's setup.py script code for making a + release, you can add a call to the Version.verify method. E.g.:: setup_args = dict(name='package', version="1.0.0", ...) @@ -51,36 +73,54 @@ package.__version__.verify(setup_args['version']) setup(**setup_args) + This can help make sure the repository is in a good state before + building a package (e.g not dirty). + 4. Tag the version of the repository to be released with a string of - the form v*.*, i.e. ``v1.0.0`` in this example. E.g. for git:: + the form v*.*.*, i.e. ``v1.0.0`` in this example. E.g. for git:: git tag -a v1.0.0 -m 'Release version 1.0.0' ; git push - -Now when you run ``setup.py`` to make a release via something like -``python setup.py register sdist upload``, Python will verify that the -version last tagged in the VCS is the same as what is declared in the -package and also in setup.py, aborting the release until either the -tag is corrected or the declared version is made to match the tag. -Releases installed without VCS information will then report the -declared release version. If VCS information is available and matches -the specified repository name, then the version reported from -e.g. ``str(package.__version__)`` will provide more detailed -information about the precise VCS revision changes since the release. -See the docstring for the Version class for more detailed information. + You need to use an annotated tag (i.e the -a flag) and you can use + PEP440 compliant strings as long as they start with a 'v' e.g + v1.0.1a1 v2.3rc5 etc. + +If you chose to specify explicit version strings in setup.py and +__init__.py and used the verify method, running ``setup.py`` to make a +release via something like ``python setup.py register sdist upload``, +Python will verify that the version last tagged in the VCS is the same +as what is declared in the package and the setup.py, aborting the +release until either the tag is corrected or the declared version is +made to match the tag. + +Releases installed without VCS information will then report the declared +release version if specified, otherwise it will read the .version file +containing the VSC information when the package was build . If live VCS +information is available and matches the specified repository name, then +the version reported from e.g. ``str(package.__version__)`` will provide +more detailed information about the precise VCS revision changes since +the release. See the docstring for the Version class for more detailed +information. + +If you used release=None in __init__.py and the get_setup_version +function in setup.py, all you need to get a live version string is set +an appropriate VCS tag. Note that to ensure this is always correct, +autover is required as a build dependency, otherwise the information +available in the .version file is used. This file is in the public domain, provided as-is, with no warranty of any kind expressed or implied. Anyone is free to copy, modify, publish, use, compile, sell, or distribute it under any license, for any purpose, commercial or non-commercial, and by any means. The original file is maintained at: -https://github.com/ioam/param/blob/master/param/version.py +https://github.com/ioam/autover/blob/master/autover/__init__.py + """ __author__ = 'Jean-Luc Stevens' -import os, subprocess +import os, subprocess, json def run_cmd(args, cwd=None): proc = subprocess.Popen(args, stdout=subprocess.PIPE, @@ -92,6 +132,8 @@ raise Exception(proc.returncode, error) return output + + class Version(object): """ A simple approach to Python package versioning that supports PyPI @@ -104,45 +146,72 @@ two or three numeric versioning levels typical. During development, a command like ``git describe`` will be used to - compute the number of commits since the last version tag, the - short commit hash, and whether the commit is dirty (has changes - not yet committed). Version tags must start with a lowercase 'v' - and have a period in them, e.g. v2.0, v0.9.8, v0.1a, or v0.2beta. - Note that any non-numeric portion of the version ("a", "beta", - etc.) will currently be discarded for the purposes of numeric - comparisons. + compute the number of commits since the last version tag, the short + commit hash, and whether the commit is dirty (has changes not yet + committed). Version tags must start with a lowercase 'v' and have a + period in them, e.g. v2.0, v0.9.8 or v0.1 and may include the PEP440 + prerelease identifiers of 'a' (alpha) 'b' (beta) or 'rc' (release + candidate) allowing tags such as v2.0.a3, v0.9.8.b3 or v0.1.rc5. Also note that when version control system (VCS) information is - used, the comparison operators take into account the number of - commits since the last version tag. This approach is often useful - in practice to decide which version is newer for a single - developer, but will not necessarily be reliable when comparing - against a different fork or branch in a distributed VCS. + used, the number of commits since the last version tag is + determined. This approach is often useful in practice to decide + which version is newer for a single developer, but will not + necessarily be reliable when comparing against a different fork or + branch in a distributed VCS. For git, if you want version control information available even in an exported archive (e.g. a .zip file from GitHub), you can set the following line in the .gitattributes file of your project:: __init__.py export-subst - """ - def __init__(self, release=None, fpath=None, commit=None, reponame=None, commit_count=0): + Note that to support pip installation directly from GitHub via git + archive, a .version file must be tracked by the repo to supply the + release number (otherwise only the short SHA is available). + + The PEP440 format returned is [N!]N(.N)*[{a|b|rc}N][.postN+SHA] + where everything before .postN is obtained from the tag, the N in + .postN is the number of commits since the last tag and the SHA is + obtained via git describe. This later portion is only shown if the + commit count since the last tag is non zero. Instead of '.post', an + alternate valid prefix such as '.rev', '_rev', '_r' or '.r' may be + supplied.""" + + def __init__(self, release=None, fpath=None, commit=None, reponame=None, + commit_count_prefix='.post', archive_commit=None, **kwargs): """ :release: Release tuple (corresponding to the current VCS tag) :commit Short SHA. Set to '$Format:%h$' for git archive support. :fpath: Set to ``__file__`` to access version control information :reponame: Used to verify VCS repository name. - :commit_count Commits since last release. Set for dev releases. """ self.fpath = fpath self._expected_commit = commit + + if release is not None or 'commit_count' in kwargs: + print('WARNING: param.Version now supports PEP440 and a new tag based workflow. See param/version.py for more details') + self.expected_release = release - self._commit = None if commit in [None, "$Format:%h$"] else commit - self._commit_count = commit_count + self._commit = None if (commit is None or commit.startswith("$Format")) else commit + self._commit_count = None self._release = None self._dirty = False + self._prerelease = None + + self.archive_commit= archive_commit + self.reponame = reponame + self.commit_count_prefix = commit_count_prefix + + @property + def prerelease(self): + """ + Either None or one of 'aN' (alpha), 'bN' (beta) or 'rcN' + (release candidate) where N is an integer. + """ + return self.fetch()._prerelease @property def release(self): @@ -188,37 +257,103 @@ return self - def git_fetch(self, cmd='git'): + def git_fetch(self, cmd='git', as_string=False): + commit_argument = self._commit + output = None try: if self.reponame is not None: # Verify this is the correct repository (since fpath could - # be an unrelated git repository, and param could just have + # be an unrelated git repository, and autover could just have # been copied/installed into it). output = run_cmd([cmd, 'remote', '-v'], cwd=os.path.dirname(self.fpath)) - repo_matches = ['/' + self.reponame + '.git' , + repo_matches = ['', # No remote set + '/' + self.reponame + '.git' , # 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): return self - output = run_cmd([cmd, 'describe', '--long', '--match', 'v*.*', '--dirty'], + output = run_cmd([cmd, 'describe', '--long', '--match', + "v[0-9]*.[0-9]*.[0-9]*", '--dirty'], cwd=os.path.dirname(self.fpath)) - except Exception as e: - if e.args[1] == 'fatal: No names found, cannot describe anything.': - raise Exception("Cannot find any git version tags of format v*.*") - # If there is any other error, return (release value still useful) - return self + if as_string: return output + except Exception as e1: + try: + output = self._output_from_file() + if output is not None: + self._update_from_vcs(output) + if self._known_stale(): + self._commit_count = None + if as_string: return output + + # If an explicit commit was supplied (e.g from git + # archive), it should take precedence over the file. + if commit_argument: + self._commit = commit_argument + return + + except IOError: + if e1.args[1] == 'fatal: No names found, cannot describe anything.': + raise Exception("Cannot find any git version tags of format v*.*") + # If there is any other error, return (release value still useful) + return self + + self._update_from_vcs(output) + + + def _known_stale(self): + """ + The commit is known to be from a file (and therefore stale) if a + SHA is supplied by git archive and doesn't match the parsed commit. + """ + if self._output_from_file() is None: + commit = None + else: + commit = self.commit + known_stale = (self.archive_commit is not None + and not self.archive_commit.startswith('$Format') + and self.archive_commit != commit) + if known_stale: self._commit_count = None + return known_stale + + def _output_from_file(self, entry='git_describe'): + """ + Read the version from a .version file that may exist alongside __init__.py. + + This file can be generated by piping the following output to file: + + git describe --long --match v*.* + """ + try: + vfile = os.path.join(os.path.dirname(self.fpath), '.version') + with open(vfile, 'r') as f: + return json.loads(f.read()).get(entry, None) + except: # File may be missing if using pip + git archive + return None + + + def _update_from_vcs(self, output): + "Update state based on the VCS state e.g the output of git describe" split = output[1:].split('-') - self._release = tuple(int(el) for el in split[0].split('.')) + dot_split = split[0].split('.') + for prefix in ['a','b','rc']: + if prefix in dot_split[-1]: + prefix_split = dot_split[-1].split(prefix) + self._prerelease = prefix + prefix_split[-1] + dot_split[-1] = prefix_split[0] + + + self._release = tuple(int(el) for el in dot_split) self._commit_count = int(split[1]) + self._commit = str(split[2][1:]) # Strip out 'g' prefix ('g'=>'git') + self._dirty = (split[-1]=='dirty') return self - def __str__(self): """ Version in x.y.z string format. Does not include the "v" @@ -231,48 +366,49 @@ (with "v" prefix removed). """ - if self.release is None: return 'None' + known_stale = self._known_stale() + if self.release is None and not known_stale: + extracted_directory_tag = self._output_from_file(entry='extracted_directory_tag') + return 'None' if extracted_directory_tag is None else extracted_directory_tag + elif self.release is None and known_stale: + extracted_directory_tag = self._output_from_file(entry='extracted_directory_tag') + if extracted_directory_tag is not None: + return extracted_directory_tag + return '0.0.0+g{SHA}-gitarchive'.format(SHA=self.archive_commit) + release = '.'.join(str(el) for el in self.release) + prerelease = '' if self.prerelease is None else self.prerelease - if (self._expected_commit is not None) and ("$Format" not in self._expected_commit): - pass # Concrete commit supplied - print full version string - elif (self.commit_count == 0 and not self.dirty): - return release - - dirty_status = '-dirty' if self.dirty else '' - return '%s-%s-g%s%s' % (release, self.commit_count if self.commit_count else 'x', - self.commit, dirty_status) + if self.commit_count == 0: + return release + prerelease + + commit = self.commit + dirty = '-dirty' if self.dirty else '' + archive_commit = '' + if known_stale: + archive_commit = '-gitarchive' + commit = self.archive_commit + + if archive_commit != '': + postcount = self.commit_count_prefix + '0' + elif self.commit_count not in [0, None]: + postcount = self.commit_count_prefix + str(self.commit_count) + else: + postcount = '' + + components = [release, prerelease, postcount, + '' if commit is None else '+g' + commit, dirty, + archive_commit] + return ''.join(components) def __repr__(self): return str(self) - def abbrev(self,dev_suffix=""): - """ - Abbreviated string representation, optionally declaring whether it is - a development version. - """ - return '.'.join(str(el) for el in self.release) + \ - (dev_suffix if self.commit_count > 0 or self.dirty else "") - - - - def __eq__(self, other): + def abbrev(self): """ - Two versions are considered equivalent if and only if they are - from the same release, with the same commit count, and are not - dirty. Any dirty version is considered different from any - other version, since it could potentially have any arbitrary - changes even for the same release and commit count. + Abbreviated string representation of just the release number. """ - if self.dirty or other.dirty: return False - return (self.release, self.commit_count) == (other.release, other.commit_count) - - def __gt__(self, other): - return (self.release, self.commit_count) > (other.release, other.commit_count) - - def __lt__(self, other): - return (self.release, self.commit_count) < (other.release, other.commit_count) - + return '.'.join(str(el) for el in self.release) def verify(self, string_version=None): """ @@ -288,11 +424,106 @@ if self.dirty: raise Exception("Current working directory is dirty.") - if self.release != self.expected_release: + if self.expected_release is not None and self.release != self.expected_release: raise Exception("Declared release does not match current release tag.") if self.commit_count !=0: raise Exception("Please update the VCS version tag before release.") - if self._expected_commit not in [None, "$Format:%h$"]: + if (self._expected_commit is not None + and not self._expected_commit.startswith( "$Format")): raise Exception("Declared release does not match the VCS version tag") + + + + @classmethod + def get_setup_version(cls, setup_path, reponame, describe=False, + dirty='raise', archive_commit=None): + """ + Helper for use in setup.py to get the version from the .version file (if available) + or more up-to-date information from git describe (if available). + + Assumes the __init__.py will be found in the directory + {reponame}/__init__.py relative to setup.py. + + If describe is True, the raw string obtained from git described is + returned which is useful for updating the .version file. + + The dirty policy can be one of 'report', 'strip', 'raise'. If it is + 'report' the version string may end in '-dirty' if the repository is + in a dirty state. If the policy is 'strip', the '-dirty' suffix + will be stripped out if present. If the policy is 'raise', an + exception is raised if the repository is in a dirty state. This can + be useful if you want to make sure packages are not built from a + dirty repository state. + """ + policies = ['raise','report', 'strip'] + if dirty not in policies: + raise AssertionError("get_setup_version dirty policy must be in %r" % policies) + + fpath = os.path.join(setup_path, reponame, "__init__.py") + version = Version(fpath=fpath, reponame=reponame, archive_commit=archive_commit) + if describe: + vstring = version.git_fetch(as_string=True) + else: + vstring = str(version) + + if version.dirty and dirty == 'raise': + raise AssertionError('Repository is in a dirty state.') + elif version.dirty and dirty=='strip': + return vstring.replace('-dirty', '') + else: + return vstring + + + @classmethod + def extract_directory_tag(cls, setup_path, reponame): + setup_dir = os.path.split(setup_path)[-1] # Directory containing setup.py + prefix = reponame + '-' # Prefix to match + if setup_dir.startswith(prefix): + tag = setup_dir[len(prefix):] + # Assuming the tag is a version if it isn't empty, 'master' and has a dot in it + if tag not in ['', 'master'] and ('.' in tag): + return tag + return None + + + @classmethod + def setup_version(cls, setup_path, reponame, archive_commit=None, dirty='raise'): + info = {} + git_describe = None + try: + # Will only work if in a git repo and git is available + git_describe = Version.get_setup_version(setup_path, + reponame, + describe=True, + dirty=dirty, + archive_commit=archive_commit) + + if git_describe is not None: + info['git_describe'] = git_describe + except: pass + + if git_describe is None: + extracted_directory_tag = Version.extract_directory_tag(setup_path, reponame) + if extracted_directory_tag is not None: + info['extracted_directory_tag'] = extracted_directory_tag + try: + with open(os.path.join(setup_path, reponame, '.version'), 'w') as f: + f.write(json.dumps({'extracted_directory_tag':extracted_directory_tag})) + except: + print('Error in setup_version: could not write .version file.') + + + info['version_string'] = Version.get_setup_version(setup_path, + reponame, + describe=False, + dirty=dirty, + archive_commit=archive_commit) + try: + with open(os.path.join(setup_path, reponame, '.version'), 'w') as f: + f.write(json.dumps(info)) + except: + print('Error in setup_version: could not write .version file.') + + return info['version_string'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param.egg-info/PKG-INFO new/param-1.6.0/param.egg-info/PKG-INFO --- old/param-1.5.1/param.egg-info/PKG-INFO 2017-04-26 15:48:47.000000000 +0200 +++ new/param-1.6.0/param.egg-info/PKG-INFO 2018-04-05 12:25:08.000000000 +0200 @@ -1,12 +1,14 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: param -Version: 1.5.1 +Version: 1.6.0 Summary: Declarative Python programming using Parameters. Home-page: http://ioam.github.com/param/ Author: IOAM Author-email: develop...@topographica.org +Maintainer: IOAM +Maintainer-email: develop...@topographica.org License: BSD -Description: |BuildStatus|_ |PyPIVersion|_ |PyVersion|_ |License|_ +Description: |LinuxTests|_ |WinTests|_ |Coverage|_ |PyPIVersion|_ |PyVersion|_ |License|_ Param ===== @@ -24,8 +26,14 @@ Please see `param's website <http://ioam.github.com/param/>`_ for official releases, installation instructions, documentation, and examples. - .. |BuildStatus| image:: https://travis-ci.org/ioam/param.svg?branch=master - .. _BuildStatus: https://travis-ci.org/ioam/param + .. |LinuxTests| image:: https://travis-ci.org/ioam/param.svg?branch=master + .. _LinuxTests: https://travis-ci.org/ioam/param + + .. |WinTests| image:: https://ci.appveyor.com/api/projects/status/huoiwwamso2or7xw/branch/master?svg=true + .. _WinTests: https://ci.appveyor.com/project/Ioam/param/branch/master + + .. |Coverage| image:: https://img.shields.io/coveralls/ioam/param.svg + .. _Coverage: https://coveralls.io/r/ioam/param?branch=master .. |PyPIVersion| image:: http://img.shields.io/pypi/v/param.svg .. _PyPIVersion: https://pypi.python.org/pypi/param @@ -42,12 +50,12 @@ Classifier: License :: OSI Approved :: BSD License Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Operating System :: OS Independent Classifier: Intended Audience :: Science/Research Classifier: Intended Audience :: Developers @@ -56,3 +64,6 @@ Classifier: Topic :: Software Development :: Libraries Provides: param Provides: numbergen +Requires-Python: >=2.7 +Provides-Extra: tests +Provides-Extra: all diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param.egg-info/SOURCES.txt new/param-1.6.0/param.egg-info/SOURCES.txt --- old/param-1.5.1/param.egg-info/SOURCES.txt 2017-04-26 15:48:48.000000000 +0200 +++ new/param-1.6.0/param.egg-info/SOURCES.txt 2018-04-05 12:25:08.000000000 +0200 @@ -4,6 +4,7 @@ setup.cfg setup.py numbergen/__init__.py +param/.version param/__init__.py param/ipython.py param/parameterized.py @@ -11,4 +12,5 @@ param.egg-info/PKG-INFO param.egg-info/SOURCES.txt param.egg-info/dependency_links.txt +param.egg-info/requires.txt param.egg-info/top_level.txt \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/param.egg-info/requires.txt new/param-1.6.0/param.egg-info/requires.txt --- old/param-1.5.1/param.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/param-1.6.0/param.egg-info/requires.txt 2018-04-05 12:25:08.000000000 +0200 @@ -0,0 +1,8 @@ + +[all] +flake8 +nose + +[tests] +nose +flake8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/setup.cfg new/param-1.6.0/setup.cfg --- old/param-1.5.1/setup.cfg 2017-04-26 15:48:48.000000000 +0200 +++ new/param-1.6.0/setup.cfg 2018-04-05 12:25:08.000000000 +0200 @@ -1,5 +1,28 @@ -[build_ext] -inplace = 1 +[wheel] +universal = 1 + +[flake8] +include = setup.py param numbergen +exclude = .git,__pycache__,.tox,.eggs,*.egg,doc,dist,build,_build,tests +ignore = E1, + E2, + E3, + E4, + E5, + E701, + E702, + E703, + E704, + E722, + E741, + E742, + E743, + W503 + +[nosetests] +verbosity = 2 +with-doctest = 1 +nologcapture = 1 [egg_info] tag_build = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/param-1.5.1/setup.py new/param-1.6.0/setup.py --- old/param-1.5.1/setup.py 2017-04-26 15:28:11.000000000 +0200 +++ new/param-1.6.0/setup.py 2018-04-05 12:24:35.000000000 +0200 @@ -1,63 +1,71 @@ -#!/usr/bin/env python import os -import sys -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -try: - # check we can compile on this machine - import cython; cython.inline("return 1;") - - from Cython.Build import cythonize - ext_modules = cythonize("param/*.py", exclude=['param/ipython.py']) -except: - ext_modules = [] +from setuptools import setup -setup_args = {} -setup_args.update(dict( +########## autover ########## + +def get_setup_version(reponame): + """Use autover to get up to date version.""" + # importing self into setup.py is unorthodox, but param has no + # required dependencies outside of python + from param.version import Version + return Version.setup_version(os.path.dirname(__file__),reponame,archive_commit="$Format:%h$") + + +########## dependencies ########## + +extras_require = { + # pip doesn't support tests_require + # (https://github.com/pypa/pip/issues/1197) + 'tests': [ + 'nose', + 'flake8', + ] +} + +extras_require['all'] = sorted(set(sum(extras_require.values(), []))) + + +########## metadata for setuptools ########## + +setup_args = dict( name='param', - version="1.5.1", + version=get_setup_version("param"), description='Declarative Python programming using Parameters.', long_description=open('README.rst').read() if os.path.isfile('README.rst') else 'Consult README.rst', - author= "IOAM", - author_email= "develop...@topographica.org", - ext_modules=ext_modules, + author="IOAM", + author_email="develop...@topographica.org", maintainer="IOAM", maintainer_email="develop...@topographica.org", platforms=['Windows', 'Mac OS X', 'Linux'], license='BSD', url='http://ioam.github.com/param/', - packages = ["param","numbergen"], - provides = ["param","numbergen"], - classifiers = [ + packages=["param","numbergen"], + provides=["param","numbergen"], + include_package_data = True, + python_requires=">=2.7", + install_requires=[], + extras_require=extras_require, + tests_require=extras_require['tests'], + classifiers=[ "License :: OSI Approved :: BSD License", "Development Status :: 5 - Production/Stable", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", "Operating System :: OS Independent", "Intended Audience :: Science/Research", "Intended Audience :: Developers", "Natural Language :: English", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Libraries"] -)) - +) if __name__=="__main__": - - if ('upload' in sys.argv) or ('sdist' in sys.argv): - import param, numbergen - param.__version__.verify(setup_args['version']) - numbergen.__version__.verify(setup_args['version']) - setup(**setup_args)