commit 7d26503cb32668c107bef3bae8389170c8ded14b Author: juga0 juga@riseup.net Date: Tue Mar 16 14:28:09 2021 +0000
fix: Move to declarative setup.cfg
Also: - Update versioneer - And include other source distribution files in MANIFEST.in - Add project URLs - Add formatter and linter dependencies and configurations. - tox: Remove travis, fix python environments - tox: Remove extra coverage options and add them in .coveragerc. --- .coveragerc | 1 + .gitattributes | 1 + MANIFEST.in | 8 +-- pyproject.toml | 24 +++++++ sbws/_version.py | 25 ++++--- setup.cfg | 93 ++++++++++++++++++++++++-- setup.py | 86 ++---------------------- tests/integration/run.sh | 3 +- tox.ini | 88 +++++++++++++----------- versioneer.py | 169 ++++++++++++++++++++++++++++------------------- 10 files changed, 289 insertions(+), 209 deletions(-)
diff --git a/.coveragerc b/.coveragerc index c6303ca..ed599ae 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,3 @@ [run] omit = */__init__.py +source = sbws diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cc47975 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +sbws/_version.py export-subst diff --git a/MANIFEST.in b/MANIFEST.in index 793621e..a5058d4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,8 @@ include *.md include *.rst -include *.ini -recursive-include docs * -prune docs/build +recursive-include docs Makefile make.bat +recursive-include sbws *.ini recursive-include tests * recursive-exclude **/__pycache__ * -include versioneer.py +recursive-exclude * *.py[co] +prune docs/build diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f790796 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ + +[tool.black] +line-length = 79 +target-version = ['py36', 'py37', 'py38'] +exclude = ''' +/( + docs + | .*__init__.py + | .*_version.py +)/ +''' + + +[tool.isort] +line_length = 79 +# Compatibility with black +# profile = black # does not seem to work +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +ensure_newline_before_comments = true +src_paths = "sbws,tests" +skip = "versioneer.py,docs,sbws/_version.py,sbws/__init__.py" diff --git a/sbws/_version.py b/sbws/_version.py index e1de1ad..cbf260a 100644 --- a/sbws/_version.py +++ b/sbws/_version.py @@ -6,7 +6,7 @@ # that just contains the computed version number.
# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) +# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer)
"""Git implementation of _version.py."""
@@ -57,7 +57,7 @@ HANDLERS = {}
def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" + """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: @@ -93,9 +93,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, if verbose: print("unable to find command, tried %s" % (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() + stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) @@ -165,6 +163,10 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -300,6 +302,9 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
return pieces @@ -338,18 +343,18 @@ def render_pep440(pieces):
def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. + """TAG[.post0.devDISTANCE] -- No -dirty.
Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] + rendered += ".post0.dev%d" % pieces["distance"] else: # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] + rendered = "0.post0.dev%d" % pieces["distance"] return rendered
@@ -385,7 +390,7 @@ def render_pep440_old(pieces):
The ".dev0" means dirty.
- Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: diff --git a/setup.cfg b/setup.cfg index fd6b30c..578a389 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,92 @@ +[metadata] +name = sbws +description = Simple Bandwidth Scanner +author = Matt Traudt, juga +author_email = {pastly, juga}@torproject.org +license = CC0 +url = gitlab.torproject.org/tpo/network-health/sbws +keywords = tor onion bandwidth measurements scanner relay circuit +classifiers = + Development Status :: 4 - Beta + Environment :: Console + Intended Audience :: Developers + Intended Audience :: System Administrators + License :: OSI Approved :: MIT License + Natural Language :: English + Operating System :: POSIX :: Linux + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 +long_description = file: README.md +license_files = LICENSE.md +project_urls = + Documentation = sbws.readthedocs.org + Source = gitlab.torproject.org/tpo/network-health/sbws + Tracker = gitlab.torproject.org/tpo/network-health/sbws/-/issues + +[options] +packages = find: +include_package_data = True +# See stable releases at https://www.python.org/downloads/ +python_requires = >= 3.6 +install_requires = + stem >= 1.7.0 + ; # Now versioneer is also needed as dependency + versioneer + requests[socks] + +[options.extras_require] +test = + black + coverage + flake8 + flake8-docstrings + freezegun + isort + ; pylint ; when we ever fix all the errors it throughs + pytest + tox + sphinx +doc = + sphinx + pylint + recommonmark +dev = + flake8 + flake8-docstrings + isort + vulture + +[options.entry_points] +console_scripts = + sbws = sbws.sbws:main + +[tool:pytest] +log_cli=true +log_cli_level=DEBUG + +[flake8] +max-line-length = 79 +# D103 Missing docstring +# D400: First line should end with a period (not 't') +# D401: First line should be in imperative mood +# Compatibility with black +# W503 line break before binary operator +# E203 whitespace before ':' +extend-ignore = E203, W503, D1, D2, D4 +exclude = docs/*,sbws/_version.py,sbws/__init__.py,versioneer.py + +[coverage:run] +# Do not give error on empty __init__ files +omit = */__init__.py +source = sbws + +[aliases] +# Define setup.py command aliases here +test = pytest + # See the docstring in versioneer.py for instructions. Note that you must # re-run 'versioneer.py setup' after changing this section, and commit the # resulting files. @@ -15,7 +104,3 @@ versionfile_build = sbws/_version.py tag_prefix = v # String at the start of all unpacked tarball filenames. parentdir_prefix = sbws- - -[tool:pytest] -log_cli=true -log_cli_level=DEBUG diff --git a/setup.py b/setup.py index 10ff1fd..9ea4303 100755 --- a/setup.py +++ b/setup.py @@ -1,85 +1,7 @@ -#!/usr/bin/env python3 -# Always prefer setuptools over distutils -from setuptools import setup, find_packages -# To use a consistent encoding -from codecs import open -import os -# To generate the version at build time based on -# git describe --tags --dirty --always +"""The setup script.""" +import setuptools import versioneer
- -here = os.path.abspath(os.path.dirname(__file__)) - - -def long_description(): - with open(os.path.join(here, 'README.md'), encoding='utf-8') as f: - return f.read() - - -def get_package_data(): - # Example that grabs all *.ini files in the cwd and all files in foo/bar - # other_files = ['*.ini'] - # for r, _, fs in os.walk(os.path.join(here, 'foo', 'bar')): - # for f in fs: - # other_files.append(os.path.join(r, f)) - # return other_files - return [ - 'config.default.ini', - 'config.log.default.ini', - ] - - -def get_data_files(): - pass - - -setup( - name='sbws', - version=versioneer.get_version(), - cmdclass=versioneer.get_cmdclass(), - description='Simple Bandwidth Scanner', - long_description=long_description(), - long_description_content_type="text/markdown", - author='Matt Traudt, juga', - author_email='{pastly, juga}@torproject.org', - license='CC0', - url="https://gitweb.torproject.org/sbws.git", - classifiers=[ - 'Development Status :: 4 - Beta', - "Environment :: Console", - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Topic :: System :: Networking', - ], - packages=find_packages(), - include_package_data=True, - package_data={ - 'sbws': get_package_data(), - }, - data_files=get_data_files(), - keywords='tor onion bandwidth measurements scanner relay circuit', - python_requires='>=3.5', - entry_points={ - 'console_scripts': [ - 'sbws = sbws.sbws:main', - ] - }, - install_requires=[ - 'stem>=1.7.0', - 'requests[socks]', - ], - extras_require={ - # vulture: find unused code - 'dev': ['flake8', 'vulture'], - 'test': ['tox', 'pytest', 'coverage', 'freezegun'], - # recommonmark: to make sphinx render markdown - 'doc': ['sphinx', 'recommonmark', 'pylint'], - }, +setuptools.setup( + version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass() ) diff --git a/tests/integration/run.sh b/tests/integration/run.sh index 70ee5f2..90a5322 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -12,6 +12,7 @@ wget -O/dev/null http://127.0.0.1:28888/sbws.bin sbws -c tests/integration/sbws_testnet.ini scanner sbws -c tests/integration/sbws_testnet.ini generate # Run integration tests -coverage run -a --rcfile=.coveragerc --source=sbws -m pytest -s tests/integration -vv +python -m coverage run --append --module pytest -svv tests/integration + sbws -c tests/integration/sbws_testnet.ini cleanup tests/integration/stop_chutney.sh diff --git a/tox.ini b/tox.ini index bb66836..5c6e2a2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,27 +1,29 @@ [tox] skip_missing_interpreters = True -envlist = py{36, 37, 38, 39, 310}, inst, setup, integration, lint, stats, doc +envlist = + py{36, 37, 38, 39, 310} + inst, + setup, + black, + isort, + flake8, + doc, + stats
-[travis] -python = - 3.6: py36, inst, setup, unit, integration, lint, doc - 3.7: py37, inst, setup, unit, integration, lint, doc - 3.8: py38, inst, setup, unit, integration, lint, doc - 3.9: py39, inst, setup, unit, integration, lint, doc - nightly: pynightly, inst, setup, unit, integration, lint, doc
-; [testenv] -# install_command can be removed when --process-dependency-links is not -# needed anymore, and this section commented -# install_command = pip install {opts} {packages} +[testenv] +; Installing with deps errors with versioneer +; deps = .[test] +skip_install = True +commands = + pip install .[test] + ; Use python -m to use the binary from the virtualenv if it is also + ; installed in the system. Do not use {envbindir} since it would require + ; to install it in tox virtualenv + python -m coverage run --append --module pytest -svv tests/unit
# test that it can be installed with custom commands and clean env [testenv:inst] -skip_install = True -commands = - # this will fail until --process-dependency-links is not needed - # it needs to be commented since error code will be still 1 - - pip install . ignore_errors = True recreate = True
@@ -32,42 +34,48 @@ skip_install = True commands = python setup.py install recreate = True
-[testenv] -deps = .[test] -commands = - coverage run -a --rcfile={toxinidir}/.coveragerc --source=sbws -m pytest \ - -s {toxinidir}/tests/unit -vv - [testenv:integration] ignore_errors = True deps = .[test] whitelist_externals = bash commands = - # For some reason .[test] is not copying config.* files - pip install . bash -c tests/integration/run.sh {envtmpdir}/chutney
-[testenv:lint] +[testenv:black] +skip_install = True +deps = + black +commands = + black --check --diff sbws tests + +[testenv:isort] +skip_install = True +deps = + isort +commands = + isort --check-only --diff sbws tests + +[testenv:flake8] skip_install = True -deps = .[dev] -commands = flake8 sbws scripts tests +deps = flake8-docstrings +commands = + flake8 sbws tests
[testenv:clean] skip_install = True -changedir={toxinidir} deps = coverage -command = coverage erase +changedir = {toxinidir} +commands = python -m coverage erase
[testenv:stats] skip_install = True -changedir={toxinidir} -deps = .[test] +deps = coverage commands= - # nothing to combine while not using several python versions - # coverage combine - coverage report - coverage html + ; nothing to combine while not using several python versions + ; python -m coverage combine + python -m coverage report + python -m coverage html
[testenv:doc] deps = .[doc] @@ -75,11 +83,11 @@ whitelist_externals = make changedir = docs commands = make html - # this requires build the pdf images - # make latexpdf - make man + ; this requires build the pdf images + ; make latexpdf + ; make man
-# this requires Internet, it should not be in envlist +; this requires Internet, it should not be in envlist [testenv:doclinks] deps = .[doc] whitelist_externals = make diff --git a/versioneer.py b/versioneer.py index 64fea1c..1040c21 100644 --- a/versioneer.py +++ b/versioneer.py @@ -1,5 +1,5 @@
-# Version: 0.18 +# Version: 0.19
"""The Versioneer - like a rocketeer, but for versions.
@@ -7,16 +7,12 @@ The Versioneer ==============
* like a rocketeer, but for versions! -* https://github.com/warner/python-versioneer +* https://github.com/python-versioneer/python-versioneer * Brian Warner * License: Public Domain -* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy -* [![Latest Version] -(https://pypip.in/version/versioneer/badge.svg?style=flat) -](https://pypi.python.org/pypi/versioneer/) -* [![Build Status] -(https://travis-ci.org/warner/python-versioneer.png?branch=master) -](https://travis-ci.org/warner/python-versioneer) +* Compatible with: Python 3.6, 3.7, 3.8, 3.9 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url]
This is a tool for managing a recorded version number in distutils-based python projects. The goal is to remove the tedious and error-prone "update @@ -27,9 +23,10 @@ system, and maybe making new tarballs.
## Quick Install
-* `pip install versioneer` to somewhere to your $PATH -* add a `[versioneer]` section to your setup.cfg (see below) +* `pip install versioneer` to somewhere in your $PATH +* add a `[versioneer]` section to your setup.cfg (see [Install](INSTALL.md)) * run `versioneer install` in your source tree, commit the results +* Verify version information with `python setup.py version`
## Version Identifiers
@@ -61,7 +58,7 @@ version 1.3). Many VCS systems can report a description that captures this, for example `git describe --tags --dirty --always` reports things like "0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the 0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has -uncommitted changes. +uncommitted changes).
The version identifier is used for multiple purposes:
@@ -166,7 +163,7 @@ which may help identify what went wrong).
Some situations are known to cause problems for Versioneer. This details the most significant ones. More can be found on Github -[issues page](https://github.com/warner/python-versioneer/issues). +[issues page](https://github.com/python-versioneer/python-versioneer/issues).
### Subprojects
@@ -180,7 +177,7 @@ two common reasons why `setup.py` might not be in the root: `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI distributions (and upload multiple independently-installable tarballs). * Source trees whose main purpose is to contain a C library, but which also - provide bindings to Python (and perhaps other langauges) in subdirectories. + provide bindings to Python (and perhaps other languages) in subdirectories.
Versioneer will look for `.git` in parent directories, and most operations should get the right version string. However `pip` and `setuptools` have bugs @@ -194,9 +191,9 @@ work too. Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in some later version.
-[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking this issue. The discussion in -[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the issue from the Versioneer side in more detail. [pip PR#3176](https://github.com/pypa/pip/pull/3176) and [pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve @@ -224,22 +221,10 @@ regenerated while a different version is checked out. Many setup.py commands cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into a different virtualenv), so this can be surprising.
-[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes this one, but upgrading to a newer version of setuptools should probably resolve it.
-### Unicode version strings - -While Versioneer works (and is continually tested) with both Python 2 and -Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. -Newer releases probably generate unicode version strings on py2. It's not -clear that this is wrong, but it may be surprising for applications when then -write these strings to a network connection or include them in bytes-oriented -APIs like cryptographic checksums. - -[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates -this question. -
## Updating Versioneer
@@ -265,6 +250,12 @@ installation by editing setup.py . Alternatively, it might go the other direction and include code from all supported VCS systems, reducing the number of intermediate scripts.
+## Similar projects + +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer
## License
@@ -274,13 +265,15 @@ Specifically, both are released under the Creative Commons "Public Domain Dedication" license (CC0-1.0), as described in https://creativecommons.org/publicdomain/zero/1.0/ .
+[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer + """
-from __future__ import print_function -try: - import configparser -except ImportError: - import ConfigParser as configparser +import configparser import errno import json import os @@ -339,9 +332,9 @@ def get_config_from_root(root): # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . setup_cfg = os.path.join(root, "setup.cfg") - parser = configparser.SafeConfigParser() + parser = configparser.ConfigParser() with open(setup_cfg, "r") as f: - parser.readfp(f) + parser.read_file(f) VCS = parser.get("versioneer", "VCS") # mandatory
def get(parser, name): @@ -371,7 +364,7 @@ HANDLERS = {}
def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" + """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: @@ -407,9 +400,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, if verbose: print("unable to find command, tried %s" % (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() + stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) @@ -418,7 +409,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, return stdout, p.returncode
-LONG_VERSION_PY['git'] = ''' +LONG_VERSION_PY['git'] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build @@ -426,7 +417,7 @@ LONG_VERSION_PY['git'] = ''' # that just contains the computed version number.
# This file is released into the public domain. Generated by -# versioneer-0.18 (https://github.com/warner/python-versioneer) +# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer)
"""Git implementation of _version.py."""
@@ -477,7 +468,7 @@ HANDLERS = {}
def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" + """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: @@ -513,9 +504,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, if verbose: print("unable to find command, tried %%s" %% (commands,)) return None, None - stdout = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() + stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %%s (error)" %% dispcmd) @@ -585,6 +574,10 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -720,6 +713,9 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
return pieces @@ -758,18 +754,18 @@ def render_pep440(pieces):
def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. + """TAG[.post0.devDISTANCE] -- No -dirty.
Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: - rendered += ".post.dev%%d" %% pieces["distance"] + rendered += ".post0.dev%%d" %% pieces["distance"] else: # exception #1 - rendered = "0.post.dev%%d" %% pieces["distance"] + rendered = "0.post0.dev%%d" %% pieces["distance"] return rendered
@@ -805,7 +801,7 @@ def render_pep440_old(pieces):
The ".dev0" means dirty.
- Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: @@ -977,6 +973,10 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because @@ -1112,6 +1112,9 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
return pieces @@ -1181,7 +1184,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):
SHORT_VERSION_PY = """ -# This file was generated by 'versioneer.py' (0.18) from +# This file was generated by 'versioneer.py' (0.19) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. @@ -1259,18 +1262,18 @@ def render_pep440(pieces):
def render_pep440_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. + """TAG[.post0.devDISTANCE] -- No -dirty.
Exceptions: - 1: no tags. 0.post.devDISTANCE + 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] + rendered += ".post0.dev%d" % pieces["distance"] else: # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] + rendered = "0.post0.dev%d" % pieces["distance"] return rendered
@@ -1306,7 +1309,7 @@ def render_pep440_old(pieces):
The ".dev0" means dirty.
- Eexceptions: + Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: @@ -1480,8 +1483,12 @@ def get_version(): return get_versions()["version"]
-def get_cmdclass(): - """Get the custom setuptools/distutils subclasses used by Versioneer.""" +def get_cmdclass(cmdclass=None): + """Get the custom setuptools/distutils subclasses used by Versioneer. + + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ if "versioneer" in sys.modules: del sys.modules["versioneer"] # this fixes the "python setup.py develop" case (also 'install' and @@ -1495,9 +1502,9 @@ def get_cmdclass(): # parent is protected against the child's "import versioneer". By # removing ourselves from sys.modules here, before the child build # happens, we protect the child from the parent's versioneer too. - # Also see https://github.com/warner/python-versioneer/issues/52 + # Also see https://github.com/python-versioneer/python-versioneer/issues/52
- cmds = {} + cmds = {} if cmdclass is None else cmdclass.copy()
# we add "version" to both distutils and setuptools from distutils.core import Command @@ -1539,7 +1546,9 @@ def get_cmdclass(): # setup.py egg_info -> ?
# we override different "build_py" commands for both environments - if "setuptools" in sys.modules: + if 'build_py' in cmds: + _build_py = cmds['build_py'] + elif "setuptools" in sys.modules: from setuptools.command.build_py import build_py as _build_py else: from distutils.command.build_py import build_py as _build_py @@ -1559,6 +1568,31 @@ def get_cmdclass(): write_to_version_file(target_versionfile, versions) cmds["build_py"] = cmd_build_py
+ if "setuptools" in sys.modules: + from setuptools.command.build_ext import build_ext as _build_ext + else: + from distutils.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext + if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe # nczeczulin reports that py2exe won't like the pep440-style string @@ -1592,10 +1626,7 @@ def get_cmdclass(): del cmds["build_py"]
if 'py2exe' in sys.modules: # py2exe enabled? - try: - from py2exe.distutils_buildexe import py2exe as _py2exe # py3 - except ImportError: - from py2exe.build_exe import py2exe as _py2exe # py2 + from py2exe.distutils_buildexe import py2exe as _py2exe
class cmd_py2exe(_py2exe): def run(self): @@ -1620,7 +1651,9 @@ def get_cmdclass(): cmds["py2exe"] = cmd_py2exe
# we override different "sdist" commands for both environments - if "setuptools" in sys.modules: + if 'sdist' in cmds: + _sdist = cmds['sdist'] + elif "setuptools" in sys.modules: from setuptools.command.sdist import sdist as _sdist else: from distutils.command.sdist import sdist as _sdist @@ -1695,7 +1728,7 @@ del get_versions
def do_setup(): - """Main VCS-independent setup function for installing Versioneer.""" + """Do main VCS-independent setup function for installing Versioneer.""" root = get_root() try: cfg = get_config_from_root(root)
tor-commits@lists.torproject.org