Projects
openEuler:Mainline
python-setuptools_scm
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
_service:tar_scm:python-setuptools_scm.spec
Changed
@@ -1,12 +1,13 @@ %global _empty_manifest_terminate_build 0 Name: python-setuptools_scm -Version: 6.0.0 +Version: 6.4.2 Release: 1 Summary: Manage your Python package versions in SCM metadata License: MIT URL: https://pypi.python.org/pypi/setuptools_scm/ -Source0: https://files.pythonhosted.org/packages/bf/b1/e647ab0ad77ad74fde7f088cfa796b6b8ff24d4e2d4fa5a0d924fdbd9c6b/setuptools_scm-6.0.0.tar.gz +Source0: https://files.pythonhosted.org/packages/4a/18/477d3d9eb2f88230ff2a41de9d8ffa3554b706352787d289f57f76bfba0b/setuptools_scm-6.4.2.tar.gz +BuildRequires: python3-tomli python3-packaging BuildArch: noarch Requires: python3-setuptool Requires: python3-toml @@ -70,11 +71,15 @@ %files -n python3-setuptools_scm -f filelist.lst %dir %{python3_sitelib}/* +%{python3_sitelib}/setuptools_scm %files help -f doclist.lst %{_pkgdocdir} %changelog +* Sun Apr 23 2023 caodongxia <caodongxia@h-partners.com> - 6.4.2-1 +- Update to 6.4.2 + * Thu Jun 16 2022 OpenStack_SIG <openstack@openeuler.org> - 6.0.0-1 - Upgrade version for openstack yoga
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="scm">git</param> <param name="url">git@gitee.com:src-openeuler/python-setuptools_scm.git</param> - <param name="revision">a0a7f860f9a33c31a0ec8e4f7990e7afce043d9a</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.github
Deleted
-(directory)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.github/FUNDING.yml
Deleted
@@ -1,1 +0,0 @@ -tidelift: pypi/setuptools-scm
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.github/workflows
Deleted
-(directory)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.github/workflows/pre-commit.yml
Deleted
@@ -1,20 +0,0 @@ -name: pre-commit - -on: - pull_request: - push: - branches: master - -jobs: - pre-commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-python@v2 - - name: set PY - run: echo "PY=$(python --version --version | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - uses: actions/cache@v1 - with: - path: ~/.cache/pre-commit - key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} - - uses: pre-commit/action@v1.0.0
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.github/workflows/python-tests.yml
Deleted
@@ -1,122 +0,0 @@ -name: python tests+artifacts+release - -on: - pull_request: - push: - branches: - - main - tags: - - "v*" - release: - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python_version: '3.6', '3.7', '3.8', '3.9', 'pypy3' - os: windows-latest, ubuntu-latest #, macos-latest - include: - - os: windows-latest - python_version: 'msys2' - - name: ${{ matrix.os }} - Python ${{ matrix.python_version }} - steps: - - uses: actions/checkout@v1 - - name: Setup python - uses: actions/setup-python@v2 - if: matrix.python_version != 'msys2' - with: - python-version: ${{ matrix.python_version }} - architecture: x64 - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 - if: matrix.python_version == 'msys2' - with: - msystem: MINGW64 - install: git mingw-w64-x86_64-python mingw-w64-x86_64-python-setuptools - update: true - - run: pip install -U setuptools - if: matrix.python_version != 'msys2' - - run: pip install -e .toml pytest - - run: pytest - - check_selfinstall: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python_version: '3.6', '3.9', 'pypy3' - installer: "pip install", easy_install - name: check self install - Python ${{ matrix.python_version }} via ${{ matrix.installer }} - steps: - - uses: actions/checkout@v1 - - name: Setup python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python_version }} - architecture: x64 - # self install testing needs some clarity - # so its being executed without any other tools running - # setuptools smaller 52 is needed too di easy_install - - run: pip install -U "setuptools<52" - - run: python setup.py egg_info - - run: python setup.py sdist - - run: ${{ matrix.installer }} dist/* - - run: python testing/check_self_install.py - - - dist: - runs-on: ubuntu-latest - - needs: test - name: Python bdist/wheel - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-python@v2 - with: - python-version: "3.8" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install --upgrade wheel setuptools build - - - name: Build package - run: python -m build -s -w -o dist/ - - uses: actions/upload-artifact@v2 - with: - name: dist - path: dist - - - dist_check: - runs-on: ubuntu-latest - needs: dist - steps: - - uses: actions/setup-python@v2 - with: - python-version: "3.8" - - name: Install dependencies - run: pip install twine - - uses: actions/download-artifact@v2 - with: - name: dist - path: dist - - run: twine check dist/* - - dist_upload: - - runs-on: ubuntu-latest - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - needs: dist_check - steps: - - uses: actions/download-artifact@v2 - with: - name: dist - path: dist - - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@master - with: - user: __token__ - password: ${{ secrets.pypi_token }}
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/.gitignore
Deleted
@@ -1,49 +0,0 @@ -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion - -*.iml - -## Directory-based project format: -.idea/ - -### Other editors -.*.swp - - -### Python template -# Byte-compiled / optimized -__pycache__/ -*.pycod -*$py.class - - -# Distribution / packaging -.env/ -env/ -.venv/ -venv/ -build/ -dist/ -.eggs/ -lib/ -lib64/ -*.egg-info/ - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt -pip-wheel-metadata - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -.pytest_cache -nosetests.xml -coverage.xml -*,cover - -# Sphinx documentation -docs/_build/
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/CHANGELOG.rst -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/CHANGELOG.rst
Changed
@@ -1,3 +1,99 @@ +v6.4.2 +====== + +* fix #671 : NoReturn is not avaliable in painfully dead python 3.6 + + +v6.4.1 +======= + + +* fix regression #669: restore get_version signature +* fix #668: harden the selftest for distribution extras + +6.4.0 +====== + +* compatibility adjustments for setuptools >58 +* only put minimal setuptools version into toml extra to warn people with old strict pins +* coorectly handle hg-git self-use +* better mercurial detection +* modernize packaging setup +* python 3.10 support +* better handling of setuptools install command deprecation +* consider ``pyproject.tomls`` when running as command +* use list in git describe command to avoid shell expansions while supporting both windows and posix +* add ``--strip-dev`` flag to ``python -m setuptools_scm`` to print the next guessed version cleanly +* ensure no-guess-dev will fail on bad tags instead of generating invalid versions +* ensure we use utc everywhere to avoid confusion + +6.3.2 +===== + +* fix #629: correctly convert Version data in tags_to_version parser to avoid errors + +6.3.1 +===== + +* fix #625: restore tomli in install_requires after the regression changes in took it out + and some users never added it even tho they have pyproject.toml files + +6.3.0 +======= + +.. warning:: + + This release explicitly warns on unsupported setuptools. + This unfortunately has to happen as the legacy ``setup_requires`` mechanism + incorrectly configures the setuptools working-set when a more recent setuptools + version than available is required. + + As all releases of setuptools are affected as the historic mechanism + for ensuring a working setuptools setup was shipping a ``ez_setup`` file + next to ``setup.py``, which would install the required version of setuptools. + + This mechanism has long since been deprecated and removed + as most people haven't been using it + + +* fix #612: depend on packaging to ensure version parsing parts +* fix #611: correct the typo that hid away the toml extra and add it in ``setup.py`` as well +* fix #615: restore support for the git_archive plugin which doesn't pass over the config +* restore the ability to run on old setuptools while to avoid breaking pipelines + +v6.2.0 +======= + +* fix #608: resolve tomli dependency issue by making it a hard dependency + as all intended/supported install options use pip/wheel this is only a feature release +* ensure python 3.10 works + +v6.1.1 +======= + +* fix #605: completely disallow bdist_egg - modern enough setuptools>=45 uses pip +* fix #606: re-integrate and harden toml parsing +* fix #597: harden and expand support for figuring the current distribution name from + `pyproject.toml` (`project.name` or `tool.setuptools_scm.dist_name`) section or `setup.cfg` (`metadata.name`) + +v6.1.0 +====== + +* fix #587: don't fail file finders when distribution is not given +* fix #524: new parameters ``normalize`` and ``version_cls`` to customize the version normalization class. +* fix #585: switch from toml to tomli for toml 1.0 support +* fix #591: allow to opt in for searching parent directories in the api +* fix #589: handle yaml encoding using the expected defaults +* fix #575: recommend storing the version_module inside of ``mypkg/_version.py`` +* fix #571: accept branches starting with ``v`` as release branches +* fix #557: Use ``packaging.version`` for ``version_tuple`` +* fix #544: enhance errors on unsupported python/setuptools versions + +v6.0.1 +====== + +* fix #537: drop node_date on old git to avoid errors on missing %cI + v6.0.0 ====== @@ -205,8 +301,8 @@ * require parse results to be ScmVersion or None (breaking change) * fix #266 by requiring the prefix word to be a word again (breaking change as the bug allowed arbitrary prefixes while the original feature only allowed words") -* introduce a internal config object to allow the configruation fo tag parsing and prefixes - (thanks to @punkadiddle for introducing it and passing it trough) +* introduce an internal config object to allow the configuration for tag parsing and prefixes + (thanks to @punkadiddle for introducing it and passing it through) v2.1.0 ====== @@ -223,7 +319,7 @@ * fix #237 - correct imports in code examples * improve mercurial commit detection (thanks Aaron) * breaking change: remove support for setuptools before parsed versions -* reintroduce manifest as the travis deploy cant use the file finder +* reintroduce manifest as the travis deploy can't use the file finder * reconfigure flake8 for future compatibility with black * introduce support for branch name in version metadata and support a opt-in simplified semver version scheme @@ -253,8 +349,8 @@ ======= * drop support for eol python versions -* #214 - fix missuse in surogate-escape api -* add the node-and-timestamp local version sheme +* #214 - fix misuse in surogate-escape api +* add the node-and-timestamp local version scheme * respect git export ignores * avoid shlex.split on windows * fix #218 - better handling of mercurial edge-cases with tag commits @@ -283,7 +379,7 @@ v1.15.4 ======= -* fix issue #164: iterate all found entry points to avoid erros when pip remakes egg-info +* fix issue #164: iterate all found entry points to avoid errors when pip remakes egg-info * enhance self-use to enable pip install from github again v1.15.3 @@ -314,7 +410,7 @@ when considering distance in commits (thanks Petre Mierlutiu) * fix issue #114: stop trying to be smart for the sdist - and ensure its always correctly usign itself + and ensure its always correctly using itself * update trove classifiers * fix issue #84: document using the installed package metadata for sphinx * fix issue #81: fail more gracious when git/hg are missing @@ -329,7 +425,7 @@ don't consider untracked file (this was a regression due to #86 in v1.13.1) * consider the distance 0 when the git node is unknown - (happens when you haven't commited anything) + (happens when you haven't committed anything) v1.14.0 ======= @@ -347,7 +443,7 @@ * fix regression caused by the fix of #101 * assert types for version dumping - * strictly pass all versions trough parsed version metadata + * strictly pass all versions through parsed version metadata v1.12.0 ======= @@ -385,7 +481,7 @@ * add support for overriding the version number via the environment variable SETUPTOOLS_SCM_PRETEND_VERSION -* fix isssue #63 by adding the --match parameter to the git describe call +* fix issue #63 by adding the --match parameter to the git describe call and prepare the possibility of passing more options to scm backends * fix issue #70 and #71 by introducing the parse keyword @@ -429,7 +525,7 @@ before we would let the setup stay at version 0.0, now there is a ValueError -* propperly raise errors on write_to missuse (thanks Te-jé Rodgers) +* properly raise errors on write_to misuse (thanks Te-jé Rodgers) v1.5.5 ====== @@ -466,7 +562,7 @@ v1.4.0 ====== -* propper handling for sdist +* proper handling for sdist * fix file-finder failure from windows * resuffle docs
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/MANIFEST.in -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/MANIFEST.in
Changed
@@ -6,4 +6,6 @@ include *.rst include LICENSE include *.toml +include mypy.ini +include testing/Dockerfile.busted-buster recursive-include testing *.bash
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/PKG-INFO -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/PKG-INFO
Changed
@@ -1,633 +1,11 @@ Metadata-Version: 2.1 Name: setuptools_scm -Version: 6.0.0 +Version: 6.4.2 Summary: the blessed package to manage your versions by scm tags Home-page: https://github.com/pypa/setuptools_scm/ Author: Ronny Pfannschmidt Author-email: opensource@ronnypfannschmidt.de License: MIT -Description: setuptools_scm - ============== - - ``setuptools_scm`` handles managing your Python package versions - in SCM metadata instead of declaring them as the version argument - or in a SCM managed file. - - Additionally ``setuptools_scm`` provides setuptools with a list of files that are managed by the SCM - (i.e. it automatically adds all of the SCM-managed files to the sdist). - Unwanted files must be excluded by discarding them via ``MANIFEST.in``. - - ``setuptools_scm`` support the following scm out of the box: - - * git - * mercurial - - - - .. image:: https://github.com/pypa/setuptools_scm/workflows/python%20tests+artifacts+release/badge.svg - :target: https://github.com/pypa/setuptools_scm/actions - - .. image:: https://tidelift.com/badges/package/pypi/setuptools-scm - :target: https://tidelift.com/subscription/pkg/pypi-setuptools-scm?utm_source=pypi-setuptools-scm&utm_medium=readme - - - ``pyproject.toml`` usage - ------------------------ - - The preferred way to configure ``setuptools_scm`` is to author - settings in a ``tool.setuptools_scm`` section of ``pyproject.toml``. - - This feature requires Setuptools 42 or later, released in Nov, 2019. - If your project needs to support build from sdist on older versions - of Setuptools, you will need to also implement the ``setup.py usage`` - for those legacy environments. - - First, ensure that ``setuptools_scm`` is present during the project's - built step by specifying it as one of the build requirements. - - .. code:: toml - - # pyproject.toml - build-system - requires = "setuptools>=42", "wheel", "setuptools_scmtoml>=3.4" - - Note that the ``toml`` extra must be supplied. - - That will be sufficient to require ``setuptools_scm`` for projects - that support PEP 518 (`pip <https://pypi.org/project/pip>`_ and - `pep517 <https://pypi.org/project/pep517/>`_). Many tools, - especially those that invoke ``setup.py`` for any reason, may - continue to rely on ``setup_requires``. For maximum compatibility - with those uses, consider also including a ``setup_requires`` directive - (described below in ``setup.py usage`` and ``setup.cfg``). - - To enable version inference, add this section to your pyproject.toml: - - .. code:: toml - - # pyproject.toml - tool.setuptools_scm - - Including this section is comparable to supplying - ``use_scm_version=True`` in ``setup.py``. Additionally, - include arbitrary keyword arguments in that section - to be supplied to ``get_version()``. For example: - - .. code:: toml - - # pyproject.toml - - tool.setuptools_scm - write_to = "pkg/version.py" - - - ``setup.py`` usage - ------------------ - - The following settings are considered legacy behavior and - superseded by the ``pyproject.toml`` usage, but for maximal - compatibility, projects may also supply the configuration in - this older form. - - To use ``setuptools_scm`` just modify your project's ``setup.py`` file - like this: - - * Add ``setuptools_scm`` to the ``setup_requires`` parameter. - * Add the ``use_scm_version`` parameter and set it to ``True``. - - For example: - - .. code:: python - - from setuptools import setup - setup( - ..., - use_scm_version=True, - setup_requires='setuptools_scm', - ..., - ) - - Arguments to ``get_version()`` (see below) may be passed as a dictionary to - ``use_scm_version``. For example: - - .. code:: python - - from setuptools import setup - setup( - ..., - use_scm_version = { - "root": "..", - "relative_to": __file__, - "local_scheme": "node-and-timestamp" - }, - setup_requires='setuptools_scm', - ..., - ) - - You can confirm the version number locally via ``setup.py``: - - .. code-block:: shell - - $ python setup.py --version - - .. note:: - - If you see unusual version numbers for packages but ``python setup.py - --version`` reports the expected version number, ensure ``egg_info`` is - not defined in ``setup.cfg``. - - - ``setup.cfg`` usage - ------------------- - - If using `setuptools 30.3.0 - <https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_ - or greater, you can store ``setup_requires`` configuration in ``setup.cfg``. - However, ``use_scm_version`` must still be placed in ``setup.py``. For example: - - .. code:: python - - # setup.py - from setuptools import setup - setup( - use_scm_version=True, - ) - - .. code:: ini - - # setup.cfg - metadata - ... - - options - setup_requires = - setuptools_scm - ... - - .. important:: - - Ensure neither the ``metadata`` ``version`` option nor the ``egg_info`` - section are defined, as these will interfere with ``setuptools_scm``. - - You may also need to define a ``pyproject.toml`` file (`PEP-0518 - <https://www.python.org/dev/peps/pep-0518>`_) to ensure you have the required - version of ``setuptools``: - - .. code:: ini - - # pyproject.toml - build-system - requires = "setuptools>=30.3.0", "wheel", "setuptools_scm" - - For more information, refer to the `setuptools issue #1002 - <https://github.com/pypa/setuptools/issues/1002>`_. - - - Programmatic usage - ------------------ - - In order to use ``setuptools_scm`` from code that is one directory deeper - than the project's root, you can use: - - .. code:: python - - from setuptools_scm import get_version - version = get_version(root='..', relative_to=__file__) - - See `setup.py Usage`_ above for how to use this within ``setup.py``. -
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/README.rst -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/README.rst
Changed
@@ -1,8 +1,8 @@ setuptools_scm ============== -``setuptools_scm`` handles managing your Python package versions -in SCM metadata instead of declaring them as the version argument +``setuptools_scm`` extract Python package versions from ``git`` or +``hg`` metadata instead of declaring them as the version argument or in a SCM managed file. Additionally ``setuptools_scm`` provides setuptools with a list of files that are managed by the SCM @@ -41,9 +41,8 @@ # pyproject.toml build-system - requires = "setuptools>=42", "wheel", "setuptools_scmtoml>=3.4" + requires = "setuptools>=45", "wheel", "setuptools_scm>=6.2" -Note that the ``toml`` extra must be supplied. That will be sufficient to require ``setuptools_scm`` for projects that support PEP 518 (`pip <https://pypi.org/project/pip>`_ and @@ -70,11 +69,15 @@ # pyproject.toml tool.setuptools_scm - write_to = "pkg/version.py" + write_to = "pkg/_version.py" -``setup.py`` usage ------------------- +``setup.py`` usage (deprecated) +------------------------------- + +.. warning:: + + ``setup_requires`` has been deprecated in favor of ``pyproject.toml`` The following settings are considered legacy behavior and superseded by the ``pyproject.toml`` usage, but for maximal @@ -129,51 +132,12 @@ not defined in ``setup.cfg``. -``setup.cfg`` usage -------------------- - -If using `setuptools 30.3.0 -<https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_ -or greater, you can store ``setup_requires`` configuration in ``setup.cfg``. -However, ``use_scm_version`` must still be placed in ``setup.py``. For example: - -.. code:: python - - # setup.py - from setuptools import setup - setup( - use_scm_version=True, - ) - -.. code:: ini - - # setup.cfg - metadata - ... - - options - setup_requires = - setuptools_scm - ... - -.. important:: - - Ensure neither the ``metadata`` ``version`` option nor the ``egg_info`` - section are defined, as these will interfere with ``setuptools_scm``. - -You may also need to define a ``pyproject.toml`` file (`PEP-0518 -<https://www.python.org/dev/peps/pep-0518>`_) to ensure you have the required -version of ``setuptools``: - -.. code:: ini - - # pyproject.toml - build-system - requires = "setuptools>=30.3.0", "wheel", "setuptools_scm" - -For more information, refer to the `setuptools issue #1002 -<https://github.com/pypa/setuptools/issues/1002>`_. +``setup.cfg`` usage (deprecated) +------------------------------------ +as ``setup_requires`` is deprecated in favour of ``pyproject.toml`` +usage in ``setup.cfg`` is considered deprecated, +please use ``pyproject.toml`` whenever possible. Programmatic usage ------------------ @@ -186,7 +150,7 @@ from setuptools_scm import get_version version = get_version(root='..', relative_to=__file__) -See `setup.py Usage`_ above for how to use this within ``setup.py``. +See `setup.py Usage (deprecated)`_ above for how to use this within ``setup.py``. Retrieving package version at runtime @@ -208,7 +172,7 @@ pass Alternatively, you can use ``pkg_resources`` which is included in -``setuptools``: +``setuptools`` (but has a significant runtime cost): .. code:: python @@ -231,13 +195,13 @@ ----------------- It is discouraged to use ``setuptools_scm`` from Sphinx itself, -instead use ``pkg_resources`` after editable/real installation: +instead use ``importlib.metadata`` after editable/real installation: .. code:: python # contents of docs/conf.py - from pkg_resources import get_distribution - release = get_distribution('myproject').version + from importlib.metadata import version + release = version('myproject') # for example take major/minor version = '.'.join(release.split('.'):2) @@ -245,6 +209,39 @@ the working directory for good reasons and using the installed metadata prevents using needless volatile data there. +Usage from Docker +----------------- + +By default, docker will not copy the ``.git`` folder into your container. +Therefore, builds with version inference might fail. +Consequently, you can use the following snipped to infer the version from +the host os without copying the entire ``.git`` folder to your Dockerfile. + +.. code:: dockerfile + + RUN --mount=source=.git,target=.git,type=bind \ + pip install --no-cache-dir -e . + +However, this build step introduces a dependency to the state of your local +.git folder the build cache and triggers the long-running pip install process on every build. +To optimize build caching, one can use an environment variable to pretend a pseudo +version that is used to cache the results of the pip install process: + +.. code:: dockerfile + + FROM python + COPY pyproject.toml + ARG PSEUDO_VERSION=1 + RUN SETUPTOOLS_SCM_PRETEND_VERSION=${PSEUDO_VERSION} pip install -e .test + RUN --mount=source=.git,target=.git,type=bind pip install -e . + +Note that running this Dockerfile requires docker with BuildKit enabled +`docs <https://github.com/moby/buildkit/blob/v0.8.3/frontend/dockerfile/docs/syntax.md>`_. + +To avoid BuildKit and mounting of the .git folder altogether, one can also pass the desired +version as a build argument. Note that ``SETUPTOOLS_SCM_PRETEND_VERSION_FOR_${UPPERCASED_DIST_NAME}`` +is preferred over ``SETUPTOOLS_SCM_PRETEND_VERSION``. + Notable Plugins --------------- @@ -351,7 +348,7 @@ :write_to: A path to a file that gets replaced with a file containing the current - version. It is ideal for creating a ``version.py`` file within the + version. It is ideal for creating a ``_version.py`` file within the package, typically used to avoid using `pkg_resources.get_distribution` (which adds some overhead). @@ -411,6 +408,30 @@ Defaults to the value set by ``setuptools_scm.git.DEFAULT_DESCRIBE`` (see `git.py <src/setuptools_scm/git.py>`_). +:normalize: + A boolean flag indicating if the version string should be normalized. + Defaults to ``True``. Setting this to ``False`` is equivalent to setting + ``version_cls`` to ``setuptools_scm.version.NonNormalizedVersion`` + +:version_cls: + An optional class used to parse, verify and possibly normalize the version + string. Its constructor should receive a single string argument, and its + ``str`` should return the normalized version string to use. + This option can also receive a class qualified name as a string. + + This defaults to ``packaging.version.Version`` if available. If + ``packaging`` is not installed, ``pkg_resources.packaging.version.Version`` + is used. Note that it is known to modify git release candidate schemes.
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/mypy.ini
Added
@@ -0,0 +1,10 @@ +mypy +python_version = 3.6 +warn_return_any = True +warn_unused_configs = True +mypy_path = $MYPY_CONFIG_FILE_DIR/src + +mypy-setuptools_scm.* +# disabled as it will take a bit +# disallow_untyped_defs = True +# strict = true
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/pyproject.toml -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/pyproject.toml
Changed
@@ -1,3 +1,8 @@ build-system -requires = "setuptools>=45", "wheel" +requires = + "setuptools>=45", + "wheel", + "tomli>=1.0", + "packaging>=20.0" + build-backend = "setuptools.build_meta"
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/setup.cfg -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/setup.cfg
Changed
@@ -19,6 +19,7 @@ Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Topic :: Software Development :: Libraries Topic :: Software Development :: Version Control Topic :: System :: Software Distribution @@ -27,12 +28,17 @@ options packages = find: install_requires = - setuptools>=45 + packaging>=20.0 + setuptools + tomli>=1.0.0 # keep in sync python_requires = >=3.6 package_dir = =src zip_safe = true +options.packages.find +where = src + options.entry_points distutils.setup_keywords = use_scm_version = setuptools_scm.integration:version_keyword @@ -56,6 +62,7 @@ PKG-INFO = setuptools_scm.hacks:parse_pkginfo pip-egg-info = setuptools_scm.hacks:parse_pip_egg_info setup.py = setuptools_scm.hacks:fallback_version + pyproject.toml = setuptools_scm.hacks:fallback_version setuptools_scm.version_scheme = guess-next-dev = setuptools_scm.version:guess_next_dev_version post-release = setuptools_scm.version:postrelease_version @@ -64,13 +71,6 @@ no-guess-dev = setuptools_scm.version:no_guess_dev_version calver-by-date = setuptools_scm.version:calver_by_date -options.extras_require -toml = - toml - -options.packages.find -where = src - egg_info tag_build = tag_date = 0
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/setup.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/setup.py
Changed
@@ -11,42 +11,58 @@ """ import os import sys + import setuptools +from setuptools.command.bdist_egg import bdist_egg as original_bdist_egg + + +class bdist_egg(original_bdist_egg): + def run(self): + raise SystemExit( + "%s is forbidden, " + "please update to setuptools>=45 which uses pip" % type(self).__name__ + ) + +def scm_version(): -def scm_config(): + if sys.version_info < (3, 6): + raise RuntimeError( + "support for python < 3.6 has been removed in setuptools_scm>=6.0.0" + ) here = os.path.dirname(os.path.abspath(__file__)) src = os.path.join(here, "src") - egg_info = os.path.join(src, "setuptools_scm.egg-info") - has_entrypoints = os.path.isdir(egg_info) - import pkg_resources sys.path.insert(0, src) - pkg_resources.working_set.add_entry(src) - # FIXME: remove debug - print(src) - print(pkg_resources.working_set) + + from setuptools_scm import get_version from setuptools_scm.hacks import parse_pkginfo - from setuptools_scm.git import parse as parse_git + from setuptools_scm import git + from setuptools_scm import hg from setuptools_scm.version import guess_next_dev_version, get_local_node_and_date - def parse(root): + def parse(root, config): try: - return parse_pkginfo(root) + return parse_pkginfo(root, config) except OSError: - return parse_git(root) + return git.parse(root, config=config) or hg.parse(root, config=config) - config = dict( - version_scheme=guess_next_dev_version, local_scheme=get_local_node_and_date + return get_version( + root=here, + parse=parse, + version_scheme=guess_next_dev_version, + local_scheme=get_local_node_and_date, ) - if has_entrypoints: - return dict(use_scm_version=config) - else: - from setuptools_scm import get_version - - return dict(version=get_version(root=here, parse=parse, **config)) - if __name__ == "__main__": - setuptools.setup(**scm_config()) + setuptools.setup( + version=scm_version(), + extras_require={ + "toml": + "setuptools>=42", + , + "test": "pytest>=6.2", "virtualenv>20", + }, + cmdclass={"bdist_egg": bdist_egg}, + )
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm.egg-info/PKG-INFO -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm.egg-info/PKG-INFO
Changed
@@ -1,633 +1,11 @@ Metadata-Version: 2.1 Name: setuptools-scm -Version: 6.0.0 +Version: 6.4.2 Summary: the blessed package to manage your versions by scm tags Home-page: https://github.com/pypa/setuptools_scm/ Author: Ronny Pfannschmidt Author-email: opensource@ronnypfannschmidt.de License: MIT -Description: setuptools_scm - ============== - - ``setuptools_scm`` handles managing your Python package versions - in SCM metadata instead of declaring them as the version argument - or in a SCM managed file. - - Additionally ``setuptools_scm`` provides setuptools with a list of files that are managed by the SCM - (i.e. it automatically adds all of the SCM-managed files to the sdist). - Unwanted files must be excluded by discarding them via ``MANIFEST.in``. - - ``setuptools_scm`` support the following scm out of the box: - - * git - * mercurial - - - - .. image:: https://github.com/pypa/setuptools_scm/workflows/python%20tests+artifacts+release/badge.svg - :target: https://github.com/pypa/setuptools_scm/actions - - .. image:: https://tidelift.com/badges/package/pypi/setuptools-scm - :target: https://tidelift.com/subscription/pkg/pypi-setuptools-scm?utm_source=pypi-setuptools-scm&utm_medium=readme - - - ``pyproject.toml`` usage - ------------------------ - - The preferred way to configure ``setuptools_scm`` is to author - settings in a ``tool.setuptools_scm`` section of ``pyproject.toml``. - - This feature requires Setuptools 42 or later, released in Nov, 2019. - If your project needs to support build from sdist on older versions - of Setuptools, you will need to also implement the ``setup.py usage`` - for those legacy environments. - - First, ensure that ``setuptools_scm`` is present during the project's - built step by specifying it as one of the build requirements. - - .. code:: toml - - # pyproject.toml - build-system - requires = "setuptools>=42", "wheel", "setuptools_scmtoml>=3.4" - - Note that the ``toml`` extra must be supplied. - - That will be sufficient to require ``setuptools_scm`` for projects - that support PEP 518 (`pip <https://pypi.org/project/pip>`_ and - `pep517 <https://pypi.org/project/pep517/>`_). Many tools, - especially those that invoke ``setup.py`` for any reason, may - continue to rely on ``setup_requires``. For maximum compatibility - with those uses, consider also including a ``setup_requires`` directive - (described below in ``setup.py usage`` and ``setup.cfg``). - - To enable version inference, add this section to your pyproject.toml: - - .. code:: toml - - # pyproject.toml - tool.setuptools_scm - - Including this section is comparable to supplying - ``use_scm_version=True`` in ``setup.py``. Additionally, - include arbitrary keyword arguments in that section - to be supplied to ``get_version()``. For example: - - .. code:: toml - - # pyproject.toml - - tool.setuptools_scm - write_to = "pkg/version.py" - - - ``setup.py`` usage - ------------------ - - The following settings are considered legacy behavior and - superseded by the ``pyproject.toml`` usage, but for maximal - compatibility, projects may also supply the configuration in - this older form. - - To use ``setuptools_scm`` just modify your project's ``setup.py`` file - like this: - - * Add ``setuptools_scm`` to the ``setup_requires`` parameter. - * Add the ``use_scm_version`` parameter and set it to ``True``. - - For example: - - .. code:: python - - from setuptools import setup - setup( - ..., - use_scm_version=True, - setup_requires='setuptools_scm', - ..., - ) - - Arguments to ``get_version()`` (see below) may be passed as a dictionary to - ``use_scm_version``. For example: - - .. code:: python - - from setuptools import setup - setup( - ..., - use_scm_version = { - "root": "..", - "relative_to": __file__, - "local_scheme": "node-and-timestamp" - }, - setup_requires='setuptools_scm', - ..., - ) - - You can confirm the version number locally via ``setup.py``: - - .. code-block:: shell - - $ python setup.py --version - - .. note:: - - If you see unusual version numbers for packages but ``python setup.py - --version`` reports the expected version number, ensure ``egg_info`` is - not defined in ``setup.cfg``. - - - ``setup.cfg`` usage - ------------------- - - If using `setuptools 30.3.0 - <https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_ - or greater, you can store ``setup_requires`` configuration in ``setup.cfg``. - However, ``use_scm_version`` must still be placed in ``setup.py``. For example: - - .. code:: python - - # setup.py - from setuptools import setup - setup( - use_scm_version=True, - ) - - .. code:: ini - - # setup.cfg - metadata - ... - - options - setup_requires = - setuptools_scm - ... - - .. important:: - - Ensure neither the ``metadata`` ``version`` option nor the ``egg_info`` - section are defined, as these will interfere with ``setuptools_scm``. - - You may also need to define a ``pyproject.toml`` file (`PEP-0518 - <https://www.python.org/dev/peps/pep-0518>`_) to ensure you have the required - version of ``setuptools``: - - .. code:: ini - - # pyproject.toml - build-system - requires = "setuptools>=30.3.0", "wheel", "setuptools_scm" - - For more information, refer to the `setuptools issue #1002 - <https://github.com/pypa/setuptools/issues/1002>`_. - - - Programmatic usage - ------------------ - - In order to use ``setuptools_scm`` from code that is one directory deeper - than the project's root, you can use: - - .. code:: python - - from setuptools_scm import get_version - version = get_version(root='..', relative_to=__file__) - - See `setup.py Usage`_ above for how to use this within ``setup.py``. -
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm.egg-info/SOURCES.txt -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm.egg-info/SOURCES.txt
Changed
@@ -1,17 +1,18 @@ -.gitignore CHANGELOG.rst LICENSE MANIFEST.in README.rst +mypy.ini pyproject.toml setup.cfg setup.py tox.ini -.github/FUNDING.yml -.github/workflows/pre-commit.yml -.github/workflows/python-tests.yml src/setuptools_scm/__init__.py src/setuptools_scm/__main__.py +src/setuptools_scm/_entrypoints.py +src/setuptools_scm/_overrides.py +src/setuptools_scm/_types.py +src/setuptools_scm/_version_cls.py src/setuptools_scm/config.py src/setuptools_scm/discover.py src/setuptools_scm/file_finder.py @@ -20,7 +21,9 @@ src/setuptools_scm/git.py src/setuptools_scm/hacks.py src/setuptools_scm/hg.py +src/setuptools_scm/hg_git.py src/setuptools_scm/integration.py +src/setuptools_scm/scm_workdir.py src/setuptools_scm/utils.py src/setuptools_scm/version.py src/setuptools_scm.egg-info/PKG-INFO @@ -30,6 +33,7 @@ src/setuptools_scm.egg-info/requires.txt src/setuptools_scm.egg-info/top_level.txt src/setuptools_scm.egg-info/zip-safe +testing/Dockerfile.busted-buster testing/check_self_install.py testing/conftest.py testing/play_out_381.bash @@ -38,6 +42,7 @@ testing/test_file_finder.py testing/test_functions.py testing/test_git.py +testing/test_hg_git.py testing/test_integration.py testing/test_main.py testing/test_mercurial.py
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm.egg-info/entry_points.txt -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm.egg-info/entry_points.txt
Changed
@@ -25,6 +25,7 @@ .hg_archival.txt = setuptools_scm.hg:parse_archival PKG-INFO = setuptools_scm.hacks:parse_pkginfo pip-egg-info = setuptools_scm.hacks:parse_pip_egg_info +pyproject.toml = setuptools_scm.hacks:fallback_version setup.py = setuptools_scm.hacks:fallback_version setuptools_scm.version_scheme
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm.egg-info/requires.txt -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm.egg-info/requires.txt
Changed
@@ -1,4 +1,10 @@ -setuptools>=45 +packaging>=20.0 +setuptools +tomli>=1.0.0 + +test +pytest>=6.2 +virtualenv>20 toml -toml +setuptools>=42
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/__init__.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/__init__.py
Changed
@@ -4,19 +4,32 @@ """ import os import warnings - -from .config import ( - Configuration, - DEFAULT_VERSION_SCHEME, - DEFAULT_LOCAL_SCHEME, - DEFAULT_TAG_REGEX, -) -from .utils import function_has_arg, trace -from .version import format_version, meta +from typing import Optional +from typing import TYPE_CHECKING + +from . import _types +from ._entrypoints import _call_entrypoint_fn +from ._entrypoints import _version_from_entrypoints +from ._overrides import _read_pretended_version_for +from ._overrides import PRETEND_KEY +from ._overrides import PRETEND_KEY_NAMED +from ._version_cls import _version_as_tuple +from ._version_cls import NonNormalizedVersion +from ._version_cls import Version +from .config import Configuration +from .config import DEFAULT_LOCAL_SCHEME +from .config import DEFAULT_TAG_REGEX +from .config import DEFAULT_VERSION_SCHEME from .discover import iter_matching_entrypoints +from .utils import function_has_arg +from .utils import trace +from .version import format_version +from .version import meta +from .version import ScmVersion + +if TYPE_CHECKING: + from typing import NoReturn -PRETEND_KEY = "SETUPTOOLS_SCM_PRETEND_VERSION" -PRETEND_KEY_NAMED = PRETEND_KEY + "_FOR_{name}" TEMPLATES = { ".py": """\ @@ -34,44 +47,19 @@ warnings.warn( "version_from_scm is deprecated please use get_version", category=DeprecationWarning, + stacklevel=2, ) - config = Configuration() - config.root = root - # TODO: Is it API? + config = Configuration(root=root) return _version_from_entrypoints(config) -def _call_entrypoint_fn(root, config, fn): - if function_has_arg(fn, "config"): - return fn(root, config=config) - else: - warnings.warn( - "parse functions are required to provide a named argument" - " 'config' in the future.", - category=PendingDeprecationWarning, - stacklevel=2, - ) - return fn(root) - - -def _version_from_entrypoints(config, fallback=False): - if fallback: - entrypoint = "setuptools_scm.parse_scm_fallback" - root = config.fallback_root - else: - entrypoint = "setuptools_scm.parse_scm" - root = config.absolute_root - for ep in iter_matching_entrypoints(root, entrypoint): - version = _call_entrypoint_fn(root, config, ep.load()) - - if version: - return version - - -def dump_version(root, version, write_to, template=None): +def dump_version( + root: _types.PathT, + version: str, + write_to: _types.PathT, + template: "str | None" = None, +): assert isinstance(version, str) - if not write_to: - return target = os.path.normpath(os.path.join(root, write_to)) ext = os.path.splitext(target)1 template = template or TEMPLATES.get(ext) @@ -82,38 +70,16 @@ os.path.splitext(target)1, target ) ) - - # version_tuple: each field is converted to an int if possible or kept as string - fields = tuple(version.split(".")) - version_fields = - for field in fields: - try: - v = int(field) - except ValueError: - v = field - version_fields.append(v) + version_tuple = _version_as_tuple(version) with open(target, "w") as fp: - fp.write(template.format(version=version, version_tuple=tuple(version_fields))) - - -def _do_parse(config): - - trace("dist name:", config.dist_name) - if config.dist_name is not None: - pretended = os.environ.get( - PRETEND_KEY_NAMED.format(name=config.dist_name.upper()) - ) - else: - pretended = None + fp.write(template.format(version=version, version_tuple=version_tuple)) - if pretended is None: - pretended = os.environ.get(PRETEND_KEY) - if pretended: - # we use meta here since the pretended version - # must adhere to the pep to begin with - return meta(tag=pretended, preformatted=True, config=config) +def _do_parse(config: Configuration) -> "ScmVersion|None": + pretended = _read_pretended_version_for(config) + if pretended is not None: + return pretended if config.parse: parse_result = _call_entrypoint_fn(config.absolute_root, config, config.parse) @@ -121,25 +87,31 @@ raise TypeError( "version parse result was a string\nplease return a parsed version" ) - version = parse_result or _version_from_entrypoints(config, fallback=True) + version: OptionalScmVersion + if parse_result: + assert isinstance(parse_result, ScmVersion) + version = parse_result + else: + version = _version_from_entrypoints(config, fallback=True) else: # include fallbacks after dropping them from the main entrypoint version = _version_from_entrypoints(config) or _version_from_entrypoints( config, fallback=True ) - if version: - return version + return version + +def _version_missing(config) -> "NoReturn": raise LookupError( - "setuptools-scm was unable to detect version for %r.\n\n" + f"setuptools-scm was unable to detect version for {config.absolute_root}.\n\n" "Make sure you're either building from a fully intact git repository " "or PyPI tarballs. Most other sources (such as GitHub's tarballs, a " "git checkout without the .git folder) don't contain the necessary " "metadata and will not work.\n\n" "For example, if you're using pip, instead of " "https://github.com/user/proj/archive/master.zip " - "use git+https://github.com/user/proj.git#egg=proj" % config.absolute_root + "use git+https://github.com/user/proj.git#egg=proj" ) @@ -157,6 +129,9 @@ parse=None, git_describe_command=None, dist_name=None, + version_cls=None, + normalize=True, + search_parent_directories=False, ): """ If supplied, relative_to should be a file from which root may @@ -166,18 +141,22 @@ """ config = Configuration(**locals()) - return _get_version(config) + maybe_version = _get_version(config) + if maybe_version is None: + _version_missing(config) + return maybe_version
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/__main__.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/__main__.py
Changed
@@ -1,14 +1,83 @@ +import argparse +import os import sys -from setuptools_scm import get_version + +from setuptools_scm import _get_version +from setuptools_scm.config import Configuration +from setuptools_scm.discover import walk_potential_roots from setuptools_scm.integration import find_files -def main(): - print("Guessed Version", get_version()) - if "ls" in sys.argv: - for fname in find_files("."): +def main() -> None: + opts = _get_cli_opts() + root = opts.root or "." + + try: + pyproject = opts.config or _find_pyproject(root) + root = opts.root or os.path.relpath(os.path.dirname(pyproject)) + config = Configuration.from_file(pyproject, root=root) + except (LookupError, FileNotFoundError) as ex: + # no pyproject.toml OR no tool.setuptools_scm + print( + f"Warning: could not use {os.path.relpath(pyproject)}," + " using default configuration.\n" + f" Reason: {ex}.", + file=sys.stderr, + ) + config = Configuration(root=root) + + version = _get_version(config) + assert version is not None + if opts.strip_dev: + version = version.partition(".dev")0 + print(version) + + if opts.command == "ls": + for fname in find_files(config.root): print(fname) +def _get_cli_opts() -> argparse.Namespace: + prog = "python -m setuptools_scm" + desc = "Print project version according to SCM metadata" + parser = argparse.ArgumentParser(prog, description=desc) + # By default, help for `--help` starts with lower case, so we keep the pattern: + parser.add_argument( + "-r", + "--root", + default=None, + help='directory managed by the SCM, default: inferred from config file, or "."', + ) + parser.add_argument( + "-c", + "--config", + default=None, + metavar="PATH", + help="path to 'pyproject.toml' with setuptools_scm config, " + "default: looked up in the current or parent directories", + ) + parser.add_argument( + "--strip-dev", + action="store_true", + help="remove the dev/local parts of the version before printing the version", + ) + sub = parser.add_subparsers(title="extra commands", dest="command", metavar="") + # We avoid `metavar` to prevent printing repetitive information + desc = "List files managed by the SCM" + sub.add_parser("ls", help=desc0.lower() + desc1:, description=desc) + return parser.parse_args() + + +def _find_pyproject(parent: str) -> str: + for directory in walk_potential_roots(os.path.abspath(parent)): + pyproject = os.path.join(directory, "pyproject.toml") + if os.path.isfile(pyproject): + return pyproject + + return os.path.abspath( + "pyproject.toml" + ) # use default name to trigger the default errors + + if __name__ == "__main__": main()
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/_entrypoints.py
Added
@@ -0,0 +1,58 @@ +import warnings +from typing import Optional + +from .config import Configuration +from .discover import iter_matching_entrypoints +from .utils import function_has_arg +from .utils import trace +from setuptools_scm.version import ScmVersion + + +def _call_entrypoint_fn(root, config, fn): + if function_has_arg(fn, "config"): + return fn(root, config=config) + else: + warnings.warn( + f"parse function {fn.__module__}.{fn.__name__}" + " are required to provide a named argument" + " 'config', setuptools_scm>=8.0 will remove support.", + category=DeprecationWarning, + stacklevel=2, + ) + return fn(root) + + +def _version_from_entrypoints( + config: Configuration, fallback: bool = False +) -> "ScmVersion|None": + if fallback: + entrypoint = "setuptools_scm.parse_scm_fallback" + root = config.fallback_root + else: + entrypoint = "setuptools_scm.parse_scm" + root = config.absolute_root + + trace("version_from_ep", entrypoint, root) + for ep in iter_matching_entrypoints(root, entrypoint, config): + version: OptionalScmVersion = _call_entrypoint_fn(root, config, ep.load()) + trace(ep, version) + if version: + return version + return None + + +try: + from importlib.metadata import entry_points # type: ignore +except ImportError: + from pkg_resources import iter_entry_points +else: + + def iter_entry_points(group: str, name: Optionalstr = None): + all_eps = entry_points() + if hasattr(all_eps, "select"): + eps = all_eps.select(group=group) + else: + eps = all_epsgroup + if name is None: + return iter(eps) + return (ep for ep in eps if ep.name == name)
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/_overrides.py
Added
@@ -0,0 +1,37 @@ +import os +from typing import Optional + +from .config import Configuration +from .utils import trace +from .version import meta +from .version import ScmVersion + + +PRETEND_KEY = "SETUPTOOLS_SCM_PRETEND_VERSION" +PRETEND_KEY_NAMED = PRETEND_KEY + "_FOR_{name}" + + +def _read_pretended_version_for(config: Configuration) -> OptionalScmVersion: + """read a a overridden version from the environment + + tries ``SETUPTOOLS_SCM_PRETEND_VERSION`` + and ``SETUPTOOLS_SCM_PRETEND_VERSION_FOR_$UPPERCASE_DIST_NAME`` + """ + trace("dist name:", config.dist_name) + pretended: Optionalstr + if config.dist_name is not None: + pretended = os.environ.get( + PRETEND_KEY_NAMED.format(name=config.dist_name.upper()) + ) + else: + pretended = None + + if pretended is None: + pretended = os.environ.get(PRETEND_KEY) + + if pretended is not None: + # we use meta here since the pretended version + # must adhere to the pep to begin with + return meta(tag=pretended, preformatted=True, config=config) + else: + return None
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/_types.py
Added
@@ -0,0 +1,31 @@ +import os +from typing import Callable +from typing import TYPE_CHECKING +from typing import TypeVar +from typing import Union + +if TYPE_CHECKING: + + from typing_extensions import ParamSpec +else: + + class ParamSpec(list): + def __init__(self, _) -> None: + pass + + +PathT = Union"os.PathLikestr", str + + +T = TypeVar("T") +T2 = TypeVar("T2") +PARAMS = ParamSpec("PARAMS") + + +def transfer_input_args( + template: "CallablePARAMS, T", +) -> CallableCallable..., T2, "CallablePARAMS, T2": + def decorate(func: Callable..., T2) -> "CallablePARAMS, T2": + return func + + return decorate
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/_version_cls.py
Added
@@ -0,0 +1,74 @@ +from logging import getLogger +from typing import Tuple + +try: + from packaging.version import Version, InvalidVersion + + assert hasattr( + Version, "release" + ), "broken installation ensure packaging>=20 is available" +except ImportError: + from pkg_resources._vendor.packaging.version import ( # type: ignore + Version as SetuptoolsVersion, + InvalidVersion, + ) + + try: + SetuptoolsVersion.release + Version = SetuptoolsVersion # type: ignore + except AttributeError: + + class Version(SetuptoolsVersion): # type: ignore + @property + def release(self): + return self._version.release + + @property + def dev(self): + return self._version.dev + + @property + def local(self): + return self._version.local + + +class NonNormalizedVersion(Version): + """A non-normalizing version handler. + + You can use this class to preserve version verification but skip normalization. + For example you can use this to avoid git release candidate version tags + ("1.0.0-rc1") to be normalized to "1.0.0rc1". Only use this if you fully + trust the version tags. + """ + + def __init__(self, version): + # parse and validate using parent + super().__init__(version) + + # store raw for str + self._raw_version = version + + def __str__(self): + # return the non-normalized version (parent returns the normalized) + return self._raw_version + + def __repr__(self): + # same pattern as parent + return f"<NonNormalizedVersion({self._raw_version!r})>" + + +def _version_as_tuple(version_str) -> Tuple"int | str", ...: + try: + parsed_version = Version(version_str) + except InvalidVersion: + + log = getLogger("setuptools_scm") + log.exception("failed to parse version %s", version_str) + return (version_str,) + else: + version_fields: Tuple"int | str", ... = parsed_version.release + if parsed_version.dev is not None: + version_fields += (f"dev{parsed_version.dev}",) + if parsed_version.local is not None: + version_fields += (parsed_version.local,) + return version_fields
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/config.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/config.py
Changed
@@ -2,7 +2,12 @@ import os import re import warnings +from typing import Type +from typing import TypeVar +from . import _types as _t +from ._version_cls import NonNormalizedVersion +from ._version_cls import Version from .utils import trace DEFAULT_TAG_REGEX = r"^(?:\w-+-)?(?P<version>vV?\d+(?:\.\d+){0,2}^\+*)(?:\+.*)?$" @@ -25,10 +30,13 @@ return regex -def _check_absolute_root(root, relative_to): - trace("l", repr(locals())) +def _check_absolute_root(root: _t.PathT, relative_to: _t.PathT): + trace("abs root", repr(locals())) if relative_to: - if os.path.isabs(root) and not root.startswith(relative_to): + if ( + os.path.isabs(root) + and not os.path.commonpath(root, relative_to) == relative_to + ): warnings.warn( "absolute root path '%s' overrides relative_to '%s'" % (root, relative_to) @@ -47,24 +55,40 @@ return os.path.abspath(root) +def _lazy_tomli_load(data: str): + from tomli import loads + + return loads(data) + + +VersionT = TypeVar("VersionT", Version, NonNormalizedVersion) + + class Configuration: - """ Global configuration model """ + """Global configuration model""" + + _root: _t.PathT + _relative_to: "_t.PathT | None" + version_cls: "TypeVersion|TypeNonNormalizedVersion" def __init__( self, - relative_to=None, - root=".", - version_scheme=DEFAULT_VERSION_SCHEME, + relative_to: "_t.PathT | None" = None, + root: _t.PathT = ".", + version_scheme: str = DEFAULT_VERSION_SCHEME, local_scheme=DEFAULT_LOCAL_SCHEME, - write_to=None, - write_to_template=None, + write_to: "_t.PathT | None" = None, + write_to_template: "str|None" = None, tag_regex=DEFAULT_TAG_REGEX, parentdir_prefix_version=None, - fallback_version=None, - fallback_root=".", + fallback_version: "str|None" = None, + fallback_root: _t.PathT = ".", parse=None, git_describe_command=None, - dist_name=None, + dist_name: str = None, + version_cls: "TypeVersion|TypeNonNormalizedVersion|str|None" = None, + normalize: bool = True, + search_parent_directories: bool = False, ): # TODO: self._relative_to = relative_to @@ -82,6 +106,33 @@ self.tag_regex = tag_regex self.git_describe_command = git_describe_command self.dist_name = dist_name + self.search_parent_directories = search_parent_directories + self.parent = None + + if not normalize: + # `normalize = False` means `version_cls = NonNormalizedVersion` + if version_cls is not None: + raise ValueError( + "Providing a custom `version_cls` is not permitted when " + "`normalize=False`" + ) + self.version_cls = NonNormalizedVersion + else: + # Use `version_cls` if provided, default to packaging or pkg_resources + if version_cls is None: + self.version_cls = Version + elif isinstance(version_cls, str): + try: + # Not sure this will work in old python + import importlib + + pkg, cls_name = version_cls.rsplit(".", 1) + version_cls_host = importlib.import_module(pkg) + self.version_cls = getattr(version_cls_host, cls_name) + except: # noqa + raise ValueError(f"Unable to import version_cls='{version_cls}'") + else: + self.version_cls = version_cls @property def fallback_root(self): @@ -126,14 +177,51 @@ self._tag_regex = _check_tag_regex(value) @classmethod - def from_file(cls, name="pyproject.toml", dist_name=None): + def from_file( + cls, + name: str = "pyproject.toml", + dist_name=None, # type: str | None + _load_toml=_lazy_tomli_load, + **kwargs, + ): """ Read Configuration from pyproject.toml (or similar). Raises exceptions when file is not found or toml is not installed or the file has invalid format or does not contain the tool.setuptools_scm section. """ - with open(name) as strm: - defn = __import__("toml").load(strm) - section = defn.get("tool", {})"setuptools_scm" - return cls(dist_name=dist_name, **section) + + with open(name, encoding="UTF-8") as strm: + data = strm.read() + defn = _load_toml(data) + try: + section = defn.get("tool", {})"setuptools_scm" + except LookupError as e: + raise LookupError( + f"{name} does not contain a tool.setuptools_scm section" + ) from e + if "dist_name" in section: + if dist_name is None: + dist_name = section.pop("dist_name") + else: + assert dist_name == section"dist_name" + del section"dist_name" + if dist_name is None: + if "project" in defn: + # minimal pep 621 support for figuring the pretend keys + dist_name = defn"project".get("name") + if dist_name is None: + dist_name = _read_dist_name_from_setup_cfg() + + return cls(dist_name=dist_name, **section, **kwargs) + + +def _read_dist_name_from_setup_cfg(): + + # minimal effort to read dist_name off setup.cfg metadata + import configparser + + parser = configparser.ConfigParser() + parser.read("setup.cfg") + dist_name = parser.get("metadata", "name", fallback=None) + return dist_name
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/discover.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/discover.py
Changed
@@ -1,13 +1,58 @@ import os -from pkg_resources import iter_entry_points + +from .config import Configuration +from .utils import iter_entry_points from .utils import trace -def iter_matching_entrypoints(path, entrypoint): - trace("looking for ep", entrypoint, path) - for ep in iter_entry_points(entrypoint): - if os.path.exists(os.path.join(path, ep.name)): - if os.path.isabs(ep.name): - trace("ignoring bad ep", ep) - trace("found ep", ep) - yield ep +def walk_potential_roots(root, search_parents=True): + """ + Iterate though a path and each of its parents. + :param root: File path. + :param search_parents: If ``False`` the parents are not considered. + """ + + if not search_parents: + yield root + return + + tail = root + + while tail: + yield root + root, tail = os.path.split(root) + + +def match_entrypoint(root, name): + """ + Consider a ``root`` as entry-point. + :param root: File path. + :param name: Subdirectory name. + :return: ``True`` if a subdirectory ``name`` exits in ``root``. + """ + + if os.path.exists(os.path.join(root, name)): + if not os.path.isabs(name): + return True + trace("ignoring bad ep", name) + + return False + + +def iter_matching_entrypoints(root, entrypoint, config: Configuration): + """ + Consider different entry-points in ``root`` and optionally its parents. + :param root: File path. + :param entrypoint: Entry-point to consider. + :param config: Configuration, + read ``search_parent_directories``, write found parent to ``parent``. + """ + + trace("looking for ep", entrypoint, root) + + for wd in walk_potential_roots(root, config.search_parent_directories): + for ep in iter_entry_points(entrypoint): + if match_entrypoint(wd, ep.name): + trace("found ep", ep, "in", wd) + config.parent = wd + yield ep
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/file_finder.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/file_finder.py
Changed
@@ -1,4 +1,5 @@ import os + from .utils import trace @@ -57,7 +58,7 @@ def is_toplevel_acceptable(toplevel): - "" + """ """ if toplevel is None: return False
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/file_finder_git.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/file_finder_git.py
Changed
@@ -1,9 +1,11 @@ +import logging import os import subprocess import tarfile -import logging -from .file_finder import scm_find_files + from .file_finder import is_toplevel_acceptable +from .file_finder import scm_find_files +from .utils import do_ex from .utils import trace log = logging.getLogger(__name__) @@ -12,13 +14,17 @@ def _git_toplevel(path): try: cwd = os.path.abspath(path or ".") - with open(os.devnull, "wb") as devnull: - out = subprocess.check_output( - "git", "rev-parse", "--show-prefix", - cwd=cwd, - universal_newlines=True, - stderr=devnull, - ) + out, err, ret = do_ex("git", "rev-parse", "HEAD", cwd=cwd) + if ret != 0: + # BAIL if there is no commit + log.error("listing git files failed - pretending there aren't any") + return None + out, err, ret = do_ex( + "git", "rev-parse", "--show-prefix", + cwd=cwd, + ) + if ret != 0: + return None out = out.strip():-1 # remove the trailing pathsep if not out: out = cwd @@ -27,7 +33,7 @@ # ``cwd`` is absolute path to current working directory. # the below method removes the length of ``out`` from # ``cwd``, which gives the git toplevel - assert cwd.replace("\\", "/").endswith(out) + assert cwd.replace("\\", "/").endswith(out), f"cwd={cwd!r}\nout={out!r}" # In windows cwd contains ``\`` which should be replaced by ``/`` # for this assertion to work. Length of string isn't changed by replace # ``\\`` is just and escape for `\` @@ -58,8 +64,11 @@ def _git_ls_files_and_dirs(toplevel): # use git archive instead of git ls-file to honor # export-ignore git attribute + cmd = "git", "archive", "--prefix", toplevel + os.path.sep, "HEAD" - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=toplevel) + proc = subprocess.Popen( + cmd, stdout=subprocess.PIPE, cwd=toplevel, stderr=subprocess.DEVNULL + ) try: try: return _git_interpret_archive(proc.stdout, toplevel) @@ -69,7 +78,7 @@ proc.terminate() except Exception: if proc.wait() != 0: - log.exception("listing git files failed - pretending there aren't any") + log.error("listing git files failed - pretending there aren't any") return (), ()
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/file_finder_hg.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/file_finder_hg.py
Changed
@@ -1,8 +1,9 @@ import os import subprocess -from .file_finder import scm_find_files from .file_finder import is_toplevel_acceptable +from .file_finder import scm_find_files +from .utils import do_ex def _hg_toplevel(path): @@ -26,9 +27,9 @@ def _hg_ls_files_and_dirs(toplevel): hg_files = set() hg_dirs = {toplevel} - out = subprocess.check_output( - "hg", "files", cwd=toplevel, universal_newlines=True - ) + out, err, ret = do_ex("hg", "files", cwd=toplevel) + if ret: + (), () for name in out.splitlines(): name = os.path.normcase(name).replace("/", os.path.sep) fullname = os.path.join(toplevel, name)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/git.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/git.py
Changed
@@ -1,29 +1,40 @@ -from .config import Configuration -from .utils import do_ex, trace, require_command -from .version import meta -from datetime import datetime, date import os -from os.path import isfile, join import warnings - - +from datetime import date +from datetime import datetime +from os.path import isfile +from os.path import join from os.path import samefile +from .config import Configuration +from .scm_workdir import Workdir +from .utils import do_ex +from .utils import require_command +from .utils import trace +from .version import meta -DEFAULT_DESCRIBE = "git describe --dirty --tags --long --match *0-9*" - - -class GitWorkdir: +# If testing command in shell make sure to quote the match argument like +# '*0-9*' as it will expand before being sent to git if there are any matching +# files in current directory. +DEFAULT_DESCRIBE = + "git", + "describe", + "--dirty", + "--tags", + "--long", + "--match", + "*0-9*", + + + +class GitWorkdir(Workdir): """experimental, may change at any time""" - def __init__(self, path): - self.path = path - - def do_ex(self, cmd): - return do_ex(cmd, cwd=self.path) + COMMAND = "git" @classmethod def from_potential_worktree(cls, wd): + require_command(cls.COMMAND) wd = os.path.abspath(wd) real_wd, _, ret = do_ex("git rev-parse --show-prefix", wd) real_wd = real_wd:-1 # remove the trailing pathsep @@ -51,16 +62,22 @@ branch, err, ret = self.do_ex("git rev-parse --abbrev-ref HEAD") if ret: trace("branch err", branch, err, ret) - return + branch, err, ret = self.do_ex("git symbolic-ref --short HEAD") + if ret: + trace("branch err (symbolic-ref)", branch, err, ret) + branch = None return branch def get_head_date(self): timestamp, err, ret = self.do_ex("git log -n 1 HEAD --format=%cI") if ret: - trace("branch err", timestamp, err, ret) + trace("timestamp err", timestamp, err, ret) return # TODO, when dropping python3.6 use fromiso date_part = timestamp.split("T")0 + if "%c" in date_part: + trace("git too old -> timestamp is ", timestamp) + return None return datetime.strptime(date_part, r"%Y-%m-%d").date() def is_shallow(self): @@ -70,14 +87,17 @@ self.do_ex("git fetch --unshallow") def node(self): - rev_node, _, ret = self.do_ex("git rev-parse --verify --quiet HEAD") + node, _, ret = self.do_ex("git rev-parse --verify --quiet HEAD") if not ret: - return rev_node:7 + return node:7 def count_all_nodes(self): revs, _, _ = self.do_ex("git rev-list HEAD") return revs.count("\n") + 1 + def default_describe(self): + return self.do_ex(DEFAULT_DESCRIBE) + def warn_on_shallow(wd): """experimental, may change at any time""" @@ -88,7 +108,7 @@ def fetch_on_shallow(wd): """experimental, may change at any time""" if wd.is_shallow(): - warnings.warn('"%s" was shallow, git fetch was used to rectify') + warnings.warn(f'"{wd.path}" was shallow, git fetch was used to rectify') wd.fetch_shallow() @@ -96,85 +116,77 @@ """experimental, may change at any time""" if wd.is_shallow(): raise ValueError( - "%r is shallow, please correct with " '"git fetch --unshallow"' % wd.path + f'{wd.path} is shallow, please correct with "git fetch --unshallow"' ) -def parse( - root, describe_command=DEFAULT_DESCRIBE, pre_parse=warn_on_shallow, config=None -): +def get_working_directory(config): + """ + Return the working directory (``GitWorkdir``). + """ + + if config.parent: + return GitWorkdir.from_potential_worktree(config.parent) + + if config.search_parent_directories: + return search_parent(config.absolute_root) + + return GitWorkdir.from_potential_worktree(config.absolute_root) + + +def parse(root, describe_command=None, pre_parse=warn_on_shallow, config=None): """ :param pre_parse: experimental pre_parse action, may change at any time """ if not config: config = Configuration(root=root) - require_command("git") + wd = get_working_directory(config) + if wd: + return _git_parse_inner( + config, wd, describe_command=describe_command, pre_parse=pre_parse + ) - wd = GitWorkdir.from_potential_worktree(config.absolute_root) - if wd is None: - return + +def _git_parse_inner(config, wd, pre_parse=None, describe_command=None): if pre_parse: pre_parse(wd) - if config.git_describe_command: + if config.git_describe_command is not None: describe_command = config.git_describe_command - out, unused_err, ret = wd.do_ex(describe_command) - node_date = wd.get_head_date() or date.today() + if describe_command is not None: + out, _, ret = wd.do_ex(describe_command) + else: + out, _, ret = wd.default_describe() - if ret: + if ret == 0: + tag, distance, node, dirty = _git_parse_describe(out) + if distance == 0 and not dirty: + distance = None + else: # If 'git git_describe_command' failed, try to get the information otherwise. - branch, branch_err, branch_ret = wd.do_ex("git symbolic-ref --short HEAD") - - if branch_ret: - branch = None - - rev_node = wd.node() + tag = "0.0" + node = wd.node() + if node is None: + distance = 0 + else: + distance = wd.count_all_nodes() + node = "g" + node dirty = wd.is_dirty() - if rev_node is None: - return meta( - "0.0", - distance=0, - node_date=node_date, - dirty=dirty, - branch=branch, - config=config,
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/hacks.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/hacks.py
Changed
@@ -1,6 +1,9 @@ import os -from .utils import data_from_mime, trace -from .version import tag_to_version, meta + +from .utils import data_from_mime +from .utils import trace +from .version import meta +from .version import tag_to_version def parse_pkginfo(root, config=None): @@ -34,4 +37,5 @@ if version is not None: return meta(str(version), preformatted=True, config=config) if config.fallback_version is not None: + trace("FALLBACK") return meta(config.fallback_version, preformatted=True, config=config)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/hg.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/hg.py
Changed
@@ -1,94 +1,151 @@ import os +from pathlib import Path + from .config import Configuration -from .utils import do, trace, data_from_mime, require_command -from .version import meta, tags_to_versions - - -def _hg_tagdist_normalize_tagcommit(config, tag, dist, node, branch): - dirty = node.endswith("+") - node = "h" + node.strip("+") - - # Detect changes since the specified tag - revset = ( - "(branch(.)" # look for revisions in this branch only - " and tag({tag!r})::." # after the last tag - # ignore commits that only modify .hgtags and nothing else: - " and (merge() or file('re:^(?!\\.hgtags).*$'))" - " and not tag({tag!r}))" # ignore the tagged commit itself - ).format(tag=tag) - if tag != "0.0": - commits = do( - "hg", "log", "-r", revset, "--template", "{node|short}", - config.absolute_root, - ) - else: - commits = True - trace("normalize", locals()) - if commits or dirty: - return meta( - tag, distance=dist, node=node, dirty=dirty, branch=branch, config=config +from .scm_workdir import Workdir +from .utils import data_from_mime +from .utils import do_ex +from .utils import require_command +from .utils import trace +from .version import meta +from .version import tag_to_version + + +class HgWorkdir(Workdir): + + COMMAND = "hg" + + @classmethod + def from_potential_worktree(cls, wd): + require_command(cls.COMMAND) + root, err, ret = do_ex("hg root", wd) + if ret: + return + return cls(root) + + def get_meta(self, config): + + node, tags, bookmark, node_date = self.hg_log( + ".", "{node}\n{tag}\n{bookmark}\n{date|shortdate}" + ).split("\n") + + # TODO: support bookmarks and topics (but nowadays bookmarks are + # mainly used to emulate Git branches, which is already supported with + # the dedicated class GitWorkdirHgClient) + + branch, dirty, dirty_date = self.do( + "hg", "id", "-T", "{branch}\n{if(dirty, 1, 0)}\n{date|shortdate}" + ).split("\n") + dirty = bool(int(dirty)) + + if dirty: + date = dirty_date + else: + date = node_date + + if all(c == "0" for c in node): + trace("initial node", self.path) + return meta("0.0", config=config, dirty=dirty, branch=branch) + + node = "h" + node:7 + + tags = tags.split() + if "tip" in tags: + # tip is not a real tag + tags = tags.remove("tip") + + if tags: + tag = tags0 + tag = tag_to_version(tag) + if tag: + return meta(tag, dirty=dirty, branch=branch, config=config) + + try: + tag = self.get_latest_normalizable_tag() + dist = self.get_distance_revs(tag) + if tag == "null": + tag = "0.0" + dist = int(dist) + 1 + + if self.check_changes_since_tag(tag) or dirty: + return meta( + tag, + distance=dist, + node=node, + dirty=dirty, + branch=branch, + config=config, + node_date=date, + ) + else: + return meta(tag, config=config) + + except ValueError: + pass # unpacking failed, old hg + + def hg_log(self, revset, template): + cmd = "hg", "log", "-r", revset, "-T", template + return self.do(cmd) + + def get_latest_normalizable_tag(self): + # Gets all tags containing a '.' (see #229) from oldest to newest + outlines = self.hg_log( + revset="ancestors(.) and tag('re:\\.')", + template="{tags}{if(tags, '\n', '')}", + ).split() + if not outlines: + return "null" + tag = outlines-1.split()-1 + return tag + + def get_distance_revs(self, rev1, rev2="."): + revset = f"({rev1}::{rev2})" + out = self.hg_log(revset, ".") + return len(out) - 1 + + def check_changes_since_tag(self, tag): + + if tag == "0.0": + return True + + revset = ( + "(branch(.)" # look for revisions in this branch only + f" and tag({tag!r})::." # after the last tag + # ignore commits that only modify .hgtags and nothing else: + " and (merge() or file('re:^(?!\\.hgtags).*$'))" + f" and not tag({tag!r}))" # ignore the tagged commit itself ) - else: - return meta(tag, config=config) + + return bool(self.hg_log(revset, ".")) def parse(root, config=None): if not config: config = Configuration(root=root) - require_command("hg") - identity_data = do("hg id -i -b -t", config.absolute_root).split() - if not identity_data: + if os.path.exists(os.path.join(root, ".hg/git")): + paths, _, ret = do_ex("hg path", root) + if not ret: + for line in paths.split("\n"): + if line.startswith("default ="): + path = Path(line.split()2) + if path.name.endswith(".git") or (path / ".git").exists(): + from .git import _git_parse_inner + from .hg_git import GitWorkdirHgClient + + wd = GitWorkdirHgClient.from_potential_worktree(root) + if wd: + return _git_parse_inner(config, wd) + + wd = HgWorkdir.from_potential_worktree(config.absolute_root) + + if wd is None: return - node = identity_data.pop(0) - branch = identity_data.pop(0) - if "tip" in identity_data: - # tip is not a real tag - identity_data.remove("tip") - tags = tags_to_versions(identity_data) - dirty = node-1 == "+" - if tags: - return meta(tags0, dirty=dirty, branch=branch, config=config) - - if node.strip("+") == "0" * 12: - trace("initial node", config.absolute_root) - return meta("0.0", config=config, dirty=dirty, branch=branch) - - try: - tag = get_latest_normalizable_tag(config.absolute_root) - dist = get_graph_distance(config.absolute_root, tag) - if tag == "null": - tag = "0.0" - dist = int(dist) + 1 - return _hg_tagdist_normalize_tagcommit(config, tag, dist, node, branch) - except ValueError: - pass # unpacking failed, old hg -
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/hg_git.py
Added
@@ -0,0 +1,133 @@ +import os +from datetime import datetime + +from .git import GitWorkdir +from .hg import HgWorkdir +from .utils import do_ex +from .utils import require_command +from .utils import trace + + +class GitWorkdirHgClient(GitWorkdir, HgWorkdir): + COMMAND = "hg" + + @classmethod + def from_potential_worktree(cls, wd): + require_command(cls.COMMAND) + root, err, ret = do_ex("hg root", wd) + if ret: + return + return cls(root) + + def is_dirty(self): + out, _, _ = self.do_ex("hg id -T '{dirty}'") + return bool(out) + + def get_branch(self): + branch, err, ret = self.do_ex("hg id -T {bookmarks}") + if ret: + trace("branch err", branch, err, ret) + return + return branch + + def get_head_date(self): + date_part, err, ret = self.do_ex("hg log -r . -T {shortdate(date)}") + if ret: + trace("head date err", date_part, err, ret) + return + return datetime.strptime(date_part, r"%Y-%m-%d").date() + + def is_shallow(self): + return False + + def fetch_shallow(self): + pass + + def get_hg_node(self): + node, _, ret = self.do_ex("hg log -r . -T {node}") + if not ret: + return node + + def _hg2git(self, hg_node): + git_node = None + with open(os.path.join(self.path, ".hg/git-mapfile")) as file: + for line in file: + if hg_node in line: + git_node, hg_node = line.split() + break + return git_node + + def node(self): + hg_node = self.get_hg_node() + if hg_node is None: + return + + git_node = self._hg2git(hg_node) + + if git_node is None: + # trying again after hg -> git + self.do_ex("hg gexport") + git_node = self._hg2git(hg_node) + + if git_node is None: + trace("Cannot get git node so we use hg node", hg_node) + + if hg_node == "0" * len(hg_node): + # mimic Git behavior + return None + + return hg_node + + return git_node:7 + + def count_all_nodes(self): + revs, _, _ = self.do_ex("hg log -r 'ancestors(.)' -T '.'") + return len(revs) + + def default_describe(self): + """ + Tentative to reproduce the output of + + `git describe --dirty --tags --long --match *0-9*` + + """ + hg_tags, _, ret = self.do_ex( + + "hg", + "log", + "-r", + "(reverse(ancestors(.)) and tag(r're:0-9'))", + "-T", + "{tags}{if(tags, ' ', '')}", + + ) + if ret: + return None, None, None + hg_tags = hg_tags.split() + + if not hg_tags: + return None, None, None + + git_tags = {} + with open(os.path.join(self.path, ".hg/git-tags")) as file: + for line in file: + node, tag = line.split() + git_tagstag = node + + # find the first hg tag which is also a git tag + for tag in hg_tags: + if tag in git_tags: + break + + out, _, ret = self.do_ex("hg", "log", "-r", f"'{tag}'::.", "-T", ".") + if ret: + return None, None, None + distance = len(out) - 1 + + node = self.node() + desc = f"{tag}-{distance}-g{node}" + + if self.is_dirty(): + desc += "-dirty" + + return desc, None, 0
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/integration.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/integration.py
Changed
@@ -1,10 +1,59 @@ -from pkg_resources import iter_entry_points +import os +import warnings -from .utils import do, trace_exception, trace -from . import _get_version, Configuration +import setuptools +from . import _get_version +from . import _version_missing +from .config import _read_dist_name_from_setup_cfg +from .config import Configuration +from .utils import do +from .utils import iter_entry_points +from .utils import trace -def version_keyword(dist, keyword, value): + +def _warn_on_old_setuptools(_version=setuptools.__version__): + if int(_version.split(".")0) < 45: + warnings.warn( + RuntimeWarning( + f""" +ERROR: setuptools=={_version} is used in combination with setuptools_scm>=6.x + +Your build configuration is incomplete and previously worked by accident! + + +This happens as setuptools is unable to replace itself when a activated build dependency +requires a more recent setuptools version +(it does not respect "setuptools>X" in setup_requires). + + +setuptools>=31 is required for setup.cfg metadata support +setuptools>=42 is required for pyproject.toml configuration support + +Suggested workarounds if applicable: + - preinstalling build dependencies like setuptools_scm before running setup.py + - installing setuptools_scm using the system package manager to ensure consistency + - migrating from the deprecated setup_requires mechanism to pep517/518 + and using a pyproject.toml to declare build dependencies + which are reliably pre-installed before running the build tools +""" + ) + ) + + +_warn_on_old_setuptools() + + +def _assign_version(dist: setuptools.Distribution, config: Configuration): + maybe_version = _get_version(config) + + if maybe_version is None: + _version_missing(config) + else: + dist.metadata.version = maybe_version + + +def version_keyword(dist: setuptools.Distribution, keyword, value): if not value: return if value is True: @@ -19,9 +68,11 @@ "version keyword", vars(dist.metadata), ) - dist_name = dist.metadata.name + dist_name = dist.metadata.name # type: str | None + if dist_name is None: + dist_name = _read_dist_name_from_setup_cfg() config = Configuration(dist_name=dist_name, **value) - dist.metadata.version = _get_version(config) + _assign_version(dist, config) def find_files(path=""): @@ -37,23 +88,17 @@ return -def _args_from_toml(name="pyproject.toml"): - # todo: more sensible config initialization - # move this helper back to config and unify it with the code from get_config - - with open(name) as strm: - defn = __import__("toml").load(strm) - return defn.get("tool", {})"setuptools_scm" - - -def infer_version(dist): +def infer_version(dist: setuptools.Distribution): trace( "finalize hook", vars(dist.metadata), ) dist_name = dist.metadata.name + if not os.path.isfile("pyproject.toml"): + return try: config = Configuration.from_file(dist_name=dist_name) - except Exception: - return trace_exception() - dist.metadata.version = _get_version(config) + except LookupError as e: + trace(e) + else: + _assign_version(dist, config)
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/scm_workdir.py
Added
@@ -0,0 +1,15 @@ +from .utils import do +from .utils import do_ex +from .utils import require_command + + +class Workdir: + def __init__(self, path): + require_command(self.COMMAND) + self.path = path + + def do_ex(self, cmd): + return do_ex(cmd, cwd=self.path) + + def do(self, cmd): + return do(cmd, cwd=self.path)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/utils.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/utils.py
Changed
@@ -2,13 +2,12 @@ utils """ import inspect -import warnings -import sys -import shlex -import subprocess import os import platform -import traceback +import shlex +import subprocess +import sys +import warnings DEBUG = bool(os.environ.get("SETUPTOOLS_SCM_DEBUG")) @@ -36,14 +35,9 @@ } -def trace(*k): +def trace(*k) -> None: if DEBUG: - print(*k) - sys.stdout.flush() - - -def trace_exception(): - DEBUG and traceback.print_exc() + print(*k, file=sys.stderr, flush=True) def ensure_stripped_str(str_or_bytes): @@ -84,6 +78,7 @@ def do_ex(cmd, cwd="."): trace("cmd", repr(cmd)) + trace(" in", cwd) if os.name == "posix" and not isinstance(cmd, (list, tuple)): cmd = shlex.split(cmd) @@ -123,7 +118,7 @@ return argname in argspec -def has_command(name, warn=True): +def has_command(name: str, warn: bool = True) -> bool: try: p = _popen_pipes(name, "help", ".") except OSError: @@ -140,3 +135,10 @@ def require_command(name): if not has_command(name, warn=False): raise OSError("%r was not found" % name) + + +def iter_entry_points(*k, **kw): + + from ._entrypoints import iter_entry_points + + return iter_entry_points(*k, **kw)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/src/setuptools_scm/version.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/src/setuptools_scm/version.py
Changed
@@ -1,21 +1,19 @@ -import datetime -import warnings -import re -import time import os +import re +import warnings +from datetime import datetime +from datetime import timezone +from typing import Callable +from typing import Iterator +from typing import List +from typing import overload +from typing import Tuple from .config import Configuration +from .config import Version as PkgVersion +from .utils import iter_entry_points from .utils import trace -try: - from packaging.version import Version -except ImportError: - import pkg_resources - - Version = pkg_resources.packaging.version.Version - - -from pkg_resources import iter_entry_points SEMVER_MINOR = 2 SEMVER_PATCH = 3 @@ -23,7 +21,7 @@ def _parse_version_tag(tag, config): - tagstring = tag if not isinstance(tag, str) else str(tag) + tagstring = tag if isinstance(tag, str) else str(tag) match = config.tag_regex.match(tagstring) result = None @@ -54,7 +52,7 @@ return ep.load() -def tag_to_version(tag, config=None): +def tag_to_version(tag, config: "Configuration | None" = None): """ take a tag that might be prefixed with a keyword and return only the version part :param config: optional configuration object @@ -79,7 +77,7 @@ ) ) - version = Version(version) + version = config.version_cls(version) trace("version", repr(version)) return version @@ -102,13 +100,13 @@ class ScmVersion: def __init__( self, - tag_version, - distance=None, - node=None, - dirty=False, - preformatted=False, - branch=None, - config=None, + tag_version: str, + distance: "int|None" = None, + node: "str|None" = None, + dirty: bool = False, + preformatted: bool = False, + branch: "str|None" = None, + config: "Configuration|None" = None, node_date=None, **kw, ): @@ -120,9 +118,11 @@ self.distance = distance self.node = node self.node_date = node_date - self.time = datetime.datetime.utcfromtimestamp( - int(os.environ.get("SOURCE_DATE_EPOCH", time.time())) - ) + if "SOURCE_DATE_EPOCH" in os.environ: + date_epoch = int(os.environ"SOURCE_DATE_EPOCH") + self.time = datetime.fromtimestamp(date_epoch, timezone.utc) + else: + self.time = datetime.now(timezone.utc) self._extra = kw self.dirty = dirty self.preformatted = preformatted @@ -167,24 +167,24 @@ return self.format_with(fmt, guessed=guessed) -def _parse_tag(tag, preformatted, config): +def _parse_tag(tag, preformatted, config: "Configuration|None"): if preformatted: return tag - if not isinstance(tag, Version): + if config is None or not isinstance(tag, config.version_cls): tag = tag_to_version(tag, config) return tag def meta( tag, - distance=None, - dirty=False, - node=None, - preformatted=False, - branch=None, - config=None, + distance: "int|None" = None, + dirty: bool = False, + node: "str|None" = None, + preformatted: bool = False, + branch: "str|None" = None, + config: "Configuration|None" = None, **kw, -): +) -> ScmVersion: if not config: warnings.warn( "meta invoked without explicit configuration," @@ -198,32 +198,45 @@ ) -def guess_next_version(tag_version): +def guess_next_version(tag_version: ScmVersion): version = _strip_local(str(tag_version)) return _bump_dev(version) or _bump_regex(version) -def _strip_local(version_string): +def _dont_guess_next_version(tag_version: ScmVersion): + version = _strip_local(str(tag_version)) + return _bump_dev(version) or _add_post(version) + + +def _strip_local(version_string: str) -> str: public, sep, local = version_string.partition("+") return public -def _bump_dev(version): +def _add_post(version: str): + if "post" in version: + raise ValueError( + f"{version} already is a post release, refusing to guess the update" + ) + return f"{version}.post1" + + +def _bump_dev(version: str) -> "str | None": if ".dev" not in version: - return + return None prefix, tail = version.rsplit(".dev", 1) if tail != "0": raise ValueError( "choosing custom numbers for the `.devX` distance " "is not supported.\n " - "The {version} can't be bumped\n" - "Please drop the tag or create a new supported one".format(version=version) + f"The {version} can't be bumped\n" + "Please drop the tag or create a new supported one ending in .dev0" ) return prefix -def _bump_regex(version): +def _bump_regex(version: str) -> str: match = re.match(r"(.*?)(\d+)$", version) if match is None: raise ValueError( @@ -235,14 +248,14 @@ return "%s%d" % (prefix, int(tail) + 1) -def guess_next_dev_version(version): +def guess_next_dev_version(version: ScmVersion): if version.exact: return version.format_with("{tag}") else: return version.format_next_version(guess_next_version) -def guess_next_simple_semver(version, retain, increment=True): +def guess_next_simple_semver(version: str, retain: int, increment=True): try: parts = int(i) for i in str(version).split("."):retain except ValueError:
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/Dockerfile.busted-buster
Added
@@ -0,0 +1,3 @@ +FROM debian:buster +RUN apt-get update -q && apt-get install -yq python3-pip python3-setuptools +RUN printf "easy_install\nallow_hosts=localhost\nfind_links=/dist\n" > /root/.pydistutils.cfg
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/check_self_install.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/check_self_install.py
Changed
@@ -1,4 +1,5 @@ import pkg_resources + import setuptools_scm dist = pkg_resources.get_distribution("setuptools_scm")
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/conftest.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/conftest.py
Changed
@@ -1,5 +1,6 @@ -import os import itertools +import os + import pytest # 2009-02-13T23:31:30+00:00 @@ -19,6 +20,13 @@ return res +def pytest_addoption(parser): + group = parser.getgroup("setuptools_scm") + group.addoption( + "--test-legacy", dest="scm_test_virtualenv", default=False, action="store_true" + ) + + class Wd: commit_command = None add_command = None @@ -49,7 +57,7 @@ def _reason(self, given_reason): if given_reason is None: - return "number-{c}".format(c=next(self.__counter)) + return f"number-{next(self.__counter)}" else: return given_reason @@ -95,3 +103,32 @@ target_wd = tmp_path.resolve() / "wd" target_wd.mkdir() return Wd(target_wd) + + +@pytest.fixture +def repositories_hg_git(tmp_path): + from setuptools_scm.utils import do + + tmp_path = tmp_path.resolve() + path_git = tmp_path / "repo_git" + path_git.mkdir() + + wd = Wd(path_git) + wd("git init") + wd("git config user.email test@example.com") + wd('git config user.name "a test"') + wd.add_command = "git add ." + wd.commit_command = "git commit -m test-{reason}" + + path_hg = tmp_path / "repo_hg" + do(f"hg clone {path_git} {path_hg} --config extensions.hggit=") + assert path_hg.exists() + + with open(path_hg / ".hg/hgrc", "a") as file: + file.write("extensions\nhggit =\n") + + wd_hg = Wd(path_hg) + wd_hg.add_command = "hg add ." + wd_hg.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"' + + return wd_hg, wd
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_basic_api.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_basic_api.py
Changed
@@ -1,18 +1,22 @@ import os +import shutil import sys -import py +from pathlib import Path + import pytest import setuptools_scm from setuptools_scm import dump_version -from setuptools_scm.utils import data_from_mime, do +from setuptools_scm.utils import data_from_mime +from setuptools_scm.utils import do +from setuptools_scm.version import ScmVersion @pytest.mark.parametrize("cmd", "ls", "dir") -def test_do(cmd, tmpdir): - if not py.path.local.sysfind(cmd): +def test_do(cmd, tmp_path: Path): + if not shutil.which(cmd): pytest.skip(cmd + " not found") - do(cmd, str(tmpdir)) + do(cmd, cwd=tmp_path) def test_data_from_mime(tmpdir): @@ -39,6 +43,7 @@ def assertion(config): assert config.absolute_root == expected_root + return ScmVersion("1.0") monkeypatch.setattr(setuptools_scm, "_do_parse", assertion) @@ -53,9 +58,12 @@ setuptools_scm.version_from_scm(str(wd)) -def test_root_parameter_pass_by(monkeypatch, tmpdir): - assert_root(monkeypatch, tmpdir) - setuptools_scm.get_version(root=tmpdir.strpath) +def test_root_parameter_pass_by(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): + assert_root(monkeypatch, os.fspath(tmp_path)) + setuptools_scm.get_version(root=os.fspath(tmp_path)) + setuptools_scm.get_version( + os.fspath(tmp_path) + ) # issue 669 - posarg difference between Configuration and get_version def test_parentdir_prefix(tmpdir, monkeypatch): @@ -90,31 +98,51 @@ assert setuptools_scm.get_version() == version -def test_root_relative_to(monkeypatch, tmp_path): +def test_root_relative_to(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): + tmp_path.joinpath("setup.cfg").touch() assert_root(monkeypatch, str(tmp_path / "alt")) module = tmp_path / "module/file.py" module.parent.mkdir() module.touch() - setuptools_scm.get_version(root="../alt", relative_to=str(module)) + + setuptools_scm.get_version( + root="../alt", + relative_to=str(module), + ) with pytest.warns(UserWarning, match="relative_to is expected to be a file.*"): - setuptools_scm.get_version(root="../alt", relative_to=str(module.parent)) + setuptools_scm.get_version( + root="../alt", + relative_to=str(module.parent), + ) + +def test_dump_version(tmp_path: Path): -def test_dump_version(tmpdir): - sp = tmpdir.strpath + dump_version(tmp_path, "1.0", "first.txt") - dump_version(sp, "1.0", "first.txt") - assert tmpdir.join("first.txt").read() == "1.0" + def read(name: str) -> str: + return tmp_path.joinpath(name).read_text() - dump_version(sp, "1.0.dev42", "first.py") - content = tmpdir.join("first.py").read() - lines = content.splitlines() + assert read("first.txt") == "1.0" + + dump_version(tmp_path, "1.0.dev42", "first.py") + lines = read("first.py").splitlines() assert "version = '1.0.dev42'" in lines assert "version_tuple = (1, 0, 'dev42')" in lines + dump_version(tmp_path, "1.0.1+g4ac9d2c", "second.py") + lines = read("second.py").splitlines() + assert "version = '1.0.1+g4ac9d2c'" in lines + assert "version_tuple = (1, 0, 1, 'g4ac9d2c')" in lines + + dump_version(tmp_path, "1.2.3.dev18+gb366d8b.d20210415", "third.py") + lines = read("third.py").splitlines() + assert "version = '1.2.3.dev18+gb366d8b.d20210415'" in lines + assert "version_tuple = (1, 2, 3, 'dev18', 'gb366d8b.d20210415')" in lines + import ast - ast.parse(content) + ast.parse(read("third.py")) def test_parse_plain_fails(recwarn): @@ -123,3 +151,24 @@ with pytest.raises(TypeError): setuptools_scm.get_version(parse=parse) + + +def test_custom_version_cls(): + """Test that `normalize` and `version_cls` work as expected""" + + class MyVersion: + def __init__(self, tag_str: str): + self.version = tag_str + + def __repr__(self): + return f"hello,{self.version}" + + # you can not use normalize=False and version_cls at the same time + with pytest.raises(ValueError): + setuptools_scm.get_version(normalize=False, version_cls=MyVersion) + + # TODO unfortunately with PRETEND_KEY the preformatted flag becomes True + # which bypasses our class. which other mechanism would be ok to use here + # to create a test? + # monkeypatch.setenv(setuptools_scm.PRETEND_KEY, "1.0.1") + # assert setuptools_scm.get_version(version_cls=MyVersion) == "1"
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_config.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_config.py
Changed
@@ -1,7 +1,10 @@ -from setuptools_scm.config import Configuration import re +import textwrap + import pytest +from setuptools_scm.config import Configuration + @pytest.mark.parametrize( "tag, expected_version", @@ -27,7 +30,17 @@ def test_config_from_pyproject(tmpdir): fn = tmpdir / "pyproject.toml" - fn.write_text("tool.setuptools_scm\n", encoding="utf-8") + fn.write_text( + textwrap.dedent( + """ + tool.setuptools_scm + project + description = "Factory ⸻ A code generator 🏭" + authors = {name = "Łukasz Langa"} + """ + ), + encoding="utf-8", + ) assert Configuration.from_file(str(fn))
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_file_finder.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_file_finder.py
Changed
@@ -31,7 +31,8 @@ bdir = wd.cwd / "bdir" bdir.mkdir() (bdir / "fileb").touch() - wd.add_and_commit() + if request.node.get_closest_marker("skip_commit") is None: + wd.add_and_commit() monkeypatch.chdir(wd.cwd) yield wd @@ -184,3 +185,9 @@ "data/datafile", } ) + + +@pytest.mark.issue(587) +@pytest.mark.skip_commit +def test_not_commited(inwd): + assert find_files() ==
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_functions.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_functions.py
Changed
@@ -1,15 +1,17 @@ -import pytest +from pathlib import Path + import pkg_resources -from setuptools_scm import dump_version, get_version, PRETEND_KEY -from setuptools_scm.version import ( - guess_next_version, - meta, - format_version, - tag_to_version, -) +import pytest +from setuptools_scm import dump_version +from setuptools_scm import get_version +from setuptools_scm import PRETEND_KEY from setuptools_scm.config import Configuration from setuptools_scm.utils import has_command +from setuptools_scm.version import format_version +from setuptools_scm.version import guess_next_version +from setuptools_scm.version import meta +from setuptools_scm.version import tag_to_version @pytest.mark.parametrize( @@ -61,27 +63,28 @@ assert format_version(version, version_scheme=vs, local_scheme=ls) == expected -def test_dump_version_doesnt_bail_on_value_error(tmpdir): +def test_dump_version_doesnt_bail_on_value_error(tmp_path): write_to = "VERSION" version = str(VERSIONS"exact".tag) - with pytest.raises(ValueError) as exc_info: - dump_version(tmpdir.strpath, version, write_to) - assert str(exc_info.value).startswith("bad file format:") + with pytest.raises(ValueError, match="^bad file format:"): + dump_version(tmp_path, version, write_to) @pytest.mark.parametrize( "version", "1.0", "1.2.3.dev1+ge871260", "1.2.3.dev15+ge871260.d20180625" ) -def test_dump_version_works_with_pretend(version, tmpdir, monkeypatch): +def test_dump_version_works_with_pretend( + version: str, tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: monkeypatch.setenv(PRETEND_KEY, version) - get_version(write_to=str(tmpdir.join("VERSION.txt"))) - assert tmpdir.join("VERSION.txt").read() == version + target = tmp_path.joinpath("VERSION.txt") + get_version(write_to=target) + assert target.read_text() == version -def test_has_command(recwarn): - assert not has_command("yadayada_setuptools_aint_ne") - msg = recwarn.pop() - assert "yadayada" in str(msg.message) +def test_has_command() -> None: + with pytest.warns(RuntimeWarning, match="yadayada"): + assert not has_command("yadayada_setuptools_aint_ne") @pytest.mark.parametrize( @@ -92,6 +95,6 @@ pytest.param("3.3.1-rc26", "3.3.1rc26", marks=pytest.mark.issue(266)), , ) -def test_tag_to_version(tag, expected_version): +def test_tag_to_version(tag: str, expected_version: str) -> None: version = str(tag_to_version(tag)) assert version == expected_version
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_git.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_git.py
Changed
@@ -1,13 +1,20 @@ -import sys import os -from setuptools_scm import integration -from setuptools_scm.utils import do, has_command -from setuptools_scm import git -import pytest +import sys +from datetime import date from datetime import datetime +from datetime import timezone from os.path import join as opj +from unittest.mock import Mock +from unittest.mock import patch + +import pytest + +from setuptools_scm import git +from setuptools_scm import integration +from setuptools_scm import NonNormalizedVersion from setuptools_scm.file_finder_git import git_find_files -from datetime import date +from setuptools_scm.utils import do +from setuptools_scm.utils import has_command pytestmark = pytest.mark.skipif( @@ -52,6 +59,19 @@ assert res == "0.1.dev0" +def test_root_search_parent_directories(tmpdir, wd, monkeypatch): + monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") + p = wd.cwd.joinpath("sub/package") + p.mkdir(parents=True) + p.joinpath("setup.py").write_text( + """from setuptools import setup +setup(use_scm_version={"search_parent_directories": True}) +""" + ) + res = do((sys.executable, "setup.py", "--version"), p) + assert res == "0.1.dev0" + + def test_git_gone(wd, monkeypatch): monkeypatch.setenv("PATH", str(wd.cwd / "not-existing")) with pytest.raises(EnvironmentError, match="'git' was not found"): @@ -104,6 +124,70 @@ wd("git tag 17.33.0-rc") assert wd.version == "17.33.0rc0" + # custom normalization + assert wd.get_version(normalize=False) == "17.33.0-rc" + assert wd.get_version(version_cls=NonNormalizedVersion) == "17.33.0-rc" + assert ( + wd.get_version(version_cls="setuptools_scm.NonNormalizedVersion") + == "17.33.0-rc" + ) + + +@pytest.mark.parametrize("with_class", False, type, str) +def test_git_version_unnormalized_setuptools(with_class, tmpdir, wd, monkeypatch): + """ + Test that when integrating with setuptools without normalization, + the version is not normalized in write_to files, + but still normalized by setuptools for the final dist metadata. + """ + monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") + p = wd.cwd + + # create a setup.py + dest_file = str(tmpdir.join("VERSION.txt")).replace("\\", "/") + if with_class is False: + # try normalize = False + setup_py = """ +from setuptools import setup +setup(use_scm_version={'normalize': False, 'write_to': '%s'}) +""" + elif with_class is type: + # custom non-normalizing class + setup_py = """ +from setuptools import setup + +class MyVersion: + def __init__(self, tag_str: str): + self.version = tag_str + + def __repr__(self): + return self.version + +setup(use_scm_version={'version_cls': MyVersion, 'write_to': '%s'}) +""" + elif with_class is str: + # non-normalizing class referenced by name + setup_py = """from setuptools import setup +setup(use_scm_version={ + 'version_cls': 'setuptools_scm.NonNormalizedVersion', + 'write_to': '%s' +}) +""" + + # finally write the setup.py file + p.joinpath("setup.py").write_text(setup_py % dest_file) + + # do git operations and tag + wd.commit_testfile() + wd("git tag 17.33.0-rc1") + + # setuptools still normalizes using packaging.Version (removing the dash) + res = do((sys.executable, "setup.py", "--version"), p) + assert res == "17.33.0rc1" + + # but the version tag in the file is non-normalized (with the dash) + assert tmpdir.join("VERSION.txt").read() == "17.33.0-rc1" + @pytest.mark.issue(179) def test_unicode_version_scheme(wd): @@ -132,7 +216,7 @@ assert wd.version.startswith("0.1.dev1") if today: # the date on the tag is in UTC - tag = datetime.utcnow().date().strftime(".d%Y%m%d") + tag = datetime.now(timezone.utc).date().strftime(".d%Y%m%d") else: tag = ".d20090213" # we are dirty, check for the tag @@ -140,12 +224,14 @@ @pytest.mark.issue(193) -def test_git_worktree_support(wd, tmpdir): +@pytest.mark.xfail(reason="sometimes relative path results") +def test_git_worktree_support(wd, tmp_path): wd.commit_testfile() - worktree = tmpdir.join("work_tree") + worktree = tmp_path / "work_tree" wd("git worktree add -b work-tree %s" % worktree) res = do(sys.executable, "-m", "setuptools_scm", "ls", cwd=worktree) + assert "test.txt" in res assert str(worktree) in res @@ -216,7 +302,7 @@ @pytest.mark.issue(228) def test_git_archive_subdirectory(wd, monkeypatch): - wd("mkdir foobar") + os.mkdir(wd.cwd / "foobar") wd.write("foobar/test1.txt", "test") wd("git add foobar") wd.commit() @@ -226,7 +312,7 @@ @pytest.mark.issue(251) def test_git_archive_run_from_subdirectory(wd, monkeypatch): - wd("mkdir foobar") + os.mkdir(wd.cwd / "foobar") wd.write("foobar/test1.txt", "test") wd("git add foobar") wd.commit() @@ -284,7 +370,7 @@ @pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/381") def test_gitdir(monkeypatch, wd): - """""" + """ """ wd.commit_testfile() normal = wd.version # git hooks set this and break subsequent setuptools_scm unless we clean @@ -307,3 +393,12 @@ assert git_wd.get_head_date() == today meta = git.parse(os.fspath(wd.cwd)) assert meta.node_date == today + + +def test_git_getdate_badgit( + wd, +): + wd.commit_testfile() + git_wd = git.GitWorkdir(os.fspath(wd.cwd)) + with patch.object(git_wd, "do_ex", Mock(return_value=("%cI", "", 0))): + assert git_wd.get_head_date() is None
View file
_service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_hg_git.py
Added
@@ -0,0 +1,79 @@ +import pytest + +from setuptools_scm.utils import do_ex +from setuptools_scm.utils import has_command + + +@pytest.fixture(scope="module", autouse=True) +def _check_hg_git(): + if not has_command("hg", warn=False): + pytest.skip("hg executable not found") + + python_hg, err, ret = do_ex("hg debuginstall --template {pythonexe}") + + if ret: + skip_no_hggit = True + else: + out, err, ret = do_ex(python_hg.strip(), "-c", "import hggit") + skip_no_hggit = bool(ret) + if skip_no_hggit: + pytest.skip("hg-git not installed") + + +def test_base(repositories_hg_git): + wd, wd_git = repositories_hg_git + + assert wd_git.version == "0.1.dev0" + assert wd.version == "0.1.dev0" + + wd_git.commit_testfile() + wd("hg pull -u") + + version_git = wd_git.version + version = wd.version + + assert version_git.startswith("0.1.dev1+g") + assert version.startswith("0.1.dev1+g") + + assert not version_git.endswith("1-") + assert not version.endswith("1-") + + wd_git("git tag v0.1") + wd("hg pull -u") + assert wd_git.version == "0.1" + assert wd.version == "0.1" + + wd_git.write("test.txt", "test2") + wd.write("test.txt", "test2") + assert wd_git.version.startswith("0.2.dev0+g") + assert wd.version.startswith("0.2.dev0+g") + + wd_git.commit_testfile() + wd("hg pull") + wd("hg up -C") + assert wd_git.version.startswith("0.2.dev1+g") + assert wd.version.startswith("0.2.dev1+g") + + wd_git("git tag version-0.2") + wd("hg pull -u") + assert wd_git.version.startswith("0.2") + assert wd.version.startswith("0.2") + + wd_git.commit_testfile() + wd_git("git tag version-0.2.post210+gbe48adfpost3+g0cc25f2") + wd("hg pull -u") + with pytest.warns( + UserWarning, match="tag '.*' will be stripped of its suffix '.*'" + ): + assert wd_git.version.startswith("0.2") + + with pytest.warns( + UserWarning, match="tag '.*' will be stripped of its suffix '.*'" + ): + assert wd.version.startswith("0.2") + + wd_git.commit_testfile() + wd_git("git tag 17.33.0-rc") + wd("hg pull -u") + assert wd_git.version == "17.33.0rc0" + assert wd.version == "17.33.0rc0"
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_integration.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_integration.py
Changed
@@ -1,9 +1,13 @@ +import os import sys +import textwrap import pytest +from setuptools_scm import PRETEND_KEY +from setuptools_scm import PRETEND_KEY_NAMED +from setuptools_scm.integration import _warn_on_old_setuptools from setuptools_scm.utils import do -from setuptools_scm import PRETEND_KEY, PRETEND_KEY_NAMED @pytest.fixture @@ -20,40 +24,81 @@ pytest.importorskip("toml") monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") pkg = tmpdir.ensure("package", dir=42) - pkg.join("pyproject.toml").write( - """tool.setuptools_scm -fallback_version = "12.34" -""" + pkg.join("pyproject.toml").write_text( + textwrap.dedent( + """ + tool.setuptools_scm + fallback_version = "12.34" + project + description = "Factory ⸻ A code generator 🏭" + authors = {name = "Łukasz Langa"} + """ + ), + encoding="utf-8", ) pkg.join("setup.py").write("__import__('setuptools').setup()") res = do((sys.executable, "setup.py", "--version"), pkg) assert res == "12.34" -def test_pyproject_support_with_git(tmpdir, monkeypatch, wd): - pytest.importorskip("toml") - pkg = tmpdir.join("wd") - pkg.join("pyproject.toml").write("""tool.setuptools_scm""") - pkg.join("setup.py").write( - "__import__('setuptools').setup(name='setuptools_scm_example')" - ) - res = do((sys.executable, "setup.py", "--version"), pkg) +PYPROJECT_FILES = { + "setup.py": "tool.setuptools_scm", + "setup.cfg": "tool.setuptools_scm", + "pyproject tool.setuptools_scm": ( + "tool.setuptools_scm\ndist_name='setuptools_scm_example'" + ), + "pyproject.project": ( + "project\nname='setuptools_scm_example'\ntool.setuptools_scm" + ), +} + +SETUP_PY_PLAIN = "__import__('setuptools').setup()" +SETUP_PY_WITH_NAME = "__import__('setuptools').setup(name='setuptools_scm_example')" + +SETUP_PY_FILES = { + "setup.py": SETUP_PY_WITH_NAME, + "setup.cfg": SETUP_PY_PLAIN, + "pyproject tool.setuptools_scm": SETUP_PY_PLAIN, + "pyproject.project": SETUP_PY_PLAIN, +} + +SETUP_CFG_FILES = { + "setup.py": "", + "setup.cfg": "metadata\nname=setuptools_scm_example", + "pyproject tool.setuptools_scm": "", + "pyproject.project": "", +} + +with_metadata_in = pytest.mark.parametrize( + "metadata_in", + "setup.py", "setup.cfg", "pyproject tool.setuptools_scm", "pyproject.project", +) + + +@with_metadata_in +def test_pyproject_support_with_git(wd, metadata_in): + pytest.importorskip("tomli") + wd.write("pyproject.toml", PYPROJECT_FILESmetadata_in) + wd.write("setup.py", SETUP_PY_FILESmetadata_in) + wd.write("setup.cfg", SETUP_CFG_FILESmetadata_in) + res = wd((sys.executable, "setup.py", "--version")) assert res.endswith("0.1.dev0") -def test_pretend_version(tmpdir, monkeypatch, wd): +def test_pretend_version(monkeypatch, wd): monkeypatch.setenv(PRETEND_KEY, "1.0.0") assert wd.get_version() == "1.0.0" assert wd.get_version(dist_name="ignored") == "1.0.0" -def test_pretend_version_named_pyproject_integration(tmpdir, monkeypatch, wd): - test_pyproject_support_with_git(tmpdir, monkeypatch, wd) +@with_metadata_in +def test_pretend_version_named_pyproject_integration(monkeypatch, wd, metadata_in): + test_pyproject_support_with_git(wd, metadata_in) monkeypatch.setenv( PRETEND_KEY_NAMED.format(name="setuptools_scm_example".upper()), "3.2.1" ) - res = do((sys.executable, "setup.py", "--version"), tmpdir / "wd") + res = wd((sys.executable, "setup.py", "--version")) assert res.endswith("3.2.1") @@ -68,3 +113,40 @@ monkeypatch.setenv(PRETEND_KEY_NAMED.format(name="test".upper()), "1.0.0") monkeypatch.setenv(PRETEND_KEY, "2.0.0") assert wd.get_version(dist_name="test") == "1.0.0" + + +def test_pretend_version_accepts_bad_string(monkeypatch, wd): + monkeypatch.setenv(PRETEND_KEY, "dummy") + wd.write("setup.py", SETUP_PY_PLAIN) + assert wd.get_version(write_to="test.py") == "dummy" + assert wd("python setup.py --version") == "0.0.0" + + +def test_own_setup_fails_on_old_python(monkeypatch): + monkeypatch.setattr("sys.version_info", (3, 5)) + monkeypatch.syspath_prepend(os.path.dirname(os.path.dirname(__file__))) + + import setup + + with pytest.raises( + RuntimeError, + match="support for python < 3.6 has been removed in setuptools_scm>=6.0.0", + ): + setup.scm_version() + + +def testwarn_on_broken_setuptools(): + _warn_on_old_setuptools("45") + with pytest.warns(RuntimeWarning, match="ERROR: setuptools==44"): + _warn_on_old_setuptools("44") + + +@pytest.mark.issue(611) +def test_distribution_procides_extras(): + try: + from importlib.metadata import distribution + except ImportError: + from importlib_metadata import distribution + + dist = distribution("setuptools_scm") + assert sorted(dist.metadata.get_all("Provides-Extra")) == "test", "toml"
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_main.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_main.py
Changed
@@ -1,4 +1,8 @@ import os.path +import sys +import textwrap + +import pytest def test_main(): @@ -8,3 +12,51 @@ with open(mainfile) as f: code = compile(f.read(), "__main__.py", "exec") exec(code) + + +@pytest.fixture +def repo(wd): + wd("git init") + wd("git config user.email user@host") + wd("git config user.name user") + wd.add_command = "git add ." + wd.commit_command = "git commit -m test-{reason}" + + wd.write("README.rst", "My example") + wd.add_and_commit() + wd("git tag v0.1.0") + + wd.write("file.txt", "file.txt") + wd.add_and_commit() + + return wd + + +def test_repo_with_config(repo): + pyproject = """\ + tool.setuptools_scm + version_scheme = "no-guess-dev" + + project + name = "example" + """ + repo.write("pyproject.toml", textwrap.dedent(pyproject)) + repo.add_and_commit() + res = repo((sys.executable, "-m", "setuptools_scm")) + assert res.startswith("0.1.0.post1.dev2") + + +def test_repo_without_config(repo): + res = repo((sys.executable, "-m", "setuptools_scm")) + assert res.startswith("0.1.1.dev1") + + +def test_repo_with_pyproject_missing_setuptools_scm(repo): + pyproject = """\ + project + name = "example" + """ + repo.write("pyproject.toml", textwrap.dedent(pyproject)) + repo.add_and_commit() + res = repo((sys.executable, "-m", "setuptools_scm")) + assert res.startswith("0.1.1.dev2")
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_mercurial.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_mercurial.py
Changed
@@ -1,9 +1,11 @@ +import pytest + from setuptools_scm import format_version -from setuptools_scm.hg import archival_to_version, parse from setuptools_scm import integration from setuptools_scm.config import Configuration +from setuptools_scm.hg import archival_to_version +from setuptools_scm.hg import parse from setuptools_scm.utils import has_command -import pytest pytestmark = pytest.mark.skipif( @@ -80,7 +82,7 @@ wd("hg up v0.1") assert wd.version == "0.1" - # commit originating from the taged revision + # commit originating from the tagged revision # that is not a actual tag wd.commit_testfile() assert wd.version.startswith("0.2.dev1+") @@ -94,7 +96,7 @@ def test_version_from_archival(wd): # entrypoints are unordered, - # cleaning the wd ensure this test wont break randomly + # cleaning the wd ensure this test won't break randomly wd.cwd.joinpath(".hg").rename(wd.cwd / ".nothg") wd.write(".hg_archival.txt", "node: 000000000000\n" "tag: 0.1\n") assert wd.version == "0.1" @@ -170,14 +172,14 @@ @pytest.mark.usefixtures("version_1_0") def test_latest_tag_detection(wd): """Tests that tags not containing a "." are ignored, the same as for git. - Note that will be superceded by the fix for pypa/setuptools_scm/issues/235 + Note that will be superseded by the fix for pypa/setuptools_scm/issues/235 """ wd('hg tag some-random-tag -u test -d "0 0"') assert wd.version == "1.0.0" @pytest.mark.usefixtures("version_1_0") -def test_feature_branch_increments_major(wd): +def test_feature_branch_increments_major(wd) -> None: wd.commit_testfile() assert wd.get_version(version_scheme="python-simplified-semver").startswith("1.0.1")
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_regressions.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_regressions.py
Changed
@@ -1,11 +1,12 @@ -import sys import subprocess +import sys + +import pytest from setuptools_scm import get_version from setuptools_scm.git import parse -from setuptools_scm.utils import do_ex, do - -import pytest +from setuptools_scm.utils import do +from setuptools_scm.utils import do_ex def test_pkginfo_noscmroot(tmpdir, monkeypatch):
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_setuptools_support.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_setuptools_support.py
Changed
@@ -1,34 +1,83 @@ """ integration tests that check setuptools version support """ -import sys import os +import pathlib import subprocess +import sys + import pytest -@pytest.fixture(scope="session") -def get_setuptools_packagedir(request): - targets = request.config.cache.makedir("setuptools_installs") +def cli_run(*k, **kw): + """this defers the virtualenv import + it helps to avoid warnings from the furthermore imported setuptools + """ + global cli_run + from virtualenv.run import cli_run + + return cli_run(*k, **kw) + + +pytestmark = pytest.mark.filterwarnings( + r"ignore:.*tool\.setuptools_scm.*", r"always:.*setup.py install is deprecated.*" +) + + +ROOT = pathlib.Path(__file__).parent.parent + + +class Venv: + def __init__(self, location: pathlib.Path): + self.location = location - def makeinstall(version): - target = targets.ensure(version, dir=1) + @property + def python(self): + return self.location / "bin/python" + + +class VenvMaker: + def __init__(self, base: pathlib.Path): + self.base = base + + def __repr__(self): + return f"<VenvMaker base={self.base}>" + + def get_venv(self, python, pip, setuptools, prefix="scm"): + name = f"{prefix}-py={python}-pip={pip}-setuptools={setuptools}" + path = self.base / name + if not path.is_dir(): + cli_run( + + str(path), + "--python", + python, + "--pip", + pip, + "--setuptools", + setuptools, + , + setup_logging=False, + ) + venv = Venv(path) + subprocess.run(venv.python, "-m", "pip", "install", "-e", str(ROOT)) + # fixup pip + subprocess.check_call(venv.python, "-m", "pip", "install", f"pip=={pip}") subprocess.check_call( - - sys.executable, - "-m", - "pip", - "install", - "--no-binary", - "setuptools", - "setuptools==" + version, - "-t", - str(target), - + venv.python, "-m", "pip", "install", f"setuptools~={setuptools}" ) - return target + return venv - return makeinstall + +@pytest.fixture +def venv_maker(pytestconfig): + if not pytestconfig.getoption("--test-legacy"): + pytest.skip( + "testing on legacy setuptools disabled, pass --test-legacy to run them" + ) + dir = pytestconfig.cache.makedir("setuptools_scm_venvs") + path = pathlib.Path(str(dir)) + return VenvMaker(path) SCRIPT = """ @@ -42,19 +91,100 @@ """ -def check(packagedir, expected_version, **env): +def check(venv, expected_version, **env): - old_pythonpath = os.environ.get("PYTHONPATH") - if old_pythonpath: - pythonpath = f"{old_pythonpath}:{packagedir}" - else: - pythonpath = str(packagedir) subprocess.check_call( - sys.executable, "-c", SCRIPT, expected_version, - env=dict(os.environ, PYTHONPATH=pythonpath, **env), + venv.python, "-c", SCRIPT, expected_version, + env=dict(os.environ, **env), ) -def test_distlib_setuptools_works(get_setuptools_packagedir): - packagedir = get_setuptools_packagedir("45.0.0") - check(packagedir, "45.0.0") +@pytest.mark.skipif( + sys.version_info:2 >= (3, 10), reason="old setuptools won't work on python 3.10" +) +def test_distlib_setuptools_works(venv_maker): + venv = venv_maker.get_venv(setuptools="45.0.0", pip="9.0", python="3.6") + subprocess.run(venv.python, "-m", "pip", "install", "-e", str(ROOT)) + + check(venv, "45.0.0") + + +SETUP_PY_NAME = """ +from setuptools import setup +setup(name='setuptools_scm_test_package') +""" + +SETUP_PY_KEYWORD = """ +from setuptools import setup +setup(use_scm_version={"write_to": "pkg_version.py"}) +""" + +PYPROJECT_TOML_WITH_KEY = """ +build-system +# Minimum requirements for the build system to execute. +requires = "setuptools>45", "wheel" # PEP 508 specifications. +tool.setuptools_scm +write_to = "pkg_version.py" +""" + +SETUP_CFG_NAME = """ +metadata +name = setuptools_scm_test_package +""" + + +def prepare_expecting_pyproject_support(pkg: pathlib.Path): + pkg.mkdir() + pkg.joinpath("setup.py").write_text(SETUP_PY_NAME) + pkg.joinpath("pyproject.toml").write_text(PYPROJECT_TOML_WITH_KEY) + pkg.joinpath("PKG-INFO").write_text("Version: 1.0.0") + + +def prepare_setup_py_config(pkg: pathlib.Path): + pkg.mkdir() + pkg.joinpath("setup.py").write_text(SETUP_PY_KEYWORD) + pkg.joinpath("setup.cfg").write_text(SETUP_CFG_NAME) + + pkg.joinpath("PKG-INFO").write_text("Version: 1.0.0") + + +@pytest.mark.skipif( + sys.version_info:2 >= (3, 10), reason="old setuptools won't work on python 3.10" +) +@pytest.mark.parametrize("setuptools", f"{v}.0" for v in range(31, 45)) +@pytest.mark.parametrize( + "project_create", + + pytest.param( + prepare_expecting_pyproject_support, + marks=pytest.mark.xfail(reason="pyproject requires setuptools > 42"), + ), + prepare_setup_py_config, + , +) +def test_on_old_setuptools( + venv_maker, tmp_path, setuptools, project_create, monkeypatch +): + pkg = tmp_path.joinpath("pkg") + project_create(pkg) + venv = venv_maker.get_venv(setuptools=setuptools, pip="9.0", python="3.6") + + # monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG", raising=False) + + def run_and_output(cmd): + res = subprocess.run(cmd, cwd=str(pkg), stdout=subprocess.PIPE)
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/testing/test_version.py -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/testing/test_version.py
Changed
@@ -1,17 +1,17 @@ -from datetime import date, timedelta +from datetime import date +from datetime import timedelta import pytest + from setuptools_scm.config import Configuration -from setuptools_scm.version import ( - meta, - simplified_semver_version, - release_branch_semver_version, - tags_to_versions, - no_guess_dev_version, - guess_next_version, - format_version, - calver_by_date, -) +from setuptools_scm.version import calver_by_date +from setuptools_scm.version import format_version +from setuptools_scm.version import guess_next_version +from setuptools_scm.version import meta +from setuptools_scm.version import no_guess_dev_version +from setuptools_scm.version import release_branch_semver_version +from setuptools_scm.version import simplified_semver_version +from setuptools_scm.version import tags_to_versions c = Configuration() @@ -83,6 +83,11 @@ id="release_branch_legacy_version", ), pytest.param( + meta("1.0.0", distance=2, branch="v1.0.x", config=c), + "1.0.1.dev2", + id="release_branch_with_v_prefix", + ), + pytest.param( meta("1.0.0", distance=2, branch="release-1.0", config=c), "1.0.1.dev2", id="release_branch_with_prefix", @@ -99,21 +104,28 @@ assert computed == expected_next +def m(tag, **kw): + return meta(tag, **kw, config=c) + + @pytest.mark.parametrize( "version, expected_next", pytest.param( - meta("1.0.0", distance=2, branch="default", config=c), + m("1.0.0", distance=2), "1.0.0.post1.dev2", id="dev_distance", ), pytest.param( - meta("1.0", distance=2, branch="default", config=c), + m("1.0.dev0", distance=2), "1.0.dev2", id="dev_distance_after_dev_tag" + ), + pytest.param( + m("1.0", distance=2), "1.0.post1.dev2", id="dev_distance_short_tag", ), pytest.param( - meta("1.0.0", distance=None, branch="default", config=c), + m("1.0.0"), "1.0.0", id="no_dev_distance", ), @@ -124,8 +136,20 @@ assert computed == expected_next +@pytest.mark.parametrize( + "version, match", + + ("1.0.dev1", "choosing custom numbers for the `.devX` distance"), + ("1.0.post1", "already is a post release"), + , +) +def test_no_guess_version_bad(version, match): + with pytest.raises(ValueError, match=match): + no_guess_dev_version(m(version, distance=1)) + + def test_bump_dev_version_zero(): - guess_next_version("1.0.dev0") + assert guess_next_version("1.0.dev0") == "1.0" def test_bump_dev_version_nonzero_raises(): @@ -136,7 +160,7 @@ "choosing custom numbers for the `.devX` distance " "is not supported.\n " "The 1.0.dev1 can't be bumped\n" - "Please drop the tag or create a new supported one" + "Please drop the tag or create a new supported one ending in .dev0" ) @@ -203,7 +227,7 @@ meta(date_to_str() + ".1", config=c), date_to_str() + ".1", id="exact patch" ), pytest.param( - meta(date_to_str(fmt="20.01.02"), config=c), + meta("20.01.02", config=c), "20.1.2", id="leading 0s", ), @@ -251,6 +275,19 @@ date_to_str(date.today() - timedelta(days=2)) + ".3.dev2", id="node date distance", ), + pytest.param( + meta( + "1.2.0", + config=c, + distance=2, + node_date=date.today() - timedelta(days=2), + ), + date_to_str(days_offset=2) + ".0.dev2", + marks=pytest.mark.filterwarnings( + "ignore:.*not correspond to a valid versioning date.*:UserWarning" + ), + id="using on old version tag", + ), , ) def test_calver_by_date(version, expected_next): @@ -278,3 +315,19 @@ def test_calver_by_date_future_warning(): with pytest.warns(UserWarning, match="your previous tag*"): calver_by_date(meta(date_to_str(days_offset=-2), config=c, distance=2)) + + +def test_custom_version_cls(): + """Test that we can pass our own version class instead of pkg_resources""" + + class MyVersion: + def __init__(self, tag_str: str): + self.tag = tag_str + + def __repr__(self): + return "Custom %s" % self.tag + + scm_version = meta("1.0.0-foo", config=Configuration(version_cls=MyVersion)) + + assert isinstance(scm_version.tag, MyVersion) + assert repr(scm_version.tag) == "Custom 1.0.0-foo"
View file
_service:tar_scm:setuptools_scm-6.0.0.tar.gz/tox.ini -> _service:tar_scm:setuptools_scm-6.4.2.tar.gz/tox.ini
Changed
@@ -1,11 +1,14 @@ tox -envlist=py{27,34,35,36,37,38,39}-test,flake8,check_readme,check-dist,py{27,37}-selfcheck,docs +envlist=py{36,37,38,39,310}-{test,selfcheck},check_readme,check-dist pytest testpaths=testing -filterwarnings=error +filterwarnings= + error + ignore:.*tool\.setuptools_scm.* markers= issue(id): reference to github issue + skip_commit: allows to skip committing in the helpers # disable unraisable until investigated addopts = -p no:unraisableexception @@ -13,14 +16,7 @@ max-complexity = 10 max-line-length = 88 ignore=E203,W503 -exclude= - .git, - .tox, - .env, - .venv, - .pytest_cache, - __pycache__, - ./src/setuptools_scm/win_py31_compat.py + testenv usedevelop=True @@ -29,21 +25,14 @@ test: False deps= pytest - setuptools >= 42 - toml + setuptools >= 45 + tomli + virtualenv>20 commands= test: pytest selfcheck: python setup.py --version -extras = - toml -testenv:flake8 -skip_install=True -deps= - flake8 - mccabe -commands = - flake8 src/setuptools_scm/ testing/ setup.py --exclude=src/setuptools_scm/win_py31_compat.py + testenv:check_readme skip_install=True @@ -58,30 +47,12 @@ testenv:check_dist deps= - wheel + build twine commands= - python setup.py clean --all rotate -k 0 -m .whl,.tar.gz,.zip - python setup.py -q egg_info - python setup.py -q sdist --formats zip bdist_wheel + python -m build twine check dist/* -testenv:dist -deps= wheel -whitelist_externals = rm -commands= - python setup.py -q clean --all - python setup.py -q rotate -k 0 -m .egg,.zip,.whl,.tar.gz - python setup.py -q egg_info - python setup.py -q sdist --formats zip,bztar bdist_wheel upload - -testenv:devpi -deps= - devpi-client -commands = - python setup.py -q egg_info - devpi upload --from-dir dist - #XXX: envs for hg versions
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2