Hello community,
here is the log from the commit of package python-python-daemon for openSUSE:Factory checked in at 2017-10-21 20:21:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-daemon (Old)
and /work/SRC/openSUSE:Factory/.python-python-daemon.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-daemon"
Sat Oct 21 20:21:25 2017 rev:17 rq:533011 version:2.1.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-python-daemon/python-python-daemon.changes 2016-02-16 09:18:22.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-python-daemon.new/python-python-daemon.changes 2017-10-21 20:21:28.179860568 +0200
@@ -1,0 +2,12 @@
+Tue Oct 10 13:18:27 UTC 2017 - jmatejek@suse.com
+
+- singlespec auto-conversion
+- update requirements
+- use pytest as test runner
+- update to 2.1.2
+ * Ensure custom types are part of the Python type hierarchy.
+ * Raise a warning that the ‘runner’ module is pending deprecation.
+ This has been an unofficial example module from the beginning, and
+ it will be removed in a future version.
+
+-------------------------------------------------------------------
@@ -216,0 +229 @@
+
Old:
----
python-daemon-2.1.1.tar.gz
New:
----
python-daemon-2.1.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-daemon.spec ++++++
--- /var/tmp/diff_new_pack.oA8F1e/_old 2017-10-21 20:21:28.707835844 +0200
+++ /var/tmp/diff_new_pack.oA8F1e/_new 2017-10-21 20:21:28.711835657 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-python-daemon
#
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,31 +16,35 @@
#
+%define oldpython python
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-python-daemon
-Version: 2.1.1
+Version: 2.1.2
Release: 0
-Url: http://pypi.python.org/pypi/python-daemon/
Summary: Library to implement a well-behaved Unix daemon process
License: Apache-2.0 and GPL-3.0
Group: Development/Languages/Python
-Source: https://pypi.python.org/packages/source/p/python-daemon/python-daemon-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildRequires: python-devel >= 2.7
-BuildRequires: python-docutils
-BuildRequires: python-lockfile >= 0.10
-BuildRequires: python-mock >= 1.0
-BuildRequires: python-setuptools
-BuildRequires: python-testscenarios >= 0.4
-BuildRequires: python-testtools
-BuildRequires: python-unittest2 >= 0.6
+Url: http://pypi.python.org/pypi/python-daemon/
+Source: https://files.pythonhosted.org/packages/source/p/python-daemon/python-daemon-%{version}.tar.gz
+BuildRequires: %{python_module devel >= 2.7}
+BuildRequires: %{python_module docutils}
+BuildRequires: %{python_module lockfile >= 0.10}
+BuildRequires: %{python_module mock >= 1.0}
+BuildRequires: %{python_module pytest}
+BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module testscenarios >= 0.4}
+BuildRequires: %{python_module testtools}
+BuildRequires: %{python_module unittest2 >= 0.6}
+BuildRequires: python-rpm-macros
+Requires: python-docutils
Requires: python-lockfile >= 0.10
-Provides: python-daemon = %{version}
-Obsoletes: python-daemon < %{version}
-%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
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
+%ifpython2
+Provides: %{oldpython}-daemon = %{version}
+Obsoletes: %{oldpython}-daemon < %{version}
%endif
+%python_subpackages
%description
This library implements the well-behaved daemon specification of PEP 3143, "Standard daemon
@@ -54,15 +58,15 @@
%setup -q -n python-daemon-%{version}
%build
-python setup.py build
+%python_build
%install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%python_install
%check
-python setup.py -q test
+%python_exec -m pytest test
-%files
+%files %{python_files}
%defattr(-,root,root,-)
%doc ChangeLog LICENSE.ASF-2 doc
%{python_sitelib}/*
++++++ python-daemon-2.1.1.tar.gz -> python-daemon-2.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/ChangeLog new/python-daemon-2.1.2/ChangeLog
--- old/python-daemon-2.1.1/ChangeLog 2016-01-30 03:04:46.000000000 +0100
+++ new/python-daemon-2.1.2/ChangeLog 2016-10-26 12:08:37.000000000 +0200
@@ -1,9 +1,46 @@
+This document is the `change log`_ for this distribution. It is a
+record of all notable changes in each version released.
+
+Version strings conform to the `Semantic Versioning`_ specification,
+`version 2.0.0 http://semver.org/spec/v2.0.0.html`__.
+
+.. _change log: http://keepachangelog.com/
+.. _Semantic Versioning: https://semver.org/
+
+
+Version 2.1.2
+=============
+
+:Released: 2016-10-26
+:Maintainer: Ben Finney
+
+Additions:
+
+* Add a README document for the code base.
+
+Changes:
+
+* Migrate code project hosting to Pagure.
+ Record the change of homepage URL in PyPI metadata.
+* Raise a warning that the ‘runner’ module is pending deprecation.
+ This has been an unofficial example module from the beginning, and
+ it will be removed in a future version.
+
+Bug Fixes:
+
+* Ensure custom types are part of the Python type hierarchy.
+* Avoid a circular dependency for the version string at install time.
+ Thanks to Maarten van Gompel for the reproducible test case.
+
+
Version 2.1.1
=============
:Released: 2016-01-30
:Maintainer: Ben Finney
+Bug Fixes:
+
* Default ‘initgroups’ option to False. Using ‘os.initgroups’ requires
permission to set process GID, so this now needs to be explicitly
requested.
@@ -15,6 +52,8 @@
:Released: 2015-11-26
:Maintainer: Ben Finney
+Additions:
+
* Add a DaemonContext option, ‘initgroups’, which specifies whether to
set the daemon process's supplementary groups.
* Set the process groups using ‘os.initgroups’.
@@ -28,9 +67,14 @@
:Released: 2015-08-30
:Maintainer: Ben Finney
+Changes:
+
* Lower dependency for ‘unittest2’, we can work with an earlier version.
* Specify development status “Production/Stable” in Trove classifiers.
* Migrate to ‘mock’ version 1.3 with corresponding API changes.
+
+Bug Fixes:
+
* Use current Python concept of “basestring” to test for an attribute name.
Thanks to Arthur de Jong for the bug report.
@@ -41,6 +85,8 @@
:Released: 2015-02-02
:Maintainer: Ben Finney
+Bug Fixes:
+
* Refine compatibility of exceptions for file operations.
* Specify the text encoding when opening the changelog file.
@@ -51,7 +97,12 @@
:Released: 2015-01-23
:Maintainer: Ben Finney
+Changes:
+
* Record version info via Setuptools commands.
+
+Removals:
+
* Remove the custom Setuptools entry points.
This closes Alioth bug#314948.
@@ -62,11 +113,19 @@
:Released: 2015-01-14
:Maintainer: Ben Finney
-* Break circular import dependency for ‘setup.py’.
+Changes:
+
* Refactor all initial metadata functionality to ‘daemon._metadata’.
-* Distribute ‘version’ (and its tests) only in source, not install.
* Build a “universal” (Python 2 and Python 3) wheel.
+Removals:
+
+* Distribute ‘version’ (and its tests) only in source, not install.
+
+Bug Fixes:
+
+* Break circular import dependency for ‘setup.py’.
+
Version 2.0.2
=============
@@ -74,11 +133,16 @@
:Released: 2015-01-13
:Maintainer: Ben Finney
-* Declare test-time dependency on recent ‘unittest2’.
-* Declare packaging-time dependency on ‘docutils’ library.
+Additions:
+
* Include unit tests for ‘version’ module with source distribution.
* Record version info consistent with distribution metadata.
+Bug Fixes:
+
+* Declare test-time dependency on recent ‘unittest2’.
+* Declare packaging-time dependency on ‘docutils’ library.
+
Version 2.0.1
=============
@@ -86,6 +150,8 @@
:Released: 2015-01-11
:Maintainer: Ben Finney
+Bug Fixes:
+
* Include the ‘version’ module with source distribution.
@@ -95,6 +161,8 @@
:Released: 2015-01-10
:Maintainer: Ben Finney
+Additions:
+
* Support both Python 3 (version 3.2 or later) and Python 2 (version
2.7 or later).
* Document the API of all functions comprehensively in docstrings.
@@ -106,22 +174,19 @@
* Preserve exception context in custom exceptions.
* Declare compatibility with current Python versions.
-* Depend on Python 3 compatible libraries.
-* Update package homepage to Alioth hosted project page.
* Use ‘pydoc.splitdoc’ to get package description text.
-* Remove ASCII translation of package description, not needed now the
- docstring is a proper Unicode text value.
* Include test suite with source distribution.
-* Move package metadata to ‘daemon/_metadata.py’.
-* Migrate to JSON (instead of Python) for serialised version info.
* Add unit tests for metadata.
* Store and retrieve version info in Setuptools metadata.
+Changes:
+
+* Depend on Python 3 compatible libraries.
+* Update package homepage to Alioth hosted project page.
* Migrate to ‘str.format’ for interpolation of values into text.
* Migrate to ‘mock’ library for mock objects in tests.
* Migrate to ‘testscenarios’ library for unit test scenarios.
* Migrate to ‘unittest2’ library for back-ported improvements.
- Remove custom test suite creation.
* Discriminate Python 2-and-3 compatible usage of dict methods.
* Discriminate Python 2-and-3 compatible bytes versus text.
* Declare explicit absolute and relative imports.
@@ -132,6 +197,14 @@
compatibility.
* Wrap function introspection for Python 3 compatibility.
* Wrap standard library imports where names changed in Python 3.
+* Move package metadata to ‘daemon/_metadata.py’.
+* Migrate to JSON (instead of Python) for serialised version info.
+
+Removals:
+
+* Remove ASCII translation of package description, not needed now the
+ docstring is a proper Unicode text value.
+* Remove custom test suite creation.
Version 1.6.1
@@ -140,17 +213,13 @@
:Released: 2014-08-04
:Maintainer: Ben Finney
-* Use unambiguous “except FooType as foo” syntax.
- This is to ease the port to Python 3, where the ambiguous comma
- usage is an error.
-* Ensure a ‘basestring’ name bound to the base type for strings.
- This is to allow checks to work on Python 2 and 3.
-* Specify versions of Python supported, as trove classifiers.
+Additions:
-* Update copyright notices.
* Add editor hints for most files.
-* Distinguish continuation-line indentation versus block indentation.
+Changes:
+
+* Distinguish continuation-line indentation versus block indentation.
* Use unicode literals by default, specifying bytes where necessary.
This is to ease the port to Python 3, where the default string type
is unicode.
@@ -161,6 +230,15 @@
* Change license of library code to Apache License 2.0. Rationale at
URL:http://wiki.python.org/moin/PythonSoftwareFoundationLicenseFaq#Contribut....
+Bug Fixes:
+
+* Use unambiguous “except FooType as foo” syntax.
+ This is to ease the port to Python 3, where the ambiguous comma
+ usage is an error.
+* Ensure a ‘basestring’ name bound to the base type for strings.
+ This is to allow checks to work on Python 2 and 3.
+* Specify versions of Python supported, as trove classifiers.
+
Version 1.6
===========
@@ -168,8 +246,21 @@
:Released: 2010-05-10
:Maintainer: Ben Finney
+Additions:
+
+* FAQ: Add some entries and re-structure the document.
+* MANIFEST.in: Include the documentation in the distribution.
+
+Changes:
+
* Use absolute imports to disambiguate provenance of names.
* setup.py: Require ‘lockfile >=0.9’.
+
+* Use ‘unicode’ data type for all text values.
+* Prepare for Python 3 upgrade by tweaking some names and imports.
+
+Removals:
+
* daemon/pidfile.py: Renamed from ‘daemon/pidlockfile.py’. Change
references elsewhere to use this new name.
* test/test_pidfile.py: Renamed from ‘test/test_pidlockfile.py’.
@@ -177,13 +268,6 @@
* daemon/pidfile.py: Remove functionality now migrated to ‘lockfile’
library.
-* FAQ: Add some entries and re-structure the document.
-
-* Use ‘unicode’ data type for all text values.
-* Prepare for Python 3 upgrade by tweaking some names and imports.
-
-* MANIFEST.in: Include the documentation in the distribution.
-
Version 1.5.5
=============
@@ -191,6 +275,8 @@
:Released: 2010-03-02
:Maintainer: Ben Finney
+Bug Fixes:
+
* Stop using ‘pkg_resources’ and revert to pre-1.5.3 version-string
handling, until a better way that doesn't break everyone else's
installation can be found.
@@ -202,6 +288,8 @@
:Released: 2010-02-27
:Maintainer: Ben Finney
+Bug Fixes:
+
* MANIFEST.in: Explicitly include version data file, otherwise
everything breaks for users of the sdist.
@@ -212,17 +300,25 @@
:Released: 2010-02-26
:Maintainer: Ben Finney
-* daemon/daemon.py: Invoke the pidfile context manager's ‘__exit__’
- method with the correct arguments (as per
- URL:http://docs.python.org/library/stdtypes.html#typecontextmanager).
- Thanks to Ludvig Ericson for the bug report.
+Additions:
+
* version: New plain-text data file to store project version string.
+* Add ‘pylint’ configuration for this project.
+
+Changes:
+
* setup.py: Read version string from data file.
* daemon/version/__init__.py: Query version string with ‘pkg_resources’.
-* Add ‘pylint’ configuration for this project.
* Update copyright notices.
+Bug Fixes:
+
+* daemon/daemon.py: Invoke the pidfile context manager's ‘__exit__’
+ method with the correct arguments (as per
+ URL:http://docs.python.org/library/stdtypes.html#typecontextmanager).
+ Thanks to Ludvig Ericson for the bug report.
+
Version 1.5.2
=============
@@ -230,12 +326,16 @@
:Released: 2009-10-24
:Maintainer: Ben Finney
+Additions:
+
+* Add initial Frequently Asked Questions document.
+
+Bug Fixes:
+
* Ensure we only prevent core dumps if ‘prevent_core’ is true.
Thanks to Denis Bilenko for reporting the lacking implementation of
this documented option.
-* Add initial Frequently Asked Questions document.
-
Version 1.5.1
=============
@@ -243,6 +343,8 @@
:Released: 2009-09-26
:Maintainer: Ben Finney
+Additions:
+
* Make a separate collection of DaemonRunner test scenarios.
* Handle a start request with a timeout on the PID file lock acquire.
@@ -257,19 +359,26 @@
:Released: 2009-09-24
:Maintainer: Ben Finney
+Additions:
+
* Make a separate collection of PIDLockFile test scenarios.
-* Raise specific errors on ‘DaemonRunner’ failures.
-* Distinguish different conditions on reading and parsing PID file.
+Changes:
+
* Refactor code to ‘_terminate_daemon_process’ method.
* Improve explanations in comments and docstrings.
* Don't set pidfile at all if no path specified to constructor.
-* Write the PID file using correct OS locking and permissions.
-* Close the PID file after writing.
* Implement ‘PIDLockFile’ as subclass of ‘lockfile.LinkFileLock’.
* Remove redundant checks for file existence.
* Manage the excluded file descriptors as a set (not a list).
+
+Bug Fixes:
+
+* Raise specific errors on ‘DaemonRunner’ failures.
+* Distinguish different conditions on reading and parsing PID file.
+* Write the PID file using correct OS locking and permissions.
+* Close the PID file after writing.
* Only inspect the file descriptor of streams if they actually have
one (via a ‘fileno’ method) when determining which file descriptors
to close. Thanks to Ask Solem for revealing this bug.
@@ -281,15 +390,26 @@
:Released: 2009-09-17
:Maintainer: Ben Finney
-* Remove child-exit signal (‘SIGCLD’, ‘SIGCHLD’) from default signal
- map. Thanks to Joel Martin for pinpointing this issue.
+Additions:
+
* Document requirement for ensuring any operating-system specific
signal handlers are considered.
+* Add specific license terms for unit test suite scaffold.
+
+Changes:
+
* Refactor ‘fork_then_exit_parent’ functionality to avoid duplicate
code.
+
+Removals:
+
* Remove redundant imports.
* Remove unused code from unit test suite scaffold.
-* Add specific license terms for unit test suite scaffold.
+
+Bug Fixes:
+
+* Remove child-exit signal (‘SIGCLD’, ‘SIGCHLD’) from default signal
+ map. Thanks to Joel Martin for pinpointing this issue.
Version 1.4.7
@@ -298,9 +418,14 @@
:Released: 2009-09-03
:Maintainer: Ben Finney
-* Fix keywords argument for distribution setup.
+Removals:
+
* Exclude ‘test’ package from distribution installation.
+Bug Fixes:
+
+* Fix keywords argument for distribution setup.
+
Version 1.4.6
=============
@@ -308,6 +433,8 @@
:Released: 2009-06-21
:Maintainer: Ben Finney
+Additions:
+
* Update documentation for changes from latest PEP 3143 revision.
* Implement DaemonContext.is_open method.
@@ -318,13 +445,18 @@
:Released: 2009-05-17
:Maintainer: Ben Finney
-* Register DaemonContext.close method for atexit processing.
-* Move PID file cleanup to close method.
+Additions:
+
* Improve docstrings by reference to, and copy from, PEP 3143.
* Use mock checking capabilities of newer ‘MiniMock’ library.
* Automate building a versioned distribution tarball.
* Include developer documentation files in source distribution.
+Bug Fixes:
+
+* Register DaemonContext.close method for atexit processing.
+* Move PID file cleanup to close method.
+
Version 1.4.4
=============
@@ -332,12 +464,17 @@
:Released: 2009-03-26
:Maintainer: Ben Finney
+Changes:
+
* Conform to current PEP version, now released as PEP 3143 “Standard
daemon process library”.
+* Redirect standard streams to null device by default.
+
+Bug Fixes:
+
* Ensure UID and GID are set in correct order.
* Delay closing all open files until just before re-binding standard
streams.
-* Redirect standard streams to null device by default.
Version 1.4.3
@@ -346,6 +483,8 @@
:Released: 2009-03-19
:Maintainer: Ben Finney
+Bug Fixes:
+
* Close the PID file context on exit.
@@ -355,6 +494,8 @@
:Released: 2009-03-18
:Maintainer: Ben Finney
+Additions:
+
* Context manager methods for DaemonContext.
@@ -364,6 +505,8 @@
:Released: 2009-03-18
:Maintainer: Ben Finney
+Changes:
+
* Improvements to docstrings.
* Further conformance with draft PEP.
@@ -374,9 +517,14 @@
:Released: 2009-03-17
:Maintainer: Ben Finney
-* Implement the interface from a draft PEP for process daemonisation.
+Additions:
+
* Complete statement coverage from unit test suite.
+Changes:
+
+* Implement the interface from a draft PEP for process daemonisation.
+
Version 1.3
===========
@@ -384,10 +532,18 @@
:Released: 2009-03-12
:Maintainer: Ben Finney
+Additions:
+
+* Huge increase in unit test suite.
+
+Changes:
+
* Separate controller (now ‘DaemonRunner’) from daemon process
context (now ‘DaemonContext’).
+
+Bug Fixes:
+
* Fix many corner cases and bugs.
-* Huge increase in unit test suite.
Version 1.2
@@ -396,13 +552,25 @@
:Released: 2009-01-27
:Maintainer: Ben Finney
+Additions:
+
+* Begin unit test suite.
+
+Changes:
+
* Initial release of this project forked from ‘bda.daemon’. Thanks,
Robert Niederreiter.
* Refactor some functionality out to helper functions.
-* Begin unit test suite.
..
+ This document is written using `reStructuredText`_ markup, and can
+ be rendered with `Docutils`_ to other formats.
+
+ .. _Docutils: http://docutils.sourceforge.net/
+ .. _reStructuredText: http://docutils.sourceforge.net/rst.html
+
+..
This is free software: you may copy, modify, and/or distribute this work
under the terms of the Apache License version 2.0 as published by the
Apache Software Foundation.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/PKG-INFO new/python-daemon-2.1.2/PKG-INFO
--- old/python-daemon-2.1.1/PKG-INFO 2016-01-30 03:06:58.000000000 +0100
+++ new/python-daemon-2.1.2/PKG-INFO 2016-10-26 12:09:22.000000000 +0200
@@ -1,8 +1,8 @@
Metadata-Version: 1.1
Name: python-daemon
-Version: 2.1.1
+Version: 2.1.2
Summary: Library to implement a well-behaved Unix daemon process.
-Home-page: https://alioth.debian.org/projects/python-daemon/
+Home-page: https://pagure.io/python-daemon/
Author: Ben Finney
Author-email: ben+python@benfinney.id.au
License: Apache-2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/README new/python-daemon-2.1.2/README
--- old/python-daemon-2.1.1/README 1970-01-01 01:00:00.000000000 +0100
+++ new/python-daemon-2.1.2/README 2016-10-22 06:32:04.000000000 +0200
@@ -0,0 +1,61 @@
+#############
+python-daemon
+#############
+
+Library to implement a well-behaved Unix daemon process
+#######################################################
+
+This library implements the well-behaved daemon specification of
+:pep:`3143`, “Standard daemon process library”.
+
+A well-behaved Unix daemon process is tricky to get right, but the
+required steps are much the same for every daemon program. A
+`DaemonContext` instance holds the behaviour and configured process
+environment for the program; use the instance as a context manager to
+enter a daemon state.
+
+Simple example of usage::
+
+ import daemon
+
+ from spam import do_main_program
+
+ with daemon.DaemonContext():
+ do_main_program()
+
+Customisation of the steps to become a daemon is available by setting
+options on the `DaemonContext` instance; see the documentation for
+that class for each option.
+
+
+Copying
+=======
+
+This work, ‘python-daemon’, is free software: you may copy, modify,
+and/or distribute this work under certain conditions; see the relevant
+files for specific grant of license. No warranty expressed or implied.
+
+* Parts of this work are licensed to you under the terms of the GNU
+ General Public License as published by the Free Software Foundation;
+ version 3 of that license or any later version.
+ See the file ‘LICENSE.GPL-3’ for details.
+
+* Parts of this work are licensed to you under the terms of the Apache
+ License, version 2.0 as published by the Apache Software Foundation.
+ See the file ‘LICENSE.ASF-2’ for details.
+
+
+..
+ This document is written using `reStructuredText`_ markup, and can
+ be rendered with `Docutils`_ to other formats.
+
+ .. _Docutils: http://docutils.sourceforge.net/
+ .. _reStructuredText: http://docutils.sourceforge.net/rst.html
+
+..
+ Local variables:
+ coding: utf-8
+ mode: text
+ mode: rst
+ End:
+ vim: fileencoding=utf-8 filetype=rst :
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/daemon/_metadata.py new/python-daemon-2.1.2/daemon/_metadata.py
--- old/python-daemon-2.1.1/daemon/_metadata.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/daemon/_metadata.py 2016-10-21 14:57:20.000000000 +0200
@@ -15,16 +15,17 @@
from __future__ import (absolute_import, unicode_literals)
import json
-import re
-import collections
import datetime
import pkg_resources
+__metaclass__ = type
+
distribution_name = "python-daemon"
version_info_filename = "version_info.json"
+
def get_distribution_version_info(filename=version_info_filename):
""" Get the version info from the installed distribution.
@@ -48,8 +49,8 @@
distribution = None
if distribution is not None:
- if distribution.has_metadata(version_info_filename):
- content = distribution.get_metadata(version_info_filename)
+ if distribution.has_metadata(filename):
+ content = distribution.get_metadata(filename)
version_info = json.loads(content)
return version_info
@@ -59,34 +60,6 @@
version_installed = version_info['version']
-rfc822_person_regex = re.compile(
- "^(?P<name>[^<]+) <(?P<email>[^>]+)>$")
-
-ParsedPerson = collections.namedtuple('ParsedPerson', ['name', 'email'])
-
-def parse_person_field(value):
- """ Parse a person field into name and email address.
-
- :param value: The text value specifying a person.
- :return: A 2-tuple (name, email) for the person's details.
-
- If the `value` does not match a standard person with email
- address, the `email` item is ``None``.
-
- """
- result = (None, None)
-
- match = rfc822_person_regex.match(value)
- if len(value):
- if match is not None:
- result = ParsedPerson(
- name=match.group('name'),
- email=match.group('email'))
- else:
- result = ParsedPerson(name=value, email=None)
-
- return result
-
author_name = "Ben Finney"
author_email = "ben+python@benfinney.id.au"
author = "{name} <{email}>".format(name=author_name, email=author_email)
@@ -142,7 +115,7 @@
copyright = "Copyright © {year_range} {author} and others".format(
year_range=copyright_year_range, author=author)
license = "Apache-2"
-url = "https://alioth.debian.org/projects/python-daemon/"
+url = "https://pagure.io/python-daemon/"
# Local variables:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/daemon/daemon.py new/python-daemon-2.1.2/daemon/daemon.py
--- old/python-daemon-2.1.1/daemon/daemon.py 2016-01-30 03:02:20.000000000 +0100
+++ new/python-daemon-2.1.2/daemon/daemon.py 2016-10-26 12:08:06.000000000 +0200
@@ -37,6 +37,8 @@
basestring = str
unicode = str
+__metaclass__ = type
+
class DaemonError(Exception):
""" Base exception class for errors from this module. """
@@ -238,8 +240,6 @@
"""
- __metaclass__ = type
-
def __init__(
self,
chroot_directory=None,
@@ -840,14 +840,16 @@
of ``MAXFD`` is returned.
"""
- limits = resource.getrlimit(resource.RLIMIT_NOFILE)
- result = limits[1]
- if result == resource.RLIM_INFINITY:
+ (__, hard_limit) = resource.getrlimit(resource.RLIMIT_NOFILE)
+
+ result = hard_limit
+ if hard_limit == resource.RLIM_INFINITY:
result = MAXFD
+
return result
-def close_all_open_files(exclude=set()):
+def close_all_open_files(exclude=None):
""" Close all open file descriptors.
:param exclude: Collection of file descriptors to skip when closing
@@ -859,6 +861,8 @@
close.
"""
+ if exclude is None:
+ exclude = set()
maxfd = get_maximum_file_descriptors()
for fd in reversed(range(maxfd)):
if fd not in exclude:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/daemon/runner.py new/python-daemon-2.1.2/daemon/runner.py
--- old/python-daemon-2.1.1/daemon/runner.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/daemon/runner.py 2016-10-26 11:55:44.000000000 +0200
@@ -19,10 +19,19 @@
from __future__ import (absolute_import, unicode_literals)
-import sys
+import errno
import os
import signal
-import errno
+import sys
+import warnings
+
+import lockfile
+
+from . import pidfile
+from .daemon import (basestring, unicode)
+from .daemon import DaemonContext
+from .daemon import _chain_exception_from_existing_exception_context
+
try:
# Python 3 standard library.
ProcessLookupError
@@ -30,12 +39,12 @@
# No such class in Python 2.
ProcessLookupError = NotImplemented
-import lockfile
+__metaclass__ = type
-from . import pidfile
-from .daemon import (basestring, unicode)
-from .daemon import DaemonContext
-from .daemon import _chain_exception_from_existing_exception_context
+
+warnings.warn(
+ "The ‘runner’ module is not a supported API for this library.",
+ PendingDeprecationWarning)
class DaemonRunnerError(Exception):
@@ -77,8 +86,6 @@
"""
- __metaclass__ = type
-
start_message = "started with pid {pid:d}"
def __init__(self, app):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/doc/hacking.txt new/python-daemon-2.1.2/doc/hacking.txt
--- old/python-daemon-2.1.1/doc/hacking.txt 2015-09-27 03:14:46.000000000 +0200
+++ new/python-daemon-2.1.2/doc/hacking.txt 2016-10-22 04:03:18.000000000 +0200
@@ -2,7 +2,26 @@
#################
:Author: Ben Finney
-:Updated: 2015-09-27
+:Updated: 2016-10-21
+
+
+VCS repository
+==============
+
+The official Version Control System (VCS) for this code base is the
+Git repository at `the ‘python-daemon’ Pagure project`_.
+
+You can submit your proposed changes as merge requests:
+
+* Use your Pagure account and use the “pull request” feature.
+
+* Subscribe to `the ‘python-daemon-devel’ discussion forum`_ and
+ direct us to a branch in your published fork.
+
+
+.. _the ‘python-daemon’ Pagure project: https://pagure.io/python-daemon/
+.. _the ‘python-daemon-devel’ discussion forum:
+ https://lists.alioth.debian.org/mailman/listinfo/python-daemon-devel
Project layout
@@ -84,7 +103,7 @@
* The first line is a one-line synopsis of the object. This summary
line appears on the same line as the opening triple-quote,
separated by a single space.
-
+
* Further lines, if needed, are separated from the first by one
blank line.
@@ -97,7 +116,7 @@
field names are: “param foo” for each parameter (where “foo” is
the parameter name), and “return” for the return value. The field
values describe the purpose of each.
-
+
* The closing triple-quote appears on a separate line.
Example::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/python_daemon.egg-info/PKG-INFO new/python-daemon-2.1.2/python_daemon.egg-info/PKG-INFO
--- old/python-daemon-2.1.1/python_daemon.egg-info/PKG-INFO 2016-01-30 03:06:44.000000000 +0100
+++ new/python-daemon-2.1.2/python_daemon.egg-info/PKG-INFO 2016-10-26 12:09:22.000000000 +0200
@@ -1,8 +1,8 @@
Metadata-Version: 1.1
Name: python-daemon
-Version: 2.1.1
+Version: 2.1.2
Summary: Library to implement a well-behaved Unix daemon process.
-Home-page: https://alioth.debian.org/projects/python-daemon/
+Home-page: https://pagure.io/python-daemon/
Author: Ben Finney
Author-email: ben+python@benfinney.id.au
License: Apache-2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/python_daemon.egg-info/SOURCES.txt new/python-daemon-2.1.2/python_daemon.egg-info/SOURCES.txt
--- old/python-daemon-2.1.1/python_daemon.egg-info/SOURCES.txt 2016-01-30 03:06:44.000000000 +0100
+++ new/python-daemon-2.1.2/python_daemon.egg-info/SOURCES.txt 2016-10-26 12:09:22.000000000 +0200
@@ -2,6 +2,7 @@
LICENSE.ASF-2
LICENSE.GPL-3
MANIFEST.in
+README
setup.cfg
setup.py
test_version.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/python_daemon.egg-info/version_info.json new/python-daemon-2.1.2/python_daemon.egg-info/version_info.json
--- old/python-daemon-2.1.1/python_daemon.egg-info/version_info.json 2016-01-30 03:06:44.000000000 +0100
+++ new/python-daemon-2.1.2/python_daemon.egg-info/version_info.json 2016-10-26 12:09:22.000000000 +0200
@@ -1,6 +1,6 @@
{
- "release_date": "2016-01-30",
- "version": "2.1.1",
+ "release_date": "2016-10-26",
+ "version": "2.1.2",
"maintainer": "Ben Finney ",
- "body": "* Default \u2018initgroups\u2019 option to False. Using \u2018os.initgroups\u2019 requires\n permission to set process GID, so this now needs to be explicitly requested.\n"
+ "body": "Additions:* Add a README document for the code base.\nChanges:* Migrate code project hosting to Pagure. Record the change of homepage URL in\n PyPI metadata.\n* Raise a warning that the \u2018runner\u2019 module is pending deprecation. This has been\n an unofficial example module from the beginning, and it will be removed in a\n future version.\nBug Fixes:* Ensure custom types are part of the Python type hierarchy.\n* Avoid a circular dependency for the version string at install time. Thanks to\n Maarten van Gompel for the reproducible test case.\n"
}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/setup.cfg new/python-daemon-2.1.2/setup.cfg
--- old/python-daemon-2.1.1/setup.cfg 2016-01-30 03:06:58.000000000 +0100
+++ new/python-daemon-2.1.2/setup.cfg 2016-10-26 12:09:22.000000000 +0200
@@ -8,7 +8,7 @@
sign = true
[egg_info]
-tag_svn_revision = 0
-tag_date = 0
tag_build =
+tag_date = 0
+tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/setup.py new/python-daemon-2.1.2/setup.py
--- old/python-daemon-2.1.1/setup.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/setup.py 2016-10-22 07:03:04.000000000 +0200
@@ -16,10 +16,7 @@
from __future__ import (absolute_import, unicode_literals)
import sys
-import os
-import os.path
import pydoc
-import distutils.util
from setuptools import (setup, find_packages)
@@ -41,16 +38,10 @@
(synopsis, long_description) = pydoc.splitdoc(pydoc.getdoc(main_module))
-version_info = metadata.get_distribution_version_info()
-version_string = version_info['version']
-
-(maintainer_name, maintainer_email) = metadata.parse_person_field(
- version_info['maintainer'])
-
setup(
+ distclass=version.ChangelogAwareDistribution,
name=metadata.distribution_name,
- version=version_string,
packages=find_packages(exclude=["test"]),
cmdclass={
"write_version_info": version.WriteVersionInfoCommand,
@@ -58,8 +49,6 @@
},
# Setuptools metadata.
- maintainer=maintainer_name,
- maintainer_email=maintainer_email,
zip_safe=False,
setup_requires=[
"docutils",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/test/test_daemon.py new/python-daemon-2.1.2/test/test_daemon.py
--- old/python-daemon-2.1.1/test/test_daemon.py 2016-01-30 03:02:20.000000000 +0100
+++ new/python-daemon-2.1.2/test/test_daemon.py 2016-10-21 14:57:20.000000000 +0200
@@ -20,18 +20,13 @@
import pwd
import tempfile
import resource
+import io
import errno
import signal
import socket
from types import ModuleType
import collections
import functools
-try:
- # Standard library of Python 2.7 and later.
- from io import StringIO
-except ImportError:
- # Standard library of Python 2.6 and earlier.
- from StringIO import StringIO
import mock
@@ -744,16 +739,9 @@
instance = self.test_instance
instance.files_preserve = list(self.test_files.values())
stream_files = self.stream_files_by_name
- mock_fileno_method = mock.MagicMock(
- spec=sys.__stdin__.fileno,
- side_effect=ValueError)
expected_result = self.test_file_descriptors.copy()
for (pseudo_stream_name, pseudo_stream) in stream_files.items():
- test_non_fd_stream = StringIO()
- if not hasattr(test_non_fd_stream, 'fileno'):
- # Python < 3 StringIO doesn't have ‘fileno’ at all.
- # Add a method which raises an exception.
- test_non_fd_stream.fileno = mock_fileno_method
+ test_non_fd_stream = io.StringIO()
setattr(instance, pseudo_stream_name, test_non_fd_stream)
stream_fd = pseudo_stream.fileno()
expected_result.discard(stream_fd)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/test/test_metadata.py new/python-daemon-2.1.2/test/test_metadata.py
--- old/python-daemon-2.1.1/test/test_metadata.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/test/test_metadata.py 2016-10-21 14:57:20.000000000 +0200
@@ -15,7 +15,6 @@
from __future__ import (absolute_import, unicode_literals)
-import sys
import errno
import re
try:
@@ -32,10 +31,9 @@
import mock
import testtools.helpers
import testtools.matchers
-import testscenarios
from . import scaffold
-from .scaffold import (basestring, unicode)
+from .scaffold import unicode
import daemon._metadata as metadata
@@ -106,40 +104,6 @@
instance, HasAttribute(self.ducktype_attribute_name))
-class parse_person_field_TestCase(
- testscenarios.WithScenarios, testtools.TestCase):
- """ Test cases for ‘get_latest_version’ function. """
-
- scenarios = [
- ('simple', {
- 'test_person': "Foo Bar ",
- 'expected_result': ("Foo Bar", "foo.bar@example.com"),
- }),
- ('empty', {
- 'test_person': "",
- 'expected_result': (None, None),
- }),
- ('none', {
- 'test_person': None,
- 'expected_error': TypeError,
- }),
- ('no email', {
- 'test_person': "Foo Bar",
- 'expected_result': ("Foo Bar", None),
- }),
- ]
-
- def test_returns_expected_result(self):
- """ Should return expected result. """
- if hasattr(self, 'expected_error'):
- self.assertRaises(
- self.expected_error,
- metadata.parse_person_field, self.test_person)
- else:
- result = metadata.parse_person_field(self.test_person)
- self.assertEqual(self.expected_result, result)
-
-
class YearRange_TestCase(scaffold.TestCaseWithScenarios):
""" Test cases for ‘YearRange’ class. """
@@ -266,7 +230,7 @@
def fake_func_has_metadata(testcase, resource_name):
""" Fake the behaviour of ‘pkg_resources.Distribution.has_metadata’. """
if (
- resource_name != testcase.expected_resource_name
+ resource_name != testcase.version_info_filename
or not hasattr(testcase, 'test_version_info')):
return False
return True
@@ -319,10 +283,12 @@
'expected_version_info': {'version': "1.0"},
}),
('file lorem_ipsum.json', {
+ 'test_filename': "lorem_ipsum.json",
'version_info_filename': "lorem_ipsum.json",
'test_version_info': json.dumps({
'version': "1.0",
}),
+ 'expected_resource_name': "lorem_ipsum.json",
'expected_version_info': {'version': "1.0"},
}),
('not installed', {
@@ -332,16 +298,28 @@
('no version_info', {
'expected_version_info': default_version_info,
}),
+ ('wrong filename', {
+ 'test_filename': "lorem_ipsum.json",
+ 'test_version_info': json.dumps({
+ 'version': "1.0",
+ }),
+ 'expected_resource_name': "lorem_ipsum.json",
+ 'expected_version_info': default_version_info,
+ }),
]
def setUp(self):
""" Set up test fixtures. """
super(get_distribution_version_info_TestCase, self).setUp()
- if hasattr(self, 'expected_resource_name'):
- self.test_args = {'filename': self.expected_resource_name}
- else:
- self.test_args = {}
+ self.test_args = {}
+ if hasattr(self, 'test_filename'):
+ self.test_args['filename'] = self.test_filename
+
+ if not hasattr(self, 'version_info_filename'):
+ self.version_info_filename = version_info_filename
+
+ if not hasattr(self, 'expected_resource_name'):
self.expected_resource_name = version_info_filename
self.mock_distribution = mock.MagicMock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/test/test_pidfile.py new/python-daemon-2.1.2/test/test_pidfile.py
--- old/python-daemon-2.1.1/test/test_pidfile.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/test/test_pidfile.py 2016-10-21 14:57:20.000000000 +0200
@@ -24,14 +24,9 @@
import os
import itertools
import tempfile
+import io
import errno
import functools
-try:
- # Standard library of Python 2.7 and later.
- from io import StringIO
-except ImportError:
- # Standard library of Python 2.6 and earlier.
- from StringIO import StringIO
import mock
import lockfile
@@ -41,7 +36,7 @@
import daemon.pidfile
-class FakeFileDescriptorStringIO(StringIO, object):
+class FakeFileDescriptorStringIO(io.StringIO, object):
""" A StringIO class that fakes a file descriptor. """
_fileno_generator = itertools.count()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/test_version.py new/python-daemon-2.1.2/test_version.py
--- old/python-daemon-2.1.1/test_version.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/test_version.py 2016-10-22 07:09:24.000000000 +0200
@@ -19,7 +19,6 @@
import io
import errno
import functools
-import contextlib
import collections
import textwrap
import json
@@ -28,12 +27,6 @@
import distutils.cmd
import distutils.errors
import distutils.fancy_getopt
-try:
- # Standard library of Python 2.7 and later.
- from io import StringIO
-except ImportError:
- # Standard library of Python 2.6 and earlier.
- from StringIO import StringIO
import mock
import testtools
@@ -52,6 +45,8 @@
version.__dict__, str('VersionInfoTranslator'),
docutils.nodes.SparseNodeVisitor)
+__metaclass__ = type
+
def make_test_classes_for_ensure_class_bases_begin_with():
""" Make test classes for use with ‘ensure_class_bases_begin_with’.
@@ -250,6 +245,40 @@
self.assertEqual(expected_output, instance.output)
+class parse_person_field_TestCase(
+ testscenarios.WithScenarios, testtools.TestCase):
+ """ Test cases for ‘get_latest_version’ function. """
+
+ scenarios = [
+ ('simple', {
+ 'test_person': "Foo Bar ",
+ 'expected_result': ("Foo Bar", "foo.bar@example.com"),
+ }),
+ ('empty', {
+ 'test_person': "",
+ 'expected_result': (None, None),
+ }),
+ ('none', {
+ 'test_person': None,
+ 'expected_error': TypeError,
+ }),
+ ('no email', {
+ 'test_person': "Foo Bar",
+ 'expected_result': ("Foo Bar", None),
+ }),
+ ]
+
+ def test_returns_expected_result(self):
+ """ Should return expected result. """
+ if hasattr(self, 'expected_error'):
+ self.assertRaises(
+ self.expected_error,
+ version.parse_person_field, self.test_person)
+ else:
+ result = version.parse_person_field(self.test_person)
+ self.assertEqual(self.expected_result, result)
+
+
class NoOpContextManager:
""" A context manager with no effect. """
def __enter__(self): pass
@@ -753,7 +782,7 @@
def test_returns_expected_version_info(self):
""" Should return expected version info mapping. """
- infile = StringIO(self.test_input)
+ infile = io.StringIO(self.test_input)
with self.expected_error_context():
result = version.changelog_to_version_info_collection(infile)
if hasattr(self, 'expected_version_info'):
@@ -781,7 +810,7 @@
fake_open_side_effects = {
'success': (
- lambda *args, **kwargs: StringIO()),
+ lambda *args, **kwargs: io.StringIO()),
'file not found': FileNotFoundError(),
'permission denied': PermissionError(),
}
@@ -816,7 +845,7 @@
else:
raise side_effect
else:
- result = StringIO()
+ result = io.StringIO()
return result
func_patcher_io_open = mock.patch.object(
@@ -1244,7 +1273,7 @@
if hasattr(self, 'changelog_path'):
self.fake_changelog_file_path = self.changelog_path
version.get_changelog_path.return_value = self.fake_changelog_file_path
- self.fake_changelog_file = StringIO()
+ self.fake_changelog_file = io.StringIO()
def fake_os_path_exists(path):
if path == self.fake_changelog_file_path:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-daemon-2.1.1/version.py new/python-daemon-2.1.2/version.py
--- old/python-daemon-2.1.1/version.py 2016-01-30 03:01:02.000000000 +0100
+++ new/python-daemon-2.1.2/version.py 2016-10-22 07:09:24.000000000 +0200
@@ -32,7 +32,6 @@
import sys
import os
import io
-import errno
import json
import datetime
import textwrap
@@ -42,7 +41,12 @@
import distutils
import distutils.errors
import distutils.cmd
+import distutils.dist
import distutils.version
+
+import setuptools
+import setuptools.command.egg_info
+
try:
# Python 2 has both ‘str’ (bytes) and ‘unicode’ (text).
basestring = basestring
@@ -52,8 +56,7 @@
basestring = str
unicode = str
-import setuptools
-import setuptools.command.egg_info
+__metaclass__ = type
def ensure_class_bases_begin_with(namespace, class_name, base_class):
@@ -117,10 +120,36 @@
self.document.walkabout(visitor)
self.output = visitor.astext()
-
+
rfc822_person_regex = re.compile(
"^(?P<name>[^<]+) <(?P<email>[^>]+)>$")
+ParsedPerson = collections.namedtuple('ParsedPerson', ['name', 'email'])
+
+def parse_person_field(value):
+ """ Parse a person field into name and email address.
+
+ :param value: The text value specifying a person.
+ :return: A 2-tuple (name, email) for the person's details.
+
+ If the `value` does not match a standard person with email
+ address, the `email` item is ``None``.
+
+ """
+ result = ParsedPerson(None, None)
+
+ match = rfc822_person_regex.match(value)
+ if len(value):
+ if match is not None:
+ result = ParsedPerson(
+ name=match.group('name'),
+ email=match.group('email'))
+ else:
+ result = ParsedPerson(name=value, email=None)
+
+ return result
+
+
class ChangeLogEntry:
""" An individual entry from the ‘ChangeLog’ document. """
@@ -228,6 +257,22 @@
class InvalidFormatError(ValueError):
""" Raised when the document is not a valid ‘ChangeLog’ document. """
+ def __init__(self, node, message=None):
+ self.node = node
+ self.message = message
+
+ def __str__(self):
+ text = "{message}: {source} line {line:d}".format(
+ message=(
+ getattr(self, 'message', "(no message)")),
+ source=(
+ getattr(self.node, 'source', "(source unknown)")),
+ line=(
+ getattr(self.node, 'line', "(unknown)")),
+ )
+
+ return text
+
class VersionInfoTranslator(object):
""" Translator from document nodes to a version info stream. """
@@ -254,7 +299,6 @@
def __init__(self, document):
super(VersionInfoTranslator, self).__init__(document)
self.settings = document.settings
- self.current_section_level = 0
self.current_field_name = None
self.content = []
self.indent_width = 0
@@ -295,8 +339,18 @@
field_list_node = node.parent.parent
if not isinstance(field_list_node, self._docutils.nodes.field_list):
raise InvalidFormatError(
+ node,
"Unexpected field within {node!r}".format(
node=field_list_node))
+ if not isinstance(
+ field_list_node.parent, self._docutils.nodes.section):
+ # Field list is not in a section.
+ raise self._docutils.nodes.SkipNode
+ if not self.current_field_name in self.attr_convert_funcs_by_attr_name:
+ raise InvalidFormatError(
+ node,
+ "Unexpected field name {name!r}".format(
+ name=self.current_field_name))
(attr_name, convert_func) = self.attr_convert_funcs_by_attr_name[
self.current_field_name]
attr_value = convert_func(node.astext())
@@ -314,12 +368,20 @@
def visit_field_name(self, node):
field_name = node.astext()
- if self.current_section_level == 1:
- # At a top-level section.
- if field_name.lower() not in ["released", "maintainer"]:
- raise InvalidFormatError(
- "Unexpected field name {name!r}".format(name=field_name))
- self.current_field_name = field_name.lower()
+ self.current_field_name = field_name.lower()
+ field_list_node = node.parent
+ if not isinstance(
+ field_list_node.parent, self._docutils.nodes.section):
+ # Field list is not in a section.
+ raise self._docutils.nodes.SkipNode
+ if not isinstance(
+ field_list_node.parent.parent, self._docutils.nodes.Root):
+ # The section is not top-level.
+ raise self._docutils.nodes.SkipNode
+ if field_name.lower() not in ["released", "maintainer"]:
+ raise InvalidFormatError(
+ node,
+ "Unexpected field name {name!r}".format(name=field_name))
def depart_field_name(self, node):
pass
@@ -348,16 +410,12 @@
self.append_to_current_entry("\n")
def visit_section(self, node):
- self.current_section_level += 1
- if self.current_section_level == 1:
- # At a top-level section.
- self.current_entry = ChangeLogEntry()
- else:
+ if not isinstance(node.parent, self._docutils.nodes.Root):
raise InvalidFormatError(
- "Subsections not implemented for this writer")
+ node, "Subsections not implemented for this writer")
+ self.current_entry = ChangeLogEntry()
def depart_section(self, node):
- self.current_section_level -= 1
self.content.append(
self.current_entry.as_version_info_entry())
self.current_entry = None
@@ -366,14 +424,15 @@
def depart_title(self, node):
title_text = node.astext()
- # At a top-level section.
words = title_text.split(" ")
version = None
if len(words) != self._expected_title_word_length:
raise InvalidFormatError(
+ node,
"Unexpected title text {text!r}".format(text=title_text))
if words[0].lower() not in ["version"]:
raise InvalidFormatError(
+ node,
"Unexpected title text {text!r}".format(text=title_text))
version = words[-1]
self.current_entry.version = version
@@ -563,6 +622,52 @@
self.write_file("version info", self.outfile_path, content)
+class ChangelogAwareDistribution(distutils.dist.Distribution, object):
+ """ A distribution of Python code for installation.
+
+ This class gets the following attributes instead from the
+ ‘ChangeLog’ document:
+
+ * version
+ * maintainer
+ * maintainer_email
+
+ """
+
+ __metaclass__ = type
+
+ def __init__(self, *args, **kwargs):
+ super(ChangelogAwareDistribution, self).__init__(*args, **kwargs)
+
+ # Undo the per-instance delegation for these methods.
+ del (
+ self.get_version,
+ self.get_maintainer,
+ self.get_maintainer_email,
+ )
+
+ @lru_cache(maxsize=128)
+ def get_version_info(self):
+ changelog_path = get_changelog_path(self)
+ version_info = generate_version_info_from_changelog(changelog_path)
+ return version_info
+
+ def get_version(self):
+ version_info = self.get_version_info()
+ version_string = version_info['version']
+ return version_string
+
+ def get_maintainer(self):
+ version_info = self.get_version_info()
+ person = parse_person_field(version_info['maintainer'])
+ return person.name
+
+ def get_maintainer_email(self):
+ version_info = self.get_version_info()
+ person = parse_person_field(version_info['maintainer'])
+ return person.email
+
+
# Local variables:
# coding: utf-8
# mode: python