Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-s3fs for openSUSE:Factory checked in at 2022-04-28 23:07:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-s3fs (Old) and /work/SRC/openSUSE:Factory/.python-s3fs.new.1538 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-s3fs" Thu Apr 28 23:07:46 2022 rev:13 rq:973235 version:2022.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-s3fs/python-s3fs.changes 2022-02-24 18:24:05.870648407 +0100 +++ /work/SRC/openSUSE:Factory/.python-s3fs.new.1538/python-s3fs.changes 2022-04-28 23:07:48.936677529 +0200 @@ -1,0 +2,10 @@ +Mon Apr 4 09:01:45 UTC 2022 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 2022.3.0 + * pre-commit (#612) + * aiobotocore 2.2 (#609) + * empty ETag (#605) + * HTTPClientError retry (#597) + * new callbacks support (#590) + +------------------------------------------------------------------- Old: ---- s3fs-2022.2.0.tar.gz New: ---- s3fs-2022.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-s3fs.spec ++++++ --- /var/tmp/diff_new_pack.wYen9T/_old 2022-04-28 23:07:49.432678069 +0200 +++ /var/tmp/diff_new_pack.wYen9T/_new 2022-04-28 23:07:49.432678069 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python3-%{**}} %define skip_python2 1 Name: python-s3fs -Version: 2022.2.0 +Version: 2022.3.0 Release: 0 Summary: Python filesystem interface for S3 License: BSD-3-Clause ++++++ s3fs-2022.2.0.tar.gz -> s3fs-2022.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/.coveragerc new/s3fs-2022.3.0/.coveragerc --- old/s3fs-2022.2.0/.coveragerc 2020-05-01 18:06:15.000000000 +0200 +++ new/s3fs-2022.3.0/.coveragerc 2022-03-29 19:28:02.000000000 +0200 @@ -1,5 +1,5 @@ [run] -include = +include = s3fs/* omit = @@ -10,4 +10,3 @@ [html] directory = coverage_html_report - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/PKG-INFO new/s3fs-2022.3.0/PKG-INFO --- old/s3fs-2022.2.0/PKG-INFO 2022-02-22 18:52:20.695571000 +0100 +++ new/s3fs-2022.3.0/PKG-INFO 2022-03-31 20:01:37.321205100 +0200 @@ -1,30 +1,11 @@ Metadata-Version: 2.1 Name: s3fs -Version: 2022.2.0 +Version: 2022.3.0 Summary: Convenient Filesystem interface over S3 Home-page: http://github.com/fsspec/s3fs/ Maintainer: Martin Durant Maintainer-email: mdur...@continuum.io License: BSD -Description: s3fs - ==== - - |Build Status| |Doc Status| - - S3FS builds on aiobotocore_ to provide a convenient Python filesystem interface for S3. - - View the documentation_ for s3fs. - - .. _documentation: http://s3fs.readthedocs.io/en/latest/ - .. _aiobotocore: https://aiobotocore.readthedocs.io/en/latest/ - - .. |Build Status| image:: https://github.com/fsspec/s3fs/workflows/CI/badge.svg - :target: https://github.com/fsspec/s3fs/actions - :alt: Build Status - .. |Doc Status| image:: https://readthedocs.org/projects/s3fs/badge/?version=latest - :target: https://s3fs.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - Keywords: s3,boto Platform: UNKNOWN Classifier: Development Status :: 4 - Beta @@ -37,3 +18,25 @@ Requires-Python: >= 3.7 Provides-Extra: awscli Provides-Extra: boto3 +License-File: LICENSE.txt + +s3fs +==== + +|Build Status| |Doc Status| + +S3FS builds on aiobotocore_ to provide a convenient Python filesystem interface for S3. + +View the documentation_ for s3fs. + +.. _documentation: http://s3fs.readthedocs.io/en/latest/ +.. _aiobotocore: https://aiobotocore.readthedocs.io/en/latest/ + +.. |Build Status| image:: https://github.com/fsspec/s3fs/workflows/CI/badge.svg + :target: https://github.com/fsspec/s3fs/actions + :alt: Build Status +.. |Doc Status| image:: https://readthedocs.org/projects/s3fs/badge/?version=latest + :target: https://s3fs.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/docs/source/changelog.rst new/s3fs-2022.3.0/docs/source/changelog.rst --- old/s3fs-2022.2.0/docs/source/changelog.rst 2022-02-22 18:50:58.000000000 +0100 +++ new/s3fs-2022.3.0/docs/source/changelog.rst 2022-03-31 20:00:49.000000000 +0200 @@ -1,6 +1,15 @@ Changelog ========= +2022.3.0 +-------- + +- pre-commit (#612) +- aiobotocore 2.2 (#609) +- empty ETag (#605) +- HTTPClientError retry (#597) +- new callbacks support (#590) + 2022.02.0 --------- @@ -119,7 +128,7 @@ - Always use multipart uploads when not autocommitting (:pr:`243`) by `Marius van Niekerk`_ - Create ``CONTRIBUTING.md`` (:pr:`248`) by `Jacob Tomlinson`_ - Use autofunction for ``S3Map`` sphinx autosummary (:pr:`251`) by `James Bourbeau`_ -- Miscellaneous doc updates (:pr:`252`) by `James Bourbeau`_ +- Miscellaneous doc updates (:pr:`252`) by `James Bourbeau`_ - Support for Python 3.8 (:pr:`264`) by `Tom Augspurger`_ - Improved performance for ``isdir`` (:pr:`259`) by `Nate Yoder`_ * Increased the minimum required version of fsspec to 0.6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/docs/source/development.rst new/s3fs-2022.3.0/docs/source/development.rst --- old/s3fs-2022.2.0/docs/source/development.rst 2022-02-08 22:42:09.000000000 +0100 +++ new/s3fs-2022.3.0/docs/source/development.rst 2022-03-29 19:28:02.000000000 +0200 @@ -7,4 +7,4 @@ Run tests:: - $ pytest \ No newline at end of file + $ pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/docs/source/index.rst new/s3fs-2022.3.0/docs/source/index.rst --- old/s3fs-2022.2.0/docs/source/index.rst 2021-12-28 21:02:35.000000000 +0100 +++ new/s3fs-2022.3.0/docs/source/index.rst 2022-03-29 19:28:02.000000000 +0200 @@ -114,6 +114,18 @@ works, but you might find the implementation interesting. +Multiprocessing +--------------- + +When using Python's `multiprocessing`, the start method must be set to either +``spawn`` or ``forkserver``. ``fork`` is not safe to use because of the open sockets +and async thread used by s3fs, and may lead to +hard-to-find bugs and occasional deadlocks. Read more about the available +`start methods`. + +.. _multiprocessing: https://docs.python.org/3/library/multiprocessing.html +.. _start methods: https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods + Limitations ----------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/requirements.txt new/s3fs-2022.3.0/requirements.txt --- old/s3fs-2022.2.0/requirements.txt 2022-02-22 18:51:22.000000000 +0100 +++ new/s3fs-2022.3.0/requirements.txt 2022-03-31 20:00:49.000000000 +0200 @@ -1,3 +1,3 @@ -aiobotocore~=2.1.0 -fsspec==2022.02.0 +aiobotocore~=2.2.0 +fsspec==2022.3.0 aiohttp<=4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs/_version.py new/s3fs-2022.3.0/s3fs/_version.py --- old/s3fs-2022.2.0/s3fs/_version.py 2022-02-22 18:52:20.696371300 +0100 +++ new/s3fs-2022.3.0/s3fs/_version.py 2022-03-31 20:01:37.322401800 +0200 @@ -8,11 +8,11 @@ version_json = ''' { - "date": "2022-02-22T12:51:44-0500", + "date": "2022-03-31T14:00:38-0400", "dirty": false, "error": null, - "full-revisionid": "50bafe4d8766c3b2a4e1fc09669cf02fb2d71454", - "version": "2022.02.0" + "full-revisionid": "c4fb41f7cc2f2aede6bbb7755096c38b9e4cc553", + "version": "2022.3.0" } ''' # END VERSION_JSON diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs/core.py new/s3fs-2022.3.0/s3fs/core.py --- old/s3fs-2022.2.0/s3fs/core.py 2022-02-08 22:42:09.000000000 +0100 +++ new/s3fs-2022.3.0/s3fs/core.py 2022-03-29 19:28:02.000000000 +0200 @@ -19,7 +19,7 @@ import botocore import aiobotocore.session from aiobotocore.config import AioConfig -from botocore.exceptions import ClientError, ParamValidationError +from botocore.exceptions import ClientError, HTTPClientError, ParamValidationError from s3fs.errors import translate_boto_error from s3fs.utils import S3BucketRegionCache, ParamKwargsHelper, _get_brange, FileExpired @@ -46,7 +46,7 @@ MANAGED_COPY_THRESHOLD = 5 * 2**30 -S3_RETRYABLE_ERRORS = (socket.timeout, IncompleteRead) +S3_RETRYABLE_ERRORS = (socket.timeout, HTTPClientError, IncompleteRead) if ClientPayloadError is not None: S3_RETRYABLE_ERRORS += (ClientPayloadError,) @@ -1071,7 +1071,7 @@ **self.req_kw, ) return { - "ETag": out["ETag"], + "ETag": out.get("ETag", ""), "LastModified": out["LastModified"], "size": out["ContentLength"], "name": "/".join([bucket, key]), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs/errors.py new/s3fs-2022.3.0/s3fs/errors.py --- old/s3fs-2022.2.0/s3fs/errors.py 2021-03-17 15:40:53.000000000 +0100 +++ new/s3fs-2022.3.0/s3fs/errors.py 2022-03-29 19:28:02.000000000 +0200 @@ -136,14 +136,15 @@ An instantiated exception ready to be thrown. If the error code isn't recognized, an IOError with the original error message is returned. """ - if not hasattr(error, "response"): - # non-http error: + error_response = getattr(error, "response", None) + if error_response is None: + # non-http error, or response is None: return error - code = error.response["Error"].get("Code") + code = error_response["Error"].get("Code") constructor = ERROR_CODE_TO_EXCEPTION.get(code) if constructor: if not message: - message = error.response["Error"].get("Message", str(error)) + message = error_response["Error"].get("Message", str(error)) custom_exc = constructor(message, *args, **kwargs) else: # No match found, wrap this in an IOError with the appropriate message. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs/tests/test_s3fs.py new/s3fs-2022.3.0/s3fs/tests/test_s3fs.py --- old/s3fs-2022.2.0/s3fs/tests/test_s3fs.py 2022-02-22 18:51:29.000000000 +0100 +++ new/s3fs-2022.3.0/s3fs/tests/test_s3fs.py 2022-03-29 20:00:43.000000000 +0200 @@ -2274,6 +2274,25 @@ assert d in s3.ls(test_bucket_name) +def test_rm_recursive_folder(s3): + s3.touch(test_bucket_name + "/sub/file") + s3.rm(test_bucket_name + "/sub", recursive=True) + assert not s3.exists(test_bucket_name + "/sub/file") + assert not s3.exists(test_bucket_name + "/sub") + + s3.touch(test_bucket_name + "/sub/file") + s3.touch(test_bucket_name + "/sub/") # placeholder + s3.rm(test_bucket_name + "/sub", recursive=True) + assert not s3.exists(test_bucket_name + "/sub/file") + assert not s3.exists(test_bucket_name + "/sub") + + s3.touch(test_bucket_name + "/sub/file") + s3.rm(test_bucket_name, recursive=True) + assert not s3.exists(test_bucket_name + "/sub/file") + assert not s3.exists(test_bucket_name + "/sub") + assert not s3.exists(test_bucket_name) + + def test_copy_file_without_etag(s3, monkeypatch): s3.touch(test_bucket_name + "/copy_tests/file") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs.egg-info/PKG-INFO new/s3fs-2022.3.0/s3fs.egg-info/PKG-INFO --- old/s3fs-2022.2.0/s3fs.egg-info/PKG-INFO 2022-02-22 18:52:20.000000000 +0100 +++ new/s3fs-2022.3.0/s3fs.egg-info/PKG-INFO 2022-03-31 20:01:36.000000000 +0200 @@ -1,30 +1,11 @@ Metadata-Version: 2.1 Name: s3fs -Version: 2022.2.0 +Version: 2022.3.0 Summary: Convenient Filesystem interface over S3 Home-page: http://github.com/fsspec/s3fs/ Maintainer: Martin Durant Maintainer-email: mdur...@continuum.io License: BSD -Description: s3fs - ==== - - |Build Status| |Doc Status| - - S3FS builds on aiobotocore_ to provide a convenient Python filesystem interface for S3. - - View the documentation_ for s3fs. - - .. _documentation: http://s3fs.readthedocs.io/en/latest/ - .. _aiobotocore: https://aiobotocore.readthedocs.io/en/latest/ - - .. |Build Status| image:: https://github.com/fsspec/s3fs/workflows/CI/badge.svg - :target: https://github.com/fsspec/s3fs/actions - :alt: Build Status - .. |Doc Status| image:: https://readthedocs.org/projects/s3fs/badge/?version=latest - :target: https://s3fs.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - Keywords: s3,boto Platform: UNKNOWN Classifier: Development Status :: 4 - Beta @@ -37,3 +18,25 @@ Requires-Python: >= 3.7 Provides-Extra: awscli Provides-Extra: boto3 +License-File: LICENSE.txt + +s3fs +==== + +|Build Status| |Doc Status| + +S3FS builds on aiobotocore_ to provide a convenient Python filesystem interface for S3. + +View the documentation_ for s3fs. + +.. _documentation: http://s3fs.readthedocs.io/en/latest/ +.. _aiobotocore: https://aiobotocore.readthedocs.io/en/latest/ + +.. |Build Status| image:: https://github.com/fsspec/s3fs/workflows/CI/badge.svg + :target: https://github.com/fsspec/s3fs/actions + :alt: Build Status +.. |Doc Status| image:: https://readthedocs.org/projects/s3fs/badge/?version=latest + :target: https://s3fs.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/s3fs.egg-info/requires.txt new/s3fs-2022.3.0/s3fs.egg-info/requires.txt --- old/s3fs-2022.2.0/s3fs.egg-info/requires.txt 2022-02-22 18:52:20.000000000 +0100 +++ new/s3fs-2022.3.0/s3fs.egg-info/requires.txt 2022-03-31 20:01:36.000000000 +0200 @@ -1,9 +1,9 @@ -aiobotocore~=2.1.0 -fsspec==2022.02.0 +aiobotocore~=2.2.0 +fsspec==2022.3.0 aiohttp<=4 [awscli] -aiobotocore[awscli]~=2.1.0 +aiobotocore[awscli]~=2.2.0 [boto3] -aiobotocore[boto3]~=2.1.0 +aiobotocore[boto3]~=2.2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/setup.cfg new/s3fs-2022.3.0/setup.cfg --- old/s3fs-2022.2.0/setup.cfg 2022-02-22 18:52:20.696058800 +0100 +++ new/s3fs-2022.3.0/setup.cfg 2022-03-31 20:01:37.321910900 +0200 @@ -2,7 +2,7 @@ long_description = file: README.rst [versioneer] -vcs = git +VCS = git style = pep440 versionfile_source = s3fs/_version.py versionfile_build = s3fs/_version.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/setup.py new/s3fs-2022.3.0/setup.py --- old/s3fs-2022.2.0/setup.py 2022-02-08 22:42:09.000000000 +0100 +++ new/s3fs-2022.3.0/setup.py 2022-03-29 19:28:02.000000000 +0200 @@ -3,37 +3,39 @@ from setuptools import setup import versioneer -with open('requirements.txt') as file: - aiobotocore_version_suffix = '' +with open("requirements.txt") as file: + aiobotocore_version_suffix = "" for line in file: - parts = line.rstrip().split('aiobotocore') + parts = line.rstrip().split("aiobotocore") if len(parts) == 2: aiobotocore_version_suffix = parts[1] break -setup(name='s3fs', - version=versioneer.get_version(), - cmdclass=versioneer.get_cmdclass(), - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - ], - description='Convenient Filesystem interface over S3', - url='http://github.com/fsspec/s3fs/', - maintainer='Martin Durant', - maintainer_email='mdur...@continuum.io', - license='BSD', - keywords='s3, boto', - packages=['s3fs'], - python_requires='>= 3.7', - install_requires=[open('requirements.txt').read().strip().split('\n')], - extras_require={ - 'awscli': [f"aiobotocore[awscli]{aiobotocore_version_suffix}"], - 'boto3': [f"aiobotocore[boto3]{aiobotocore_version_suffix}"], - }, - zip_safe=False) +setup( + name="s3fs", + version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), + classifiers=[ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + ], + description="Convenient Filesystem interface over S3", + url="http://github.com/fsspec/s3fs/", + maintainer="Martin Durant", + maintainer_email="mdur...@continuum.io", + license="BSD", + keywords="s3, boto", + packages=["s3fs"], + python_requires=">= 3.7", + install_requires=[open("requirements.txt").read().strip().split("\n")], + extras_require={ + "awscli": [f"aiobotocore[awscli]{aiobotocore_version_suffix}"], + "boto3": [f"aiobotocore[boto3]{aiobotocore_version_suffix}"], + }, + zip_safe=False, +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3fs-2022.2.0/versioneer.py new/s3fs-2022.3.0/versioneer.py --- old/s3fs-2022.2.0/versioneer.py 2021-12-13 21:26:38.000000000 +0100 +++ new/s3fs-2022.3.0/versioneer.py 2022-03-29 19:28:02.000000000 +0200 @@ -1,4 +1,3 @@ - # Version: 0.20 """The Versioneer - like a rocketeer, but for versions. @@ -303,11 +302,13 @@ setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - err = ("Versioneer was unable to run the project root directory. " - "Versioneer requires setup.py to be executed from " - "its immediate directory (like 'python setup.py COMMAND'), " - "or in a way that lets it use sys.argv[0] to find the root " - "(like 'python path/to/setup.py COMMAND').") + err = ( + "Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND')." + ) raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools @@ -320,8 +321,10 @@ me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir: - print("Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(my_path), versioneer_py)) + print( + "Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py) + ) except NameError: pass return root @@ -367,16 +370,17 @@ def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f): """Store f in HANDLERS[vcs][method].""" HANDLERS.setdefault(vcs, {})[method] = f return f + return decorate # pylint:disable=too-many-arguments,consider-using-with # noqa -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, - env=None): +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None @@ -384,10 +388,13 @@ try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - process = subprocess.Popen([command] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None)) + process = subprocess.Popen( + [command] + args, + cwd=cwd, + env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr else None), + ) break except EnvironmentError: e = sys.exc_info()[1] @@ -410,7 +417,9 @@ return stdout, process.returncode -LONG_VERSION_PY['git'] = r''' +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 @@ -1091,7 +1100,7 @@ # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -1100,7 +1109,7 @@ # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "main". - tags = {r for r in refs if re.search(r'\d', r)} + tags = {r for r in refs if re.search(r"\d", r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -1108,24 +1117,31 @@ for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] + r = ref[len(tag_prefix) :] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') - if not re.match(r'\d', r): + if not re.match(r"\d", r): continue if verbose: print("picking %s" % r) - return {"version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": None, - "date": date} + return { + "version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": None, + "date": date, + } # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") - return {"version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": "no suitable tags", "date": None} + return { + "version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": "no suitable tags", + "date": None, + } @register_vcs_handler("git", "pieces_from_vcs") @@ -1140,8 +1156,7 @@ if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=True) + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -1149,10 +1164,19 @@ # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty", - "--always", "--long", - "--match", "%s*" % tag_prefix], - cwd=root) + describe_out, rc = runner( + GITS, + [ + "describe", + "--tags", + "--dirty", + "--always", + "--long", + "--match", + "%s*" % tag_prefix, + ], + cwd=root, + ) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") @@ -1167,8 +1191,7 @@ pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None - branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], - cwd=root) + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") @@ -1208,17 +1231,16 @@ dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: - git_describe = git_describe[:git_describe.rindex("-dirty")] + git_describe = git_describe[: git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX - mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? - pieces["error"] = ("unable to parse git-describe output: '%s'" - % describe_out) + pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag @@ -1227,10 +1249,12 @@ if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" - % (full_tag, tag_prefix)) + pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( + full_tag, + tag_prefix, + ) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix):] + pieces["closest-tag"] = full_tag[len(tag_prefix) :] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) @@ -1303,15 +1327,21 @@ for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): - return {"version": dirname[len(parentdir_prefix):], - "full-revisionid": None, - "dirty": False, "error": None, "date": None} + return { + "version": dirname[len(parentdir_prefix) :], + "full-revisionid": None, + "dirty": False, + "error": None, + "date": None, + } rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: - print("Tried directories %s but none started with prefix %s" % - (str(rootdirs), parentdir_prefix)) + print( + "Tried directories %s but none started with prefix %s" + % (str(rootdirs), parentdir_prefix) + ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -1340,11 +1370,13 @@ contents = f.read() except EnvironmentError: raise NotThisMethod("unable to read _version.py") - mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", - contents, re.M | re.S) + mo = re.search( + r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) if not mo: - mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", - contents, re.M | re.S) + mo = re.search( + r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) @@ -1353,8 +1385,7 @@ def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) - contents = json.dumps(versions, sort_keys=True, - indent=1, separators=(",", ": ")) + contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) @@ -1386,8 +1417,7 @@ rendered += ".dirty" else: # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) + rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1416,8 +1446,7 @@ rendered = "0" if pieces["branch"] != "main": rendered += ".dev0" - rendered += "+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) + rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1560,11 +1589,13 @@ def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: - return {"version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None} + return { + "version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None, + } if not style or style == "default": style = "pep440" # the default @@ -1588,9 +1619,13 @@ else: raise ValueError("unknown style '%s'" % style) - return {"version": rendered, "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], "error": None, - "date": pieces.get("date")} + return { + "version": rendered, + "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], + "error": None, + "date": pieces.get("date"), + } class VersioneerBadRootError(Exception): @@ -1613,8 +1648,9 @@ handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose - assert cfg.versionfile_source is not None, \ - "please set versioneer.versionfile_source" + assert ( + cfg.versionfile_source is not None + ), "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) @@ -1668,9 +1704,13 @@ if verbose: print("unable to compute version") - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, "error": "unable to compute version", - "date": None} + return { + "version": "0+unknown", + "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", + "date": None, + } def get_version(): @@ -1723,6 +1763,7 @@ print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version # we override "build_py" in both distutils and setuptools @@ -1741,8 +1782,8 @@ # setup.py egg_info -> ? # we override different "build_py" commands for both environments - if 'build_py' in cmds: - _build_py = cmds['build_py'] + 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: @@ -1757,14 +1798,14 @@ # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: - target_versionfile = os.path.join(self.build_lib, - cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py - if 'build_ext' in cmds: - _build_ext = cmds['build_ext'] + if "build_ext" in cmds: + _build_ext = cmds["build_ext"] elif "setuptools" in sys.modules: from setuptools.command.build_ext import build_ext as _build_ext else: @@ -1784,14 +1825,15 @@ 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_build) + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) 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 # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ @@ -1812,17 +1854,21 @@ os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % - {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + cmds["build_exe"] = cmd_build_exe del cmds["build_py"] - if 'py2exe' in sys.modules: # py2exe enabled? + if "py2exe" in sys.modules: # py2exe enabled? from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): @@ -1838,18 +1884,22 @@ os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % - {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + cmds["py2exe"] = cmd_py2exe # we override different "sdist" commands for both environments - if 'sdist' in cmds: - _sdist = cmds['sdist'] + if "sdist" in cmds: + _sdist = cmds["sdist"] elif "setuptools" in sys.modules: from setuptools.command.sdist import sdist as _sdist else: @@ -1874,8 +1924,10 @@ # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) - write_to_version_file(target_versionfile, - self._versioneer_generated_versions) + write_to_version_file( + target_versionfile, self._versioneer_generated_versions + ) + cmds["sdist"] = cmd_sdist return cmds @@ -1935,11 +1987,13 @@ root = get_root() try: cfg = get_config_from_root(root) - except (EnvironmentError, configparser.NoSectionError, - configparser.NoOptionError) as e: + except ( + EnvironmentError, + configparser.NoSectionError, + configparser.NoOptionError, + ) as e: if isinstance(e, (EnvironmentError, configparser.NoSectionError)): - print("Adding sample versioneer config to setup.cfg", - file=sys.stderr) + print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) @@ -1948,15 +2002,18 @@ print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) - ipy = os.path.join(os.path.dirname(cfg.versionfile_source), - "__init__.py") + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: @@ -2004,8 +2061,10 @@ else: print(" 'versioneer.py' already in MANIFEST.in") if cfg.versionfile_source not in simple_includes: - print(" appending versionfile_source ('%s') to MANIFEST.in" % - cfg.versionfile_source) + print( + " appending versionfile_source ('%s') to MANIFEST.in" + % cfg.versionfile_source + ) with open(manifest_in, "a") as f: f.write("include %s\n" % cfg.versionfile_source) else: