summaryrefslogtreecommitdiffstats
path: root/external_libs/python/python-daemon-2.0.5/version.py
diff options
context:
space:
mode:
Diffstat (limited to 'external_libs/python/python-daemon-2.0.5/version.py')
-rw-r--r--external_libs/python/python-daemon-2.0.5/version.py547
1 files changed, 0 insertions, 547 deletions
diff --git a/external_libs/python/python-daemon-2.0.5/version.py b/external_libs/python/python-daemon-2.0.5/version.py
deleted file mode 100644
index 7e4c4202..00000000
--- a/external_libs/python/python-daemon-2.0.5/version.py
+++ /dev/null
@@ -1,547 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# version.py
-# Part of ‘python-daemon’, an implementation of PEP 3143.
-#
-# Copyright © 2008–2015 Ben Finney <ben+python@benfinney.id.au>
-#
-# This is free software: you may copy, modify, and/or distribute this work
-# 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.
-# No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details.
-
-""" Version information unified for human- and machine-readable formats.
-
- The project ‘ChangeLog’ file is a reStructuredText document, with
- each section describing a version of the project. The document is
- intended to be readable as-is by end users.
-
- This module handles transformation from the ‘ChangeLog’ to a
- mapping of version information, serialised as JSON. It also
- provides functionality for Distutils to use this information.
-
- Requires:
-
- * Docutils <http://docutils.sourceforge.net/>
- * JSON <https://docs.python.org/3/reference/json.html>
-
- """
-
-from __future__ import (absolute_import, unicode_literals)
-
-import sys
-import os
-import io
-import errno
-import json
-import datetime
-import textwrap
-import re
-import functools
-import collections
-import distutils
-import distutils.errors
-import distutils.cmd
-try:
- # Python 2 has both ‘str’ (bytes) and ‘unicode’ (text).
- basestring = basestring
- unicode = unicode
-except NameError:
- # Python 3 names the Unicode data type ‘str’.
- basestring = str
- unicode = str
-
-import setuptools
-import setuptools.command.egg_info
-
-
-def ensure_class_bases_begin_with(namespace, class_name, base_class):
- """ Ensure the named class's bases start with the base class.
-
- :param namespace: The namespace containing the class name.
- :param class_name: The name of the class to alter.
- :param base_class: The type to be the first base class for the
- newly created type.
- :return: ``None``.
-
- This function is a hack to circumvent a circular dependency:
- using classes from a module which is not installed at the time
- this module is imported.
-
- Call this function after ensuring `base_class` is available,
- before using the class named by `class_name`.
-
- """
- existing_class = namespace[class_name]
- assert isinstance(existing_class, type)
-
- bases = list(existing_class.__bases__)
- if base_class is bases[0]:
- # Already bound to a type with the right bases.
- return
- bases.insert(0, base_class)
-
- new_class_namespace = existing_class.__dict__.copy()
- # Type creation will assign the correct ‘__dict__’ attribute.
- del new_class_namespace['__dict__']
-
- metaclass = existing_class.__metaclass__
- new_class = metaclass(class_name, tuple(bases), new_class_namespace)
-
- namespace[class_name] = new_class
-
-
-class VersionInfoWriter(object):
- """ Docutils writer to produce a version info JSON data stream. """
-
- # This class needs its base class to be a class from `docutils`.
- # But that would create a circular dependency: Setuptools cannot
- # ensure `docutils` is available before importing this module.
- #
- # Use `ensure_class_bases_begin_with` after importing `docutils`, to
- # re-bind the `VersionInfoWriter` name to a new type that inherits
- # from `docutils.writers.Writer`.
-
- __metaclass__ = type
-
- supported = ['version_info']
- """ Formats this writer supports. """
-
- def __init__(self):
- super(VersionInfoWriter, self).__init__()
- self.translator_class = VersionInfoTranslator
-
- def translate(self):
- visitor = self.translator_class(self.document)
- self.document.walkabout(visitor)
- self.output = visitor.astext()
-
-
-rfc822_person_regex = re.compile(
- "^(?P<name>[^<]+) <(?P<email>[^>]+)>$")
-
-class ChangeLogEntry:
- """ An individual entry from the ‘ChangeLog’ document. """
-
- __metaclass__ = type
-
- field_names = [
- 'release_date',
- 'version',
- 'maintainer',
- 'body',
- ]
-
- date_format = "%Y-%m-%d"
- default_version = "UNKNOWN"
- default_release_date = "UNKNOWN"
-
- def __init__(
- self,
- release_date=default_release_date, version=default_version,
- maintainer=None, body=None):
- self.validate_release_date(release_date)
- self.release_date = release_date
-
- self.version = version
-
- self.validate_maintainer(maintainer)
- self.maintainer = maintainer
- self.body = body
-
- @classmethod
- def validate_release_date(cls, value):
- """ Validate the `release_date` value.
-
- :param value: The prospective `release_date` value.
- :return: ``None`` if the value is valid.
- :raises ValueError: If the value is invalid.
-
- """
- if value in ["UNKNOWN", "FUTURE"]:
- # A valid non-date value.
- return None
-
- # Raises `ValueError` if parse fails.
- datetime.datetime.strptime(value, ChangeLogEntry.date_format)
-
- @classmethod
- def validate_maintainer(cls, value):
- """ Validate the `maintainer` value.
-
- :param value: The prospective `maintainer` value.
- :return: ``None`` if the value is valid.
- :raises ValueError: If the value is invalid.
-
- """
- valid = False
-
- if value is None:
- valid = True
- elif rfc822_person_regex.search(value):
- valid = True
-
- if not valid:
- raise ValueError("Not a valid person specification {value!r}")
- else:
- return None
-
- @classmethod
- def make_ordered_dict(cls, fields):
- """ Make an ordered dict of the fields. """
- result = collections.OrderedDict(
- (name, fields[name])
- for name in cls.field_names)
- return result
-
- def as_version_info_entry(self):
- """ Format the changelog entry as a version info entry. """
- fields = vars(self)
- entry = self.make_ordered_dict(fields)
-
- return entry
-
-
-class InvalidFormatError(ValueError):
- """ Raised when the document is not a valid ‘ChangeLog’ document. """
-
-
-class VersionInfoTranslator(object):
- """ Translator from document nodes to a version info stream. """
-
- # This class needs its base class to be a class from `docutils`.
- # But that would create a circular dependency: Setuptools cannot
- # ensure `docutils` is available before importing this module.
- #
- # Use `ensure_class_bases_begin_with` after importing `docutils`,
- # to re-bind the `VersionInfoTranslator` name to a new type that
- # inherits from `docutils.nodes.SparseNodeVisitor`.
-
- __metaclass__ = type
-
- wrap_width = 78
- bullet_text = "* "
-
- attr_convert_funcs_by_attr_name = {
- 'released': ('release_date', unicode),
- 'version': ('version', unicode),
- 'maintainer': ('maintainer', unicode),
- }
-
- 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
- self.initial_indent = ""
- self.subsequent_indent = ""
- self.current_entry = None
-
- # Docutils is not available when this class is defined.
- # Get the `docutils` module dynamically.
- self._docutils = sys.modules['docutils']
-
- def astext(self):
- """ Return the translated document as text. """
- text = json.dumps(self.content, indent=4)
- return text
-
- def append_to_current_entry(self, text):
- if self.current_entry is not None:
- if self.current_entry.body is not None:
- self.current_entry.body += text
-
- def visit_Text(self, node):
- raw_text = node.astext()
- text = textwrap.fill(
- raw_text,
- width=self.wrap_width,
- initial_indent=self.initial_indent,
- subsequent_indent=self.subsequent_indent)
- self.append_to_current_entry(text)
-
- def depart_Text(self, node):
- pass
-
- def visit_comment(self, node):
- raise self._docutils.nodes.SkipNode
-
- def visit_field_body(self, node):
- field_list_node = node.parent.parent
- if not isinstance(field_list_node, self._docutils.nodes.field_list):
- raise InvalidFormatError(
- "Unexpected field within {node!r}".format(
- node=field_list_node))
- (attr_name, convert_func) = self.attr_convert_funcs_by_attr_name[
- self.current_field_name]
- attr_value = convert_func(node.astext())
- setattr(self.current_entry, attr_name, attr_value)
-
- def depart_field_body(self, node):
- pass
-
- def visit_field_list(self, node):
- pass
-
- def depart_field_list(self, node):
- self.current_field_name = None
- self.current_entry.body = ""
-
- 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()
-
- def depart_field_name(self, node):
- pass
-
- def visit_bullet_list(self, node):
- self.current_context = []
-
- def depart_bullet_list(self, node):
- self.current_entry.changes = self.current_context
- self.current_context = None
-
- def adjust_indent_width(self, delta):
- self.indent_width += delta
- self.subsequent_indent = " " * self.indent_width
- self.initial_indent = self.subsequent_indent
-
- def visit_list_item(self, node):
- indent_delta = +len(self.bullet_text)
- self.adjust_indent_width(indent_delta)
- self.initial_indent = self.subsequent_indent[:-indent_delta]
- self.append_to_current_entry(self.initial_indent + self.bullet_text)
-
- def depart_list_item(self, node):
- indent_delta = +len(self.bullet_text)
- self.adjust_indent_width(-indent_delta)
- 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:
- raise InvalidFormatError(
- "Subsections not implemented for this writer")
-
- def depart_section(self, node):
- self.current_section_level -= 1
- self.content.append(
- self.current_entry.as_version_info_entry())
- self.current_entry = None
-
- _expected_title_word_length = len("Version FOO".split(" "))
-
- 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(
- "Unexpected title text {text!r}".format(text=title_text))
- if words[0].lower() not in ["version"]:
- raise InvalidFormatError(
- "Unexpected title text {text!r}".format(text=title_text))
- version = words[-1]
- self.current_entry.version = version
-
-
-def changelog_to_version_info_collection(infile):
- """ Render the ‘ChangeLog’ document to a version info collection.
-
- :param infile: A file-like object containing the changelog.
- :return: The serialised JSON data of the version info collection.
-
- """
-
- # Docutils is not available when Setuptools needs this module, so
- # delay the imports to this function instead.
- import docutils.core
- import docutils.nodes
- import docutils.writers
-
- ensure_class_bases_begin_with(
- globals(), str('VersionInfoWriter'), docutils.writers.Writer)
- ensure_class_bases_begin_with(
- globals(), str('VersionInfoTranslator'),
- docutils.nodes.SparseNodeVisitor)
-
- writer = VersionInfoWriter()
- settings_overrides = {
- 'doctitle_xform': False,
- }
- version_info_json = docutils.core.publish_string(
- infile.read(), writer=writer,
- settings_overrides=settings_overrides)
-
- return version_info_json
-
-
-try:
- lru_cache = functools.lru_cache
-except AttributeError:
- # Python < 3.2 does not have the `functools.lru_cache` function.
- # Not essential, so replace it with a no-op.
- lru_cache = lambda maxsize=None, typed=False: lambda func: func
-
-
-@lru_cache(maxsize=128)
-def generate_version_info_from_changelog(infile_path):
- """ Get the version info for the latest version in the changelog.
-
- :param infile_path: Filesystem path to the input changelog file.
- :return: The generated version info mapping; or ``None`` if the
- file cannot be read.
-
- The document is explicitly opened as UTF-8 encoded text.
-
- """
- version_info = collections.OrderedDict()
-
- versions_all_json = None
- try:
- with io.open(infile_path, 'rt', encoding="utf-8") as infile:
- versions_all_json = changelog_to_version_info_collection(infile)
- except EnvironmentError:
- # If we can't read the input file, leave the collection empty.
- pass
-
- if versions_all_json is not None:
- versions_all = json.loads(versions_all_json.decode('utf-8'))
- version_info = get_latest_version(versions_all)
-
- return version_info
-
-
-def get_latest_version(versions):
- """ Get the latest version from a collection of changelog entries.
-
- :param versions: A collection of mappings for changelog entries.
- :return: An ordered mapping of fields for the latest version,
- if `versions` is non-empty; otherwise, an empty mapping.
-
- """
- version_info = collections.OrderedDict()
-
- versions_by_release_date = {
- item['release_date']: item
- for item in versions}
- if versions_by_release_date:
- latest_release_date = max(versions_by_release_date.keys())
- version_info = ChangeLogEntry.make_ordered_dict(
- versions_by_release_date[latest_release_date])
-
- return version_info
-
-
-def serialise_version_info_from_mapping(version_info):
- """ Generate the version info serialised data.
-
- :param version_info: Mapping of version info items.
- :return: The version info serialised to JSON.
-
- """
- content = json.dumps(version_info, indent=4)
-
- return content
-
-
-changelog_filename = "ChangeLog"
-
-def get_changelog_path(distribution, filename=changelog_filename):
- """ Get the changelog file path for the distribution.
-
- :param distribution: The distutils.dist.Distribution instance.
- :param filename: The base filename of the changelog document.
- :return: Filesystem path of the changelog document, or ``None``
- if not discoverable.
-
- """
- setup_dirname = os.path.dirname(distribution.script_name)
- filepath = os.path.join(setup_dirname, filename)
-
- return filepath
-
-
-def has_changelog(command):
- """ Return ``True`` iff the distribution's changelog file exists. """
- result = False
-
- changelog_path = get_changelog_path(command.distribution)
- if changelog_path is not None:
- if os.path.exists(changelog_path):
- result = True
-
- return result
-
-
-class EggInfoCommand(setuptools.command.egg_info.egg_info, object):
- """ Custom ‘egg_info’ command for this distribution. """
-
- sub_commands = ([
- ('write_version_info', has_changelog),
- ] + setuptools.command.egg_info.egg_info.sub_commands)
-
- def run(self):
- """ Execute this command. """
- super(EggInfoCommand, self).run()
-
- for command_name in self.get_sub_commands():
- self.run_command(command_name)
-
-
-version_info_filename = "version_info.json"
-
-class WriteVersionInfoCommand(EggInfoCommand, object):
- """ Setuptools command to serialise version info metadata. """
-
- user_options = ([
- ("changelog-path=", None,
- "Filesystem path to the changelog document."),
- ("outfile-path=", None,
- "Filesystem path to the version info file."),
- ] + EggInfoCommand.user_options)
-
- def initialize_options(self):
- """ Initialise command options to defaults. """
- super(WriteVersionInfoCommand, self).initialize_options()
- self.changelog_path = None
- self.outfile_path = None
-
- def finalize_options(self):
- """ Finalise command options before execution. """
- self.set_undefined_options(
- 'build',
- ('force', 'force'))
-
- super(WriteVersionInfoCommand, self).finalize_options()
-
- if self.changelog_path is None:
- self.changelog_path = get_changelog_path(self.distribution)
-
- if self.outfile_path is None:
- egg_dir = self.egg_info
- self.outfile_path = os.path.join(egg_dir, version_info_filename)
-
- def run(self):
- """ Execute this command. """
- version_info = generate_version_info_from_changelog(self.changelog_path)
- content = serialise_version_info_from_mapping(version_info)
- self.write_file("version info", self.outfile_path, content)
-
-
-# Local variables:
-# coding: utf-8
-# mode: python
-# End:
-# vim: fileencoding=utf-8 filetype=python :