[med-svn] [Git][python-team/packages/python-sinfo][upstream] New upstream version 1.0.0

Andreas Tille (@tille) gitlab at salsa.debian.org
Thu Jan 12 12:01:43 GMT 2023



Andreas Tille pushed to branch upstream at Debian Python Team / packages / python-sinfo


Commits:
e13cb9bd by Andreas Tille at 2023-01-12T10:24:26+01:00
New upstream version 1.0.0
- - - - -


10 changed files:

- CHANGELOG.md
- CONTRIBUTING.md
- MANIFEST.in
- README.md
- sinfo/__init__.py → session_info/__init__.py
- sinfo/_version.py → session_info/_version.py
- sinfo/main.py → session_info/main.py
- setup.cfg
- setup.py
- versioneer.py


Changes:

=====================================
CHANGELOG.md
=====================================
@@ -1,10 +1,38 @@
 # Changelog
 
 All notable changes to this project will be documented in this file.
-
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
-## [0.3.1] - 20200115
+## [1.0.0] - 2021-05-26
+- This is a major release which breaks backwards compatibility since the package was renamed from `sinfo` to `session_info` and some defaults changed.
+
+## Added
+- Clearer examples in the README.
+
+## Changed
+- The package name was changed to `session_info` to make it more discoverable and self-explanatory.
+    - The `sinfo` PyPI package will be kept around to avoid breaking old installs and you can downgrade to 0.3.2 if you want to use it without seeing this message. For the latest features and bug fixes, please install `session_info` instead.
+- The syntax for the default usage changed from `from sinfo import sinfo; sinfo()` to `import session_info; session_info.show()`.
+- The default is now to show the HTML version in notebooks and to not write a requirement text file unless explicitly asked for.
+- The CPU info is excluded by default.
+
+## [0.3.4] - 2021-05-26
+### Added
+- Inform about package name change in the README.
+
+## [0.3.3] - 2021-05-26
+### Added
+- Inform about package name change when called.
+
+## [0.3.2] - 2021-05-06
+
+### Fixed
+- Do not print `None` for output fields that are not included in the output
+- Show only dependencies that are not already in the imported modules
+- Deal gracefully with version functions that do not return version strings
+- Use a single line for description in setup.py to avoid some installs breaking
+
+## [0.3.1] - 2020-01-15
 
 ### Changed
 - HTML defaults to False for output to show up on GitHub.


=====================================
CONTRIBUTING.md
=====================================
@@ -1,8 +1,8 @@
-Thanks for your interest in helping to improve `sinfo`!
+Thanks for your interest in helping to improve `session_info`!
 
 The best way to get in touch to discuss ideas is to [open a new
-issue](https://gitlab.com/joelostblom/sinfo/issues).
+issue](https://gitlab.com/joelostblom/session_info/issues).
 
 Remember to follow the [Code of
-conduct](https://gitlab.com/joelostblom/sinfo/blob/master/CODE_OF_CONDUCT.md)
+conduct](https://gitlab.com/joelostblom/session_info/blob/master/CODE_OF_CONDUCT.md)
 when you participate in this project =)


=====================================
MANIFEST.in
=====================================
@@ -1,2 +1,2 @@
 include versioneer.py
-include sinfo/_version.py
+include session_info/_version.py


=====================================
README.md
=====================================
@@ -1,77 +1,143 @@
-# sinfo
+# session_info
 
-`sinfo` outputs version information for modules loaded in the current session,
+`session_info` outputs version information for modules loaded in the current session,
 Python, the OS, and the CPU. It is designed as a minimum measure to increase
-reproducibility and provides similar information as `sessionInfo` in R. The
-name is shortened to encourage regular usage through reduced typing =)
+reproducibility and provides similar information as `sessionInfo` and
+`devtools::session_info` in R.
 
 ## Motivation
 
-`sinfo` is particularly useful when conducting exploratory data analysis in
+`session_info` is particularly useful when conducting exploratory data analysis in
 Jupyter notebooks. Listing the version numbers of all loaded modules after
 importing them is a simple way to ensure a minimum level of reproducibility
 while requiring little additional effort. This practice is useful both when
-revisiting notebooks and when sharing them with colleagues. `sinfo` is meant to
+revisiting notebooks and when sharing them with colleagues. `session_info` is meant to
 complement more robust practices such as frozen virtual environments,
 containers, and binder.
 
 ## Installation
 
-`sinfo` can be installed via `pip install sinfo`. It does not depend on a package
+`session_info` can be installed via `pip install session_info`. It does not depend on a package
 manager to find version numbers since it fetches them from the module's version
 string. Its only dependency is `stdlib_list`, which is used to distinguish
 between standard library and third party modules.
 
 ## Usage
 
+`session_info` can be used from a script like so:
+
 ```python
 import math
 
 import natsort
-import numpy
 import pandas
-from sinfo import sinfo
+import session_info
 
 
-sinfo()
+session_info.show()
 ```
 
 
 Output:
 
 ```
-
+Session information:
+-----
+natsort             7.1.1
+pandas              1.2.2
+session_info        1.0.0
 -----
-natsort     5.3.3
-numpy       1.17.3
-pandas      0.25.1
-sinfo       0.3.0
+IPython             7.23.0
+jupyter_client      6.1.12
+jupyter_core        4.7.1
 -----
-Python 3.7.3 | packaged by conda-forge | (default, Dec  6 2019, 08:54:18) [GCC 7.3.0]
-Linux-5.4.2-arch1-1-x86_64-with-arch
-4 logical CPU cores
+Python 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:46) [GCC 9.3.0]
+Linux-5.11.13-arch1-1-x86_64-with-glibc2.33
 -----
-Session information updated at 2019-12-14 16:14
+Session information updated at 2021-05-06 09:59
 ```
 
 The default behavior is to only output modules not in the standard library,
 which is why the `math` module is omitted above (it can be included by
 specifying `std_lib=True`). To include not only the explicitly imported
 modules, but also any dependencies they import internally, specify `dependencies=True`.
-The notebook output is concealed in `<details>` tags by default to not take up too much visual real estate.
-When called from a notebook, `sinfo` writes the module dependencies
-to a file called to `<notebook_name>-requirements.txt`, which is compatible with `pip install -r /path/to/requirements.txt`.
-See the docstring for complete parameter info.
+
+When `session_info` is invoked from a Jupyter Notebook,
+the output is concealed in `<details>` tags
+and will only show when clicked.
+Since this saves visual real estate,
+any modules imported indirectly as dependencies
+will be included by default
+and it looks like this:
+
+<details>
+<summary>Click to view session information</summary>
+<pre>
+-----
+natsort             7.1.1
+pandas              1.2.2
+session_info        1.0.0
+-----
+</pre>
+<details>
+<summary>Click to view modules imported as dependencies</summary>
+<pre>
+backcall            0.2.0
+cython_runtime      NA
+dateutil            2.8.1
+decorator           5.0.7
+ipykernel           5.5.3
+ipython_genutils    0.2.0
+jedi                0.18.0
+numpy               1.20.2
+parso               0.8.2
+pexpect             4.8.0
+pickleshare         0.7.5
+prompt_toolkit      3.0.18
+ptyprocess          0.7.0
+pygments            2.8.1
+pytz                2021.1
+six                 1.15.0
+storemagic          NA
+tornado             6.1
+traitlets           5.0.5
+wcwidth             0.2.5
+zmq                 22.0.3
+</pre>
+</details>
+<pre>
+-----
+IPython             7.23.0
+jupyter_client      6.1.12
+jupyter_core        4.7.1
+-----
+Python 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:46) [GCC 9.3.0]
+Linux-5.11.13-arch1-1-x86_64-with-glibc2.33
+-----
+Session information updated at 2021-05-06 09:59
+</pre>
+</details>
+
+If you prefer to show the session information without the HTML tags,
+you can use `session_info.show(html=False)` in the notebook
+to get the same output as in the first example above.
+
+`session_info` can also write the module dependencies
+to a `requirements.txt` file,
+which is compatible with `pip install -r /path/to/requirements.txt`.
+
+[View the docstring for complete parameter information](https://gitlab.com/joelostblom/session_info/-/blob/master/sinfo/main.py#L73-118).
 
 ## Background
 
-`sinfo` started as minor modifications of `py_session`, and as it grew it
-became convenient to create a new package. `sinfo` was built with the help of
+`session_info` started as minor modifications of `py_session`, and as it grew it
+became convenient to create a new package. `session_info` was built with the help of
 information provided in stackoverflow answers and existing similar packages,
 including
 
 - https://github.com/fbrundu/py_session
 - https://github.com/jrjohansson/version_information
+- https://github.com/rasbt/watermark
 - https://stackoverflow.com/a/4858123/2166823
 - https://stackoverflow.com/a/40690954/2166823
 - https://stackoverflow.com/a/52187331/2166823


=====================================
sinfo/__init__.py → session_info/__init__.py
=====================================
@@ -1,4 +1,4 @@
-from .main import sinfo
+from .main import show
 from ._version import get_versions
 
 


=====================================
sinfo/_version.py → session_info/_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."""
 
@@ -23,9 +23,9 @@ def get_keywords():
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (HEAD -> master, tag: 0.3.1, refs/keep-around/d7037becde4d587545c800b80ced85015962b588)"
-    git_full = "d7037becde4d587545c800b80ced85015962b588"
-    git_date = "2020-01-15 19:51:02 +0100"
+    git_refnames = "$Format:%d$"
+    git_full = "$Format:%H$"
+    git_date = "$Format:%ci$"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 
@@ -43,7 +43,7 @@ def get_config():
     cfg.style = "pep440"
     cfg.tag_prefix = ""
     cfg.parentdir_prefix = ""
-    cfg.versionfile_source = "sinfo/_version.py"
+    cfg.versionfile_source = "session_info/_version.py"
     cfg.verbose = False
     return cfg
 
@@ -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"]:


=====================================
sinfo/main.py → session_info/main.py
=====================================
@@ -1,6 +1,6 @@
 '''
-sinfo finds and prints version information for loaded modules in the current
-session, Python, and the OS.
+session_info finds and prints version information for loaded modules in the
+current session, Python, and the OS.
 '''
 
 import sys
@@ -39,13 +39,22 @@ def _find_version(mod_version_attr):
         joined_tuple = '.'.join([str(num) for num in mod_version_attr])
         return joined_tuple
     elif callable(mod_version_attr):
-        return mod_version_attr()
+        try:
+            return mod_version_attr()
+        # A module might have a function that does something else than return
+        # the version number altough it is named "version" or similar, e.g.
+        # https://gitlab.com/joelostblom/session_info/-/issues/8. In these cases it
+        # will likely fail to call without arguments, we're raising the same
+        # type of error as in the parent try/except clause to continue looking
+        # for more possible version strings.
+        except Exception:
+            raise AttributeError
     else:
         # print(f'Does not support module version of type {type(mod_ver_attr)}')
         return 'NA'
 
 
-# Straight from https://stackoverflow.com/a/52187331/2166823
+# From https://stackoverflow.com/a/52187331/2166823
 # Slight modifications added
 def _notebook_basename():
     """Returns the absolute path of the Notebook or None if it cannot be determined
@@ -70,51 +79,65 @@ def _notebook_basename():
     return None
 
 
-def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
-          std_lib=False, private=False, write_req_file=None, req_file_name=None,
-          html=False, excludes=['builtins', 'stdlib_list']):
+def _clean_modules(modules, private, excludes):
+    # Keep module basename only. Filter duplicates and excluded modules.
+    if private:
+        clean_modules = set(module.split('.')[0] for module in modules
+                            if module.split('.')[0] not in excludes)
+    else:  # Also filter private modules
+        clean_modules = set(module.split('.')[0] for module in modules
+                            if module.split('.')[0] not in excludes
+                            and not module.startswith('_'))
+    return clean_modules
+
+
+def show(na=True, os=True, cpu=False, jupyter=None, dependencies=None,
+         std_lib=False, private=False, write_req_file=False, req_file_name=None,
+         html=None, excludes=['builtins', 'stdlib_list']):
     '''
-    Output version information for loaded modules in the current session,
+    Show version information for loaded modules in the current session,
     Python, and the OS.
 
     Parameters
     ----------
     na : bool
-        Output module name even when no version number is found.
+        Show module name even when no version number is found.
     os : bool
-        Output OS information.
+        Show OS information.
     cpu : bool
-        Output number of logical CPU cores and info string (if available).
+        Show number of logical CPU cores and info string (if available).
     jupyter : bool
-        Output information about the jupyter environment. If `None`, output
+        Show information about the jupyter environment. If `None`, output
         jupyter info only if inside a Jupyter notebook.
     dependencies : bool
-        Output information about modules imported by the Python interpreter on
+        Show information about modules imported by the Python interpreter on
         startup and depency modules imported via other modules. If `None`,
         dependency modules will be included in the HTML output under a
         <details> tag, and excluded from the printed output. Setting `na` to
         `False` could be helpful to reduce verboseness.
     std_lib : bool
-        Output information for modules imported from the standard library.
+        Show information for modules imported from the standard library.
         Tries to detect the Python version to compare with the corresponding
         standard libarary, falls back to Python 3.7 if the version cannot be
         detected.
     private : bool
-        Output information for private modules.
+        Show information for private modules.
     write_req_file: bool
         Create a pip-compatible text file that lists all the module versions.
-        If `None`, write dependency files for Jupyter notebooks only. Tries to
-        find the notebook name to prefix the requirments file, falls back to
-        `sinfo-requirements.txt`. Only writes explicitly imported modules.
+        If `None`, write dependency files for Jupyter notebooks only. If the
+        `notebook` module is installed, `session_info` can automatically find the
+        notebook name use it as a prefix for the requirments file. Otherwise
+        it falls back to `session_info-requirements.txt`.
+        This only writes explicitly imported modules.
     req_file_name : str
         Change the name of the requirements file.
     html: bool
-        Format output as HTML and collapse it in a <details> tag. If `None`,
+        Format the output as HTML and collapse it in a <details> tag. If `None`,
         HTML will be used only if a Jupyter notebook environment is detected.
         Note that this will not be visible in notebooks shared on GitHub since
         they seemingly do not support the <details> tag. Requires IPython.
     excludes : list
-        Do not output version information for these modules.
+        Do not show version information for these modules.
     '''
     # Exclude std lib packages
     if not std_lib:
@@ -153,27 +176,22 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
     caller_globals = dict(
         inspect.getmembers(inspect.stack()[1][0]))["f_globals"]
     # Find imported modules in the global namespace
-    imported_modules = set(_imports(caller_globals.items()))
+    imported_modules = _clean_modules(set(_imports(caller_globals.items())), private, excludes)
     # Wether to include dependency module not explicitly imported
     all_modules = {'imported': imported_modules}
     if dependencies is not False:  # Default with HTML is to include deps
         if html or dependencies:
             dependencies = True  # HTML default, used later for output strings
-            sys_modules = set(sys.modules.keys())
+            sys_modules = _clean_modules(set(sys.modules.keys()), private, excludes)
             depend_modules = sys_modules.difference(imported_modules)
-            all_modules['depend'] = depend_modules
+            if depend_modules:
+                all_modules['depend'] = depend_modules
+            else:
+                dependencies = False
 
     output_modules = {}
     for mod_type in all_modules:
-        modules = all_modules[mod_type]
-        # Keep module basename only. Filter duplicates and excluded modules.
-        if private:
-            clean_modules = set(module.split('.')[0] for module in modules
-                                if module.split('.')[0] not in excludes)
-        else:  # Also filter private modules
-            clean_modules = set(module.split('.')[0] for module in modules
-                                if module.split('.')[0] not in excludes
-                                and not module.startswith('_'))
+        clean_modules = all_modules[mod_type]
 
         # Don't duplicate jupyter module output
         if jupyter or in_notebook:
@@ -214,15 +232,20 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
     # Write requirements file for notebooks only by default
     if write_req_file or (write_req_file is None and in_notebook):
         if req_file_name is None:
-            # Only import notebook librarie if we are in the notebook
+            # Only import notebook libraries if we are in the notebook
             # Otherwise, running this multiple times would set `in_notebook=True`
             if in_notebook:
                 try:
                     req_file_name = f'{_notebook_basename()}-requirements.txt'
-                except:  # Fallback if the notebook name cannot be found
-                    req_file_name = 'sinfo-requirements.txt'
+                # If the notebook name cannot be found for, we want to fall
+                # back to the default name. Usually this happens because the
+                # notebook module is not found, but this is already mentioned
+                # in the docstring so we're not differentiating between that
+                # and other exceptions here.
+                except Exception:
+                    req_file_name = 'session_info-requirements.txt'
             else:
-                req_file_name = 'sinfo-requirements.txt'
+                req_file_name = 'session_info-requirements.txt'
 
         # For NA modules, just include the latest, so no version number.
         mods_na_removed = [mod_ver.replace('\tNA', '')
@@ -239,14 +262,14 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
 
     # Sys info
     sys_output = 'Python ' + sys.version.replace('\n', '')
-    os_output = platform.platform() if os else None
+    os_output = platform.platform() if os else ''
     if cpu:
         if platform.processor() != '':
             cpu_output = f'{cpu_count()} logical CPU cores, {platform.processor()}'
         else:
             cpu_output = f'{cpu_count()} logical CPU cores'
     else:
-        cpu_output = None
+        cpu_output = ''
     date_output = 'Session information updated at {}'.format(
         datetime.now().strftime('%Y-%m-%d %H:%M'))
 
@@ -264,7 +287,7 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
             -----
             </pre>
             <details>
-            <summary>Click to view dependency modules</summary>
+            <summary>Click to view modules imported as dependencies</summary>
             <pre>
             {output_modules['depend']}
             </pre>
@@ -274,7 +297,7 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
             output_depend_str = ''
         return HTML(cleandoc(f"""
             <details>
-            <summary>Click to view module versions</summary>
+            <summary>Click to view session information</summary>
             <pre>
             -----
             {output_modules['imported']}{output_depend_str}{output_jup_str}
@@ -285,7 +308,7 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
             -----
             {date_output}
             </pre>
-            </details>"""))
+            </details>""").replace('\n\n', '\n'))  # Clean empty output fields
     else:
         if dependencies:
             # Must be dedented to line up with the returned HTML.
@@ -303,4 +326,4 @@ def sinfo(na=True, os=True, cpu=True, jupyter=None, dependencies=None,
             {os_output}
             {cpu_output}
             -----
-            {date_output}"""))
+            {date_output}""").replace('\n\n', '\n'))  # Clean empty output fields


=====================================
setup.cfg
=====================================
@@ -1,7 +1,7 @@
 [versioneer]
 VCS = git
 style = pep440
-versionfile_source = sinfo/_version.py
-versionfile_build = sinfo/_version.py
+versionfile_source = session_info/_version.py
+versionfile_build = session_info/_version.py
 tag_prefix =
 parentdir_prefix =


=====================================
setup.py
=====================================
@@ -9,8 +9,8 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
     long_description = f.read()
 
 setup(
-    name='sinfo',
-    url='https://gitlab.com/joelostblom/sinfo',
+    name='session_info',
+    url='https://gitlab.com/joelostblom/session_info',
     author='Joel Ostblom',
     author_email='joel.ostblom at protonmail.com',
     packages=find_packages(),
@@ -20,9 +20,7 @@ setup(
     version=versioneer.get_version(),
     cmdclass=versioneer.get_cmdclass(),
     license='BSD-3',
-    description='''
-        sinfo outputs version information for modules loaded in the current
-        session, Python, and the OS.''',
+    description='session_info outputs version information for modules loaded in the current session, Python, and the OS.',
     # Include readme in markdown format, GFM markdown style by default
     long_description=open('README.md').read(),
     long_description_content_type='text/markdown'


=====================================
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)



View it on GitLab: https://salsa.debian.org/python-team/packages/python-sinfo/-/commit/e13cb9bd1118ddf573c699f8b2ed10babf1a4f1d

-- 
View it on GitLab: https://salsa.debian.org/python-team/packages/python-sinfo/-/commit/e13cb9bd1118ddf573c699f8b2ed10babf1a4f1d
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20230112/1fd92193/attachment-0001.htm>


More information about the debian-med-commit mailing list