Skip to content

Commit 682d669

Browse files
Merge pull request #616 from RonnyPfannschmidt/fix-regressions
combined preparation for the 6.3.0 release and a regression resolution
2 parents 410011b + 7b65699 commit 682d669

20 files changed

+400
-155
lines changed

.github/workflows/python-tests.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
update: true
4141
- run: pip install -U setuptools
4242
if: matrix.python_version != 'msys2'
43-
- run: pip install -e .[toml] pytest
43+
- run: pip install -e .[toml] pytest virtualenv
4444
# pip2 is needed because Mercurial uses python2 on Ubuntu 20.04
4545
- run: |
4646
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
@@ -49,6 +49,17 @@ jobs:
4949
if: matrix.os == 'ubuntu-latest'
5050
- run: pytest
5151

52+
test_legacy_setuptools:
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v1
56+
- name: Setup python
57+
uses: actions/setup-python@v2
58+
with:
59+
python-version: "3.6"
60+
architecture: x64
61+
- run: pip install -e .[toml] pytest virtualenv
62+
- run: pytest --test-legacy testing/test_setuptools_support.py || true # ignore fail flaky on ci
5263
check_selfinstall:
5364
runs-on: ubuntu-latest
5465
strategy:
@@ -66,8 +77,8 @@ jobs:
6677
architecture: x64
6778
# self install testing needs some clarity
6879
# so its being executed without any other tools running
69-
# setuptools smaller 52 is needed too di easy_install
70-
- run: pip install -U "setuptools<52" tomli
80+
# setuptools smaller 52 is needed to do easy_install
81+
- run: pip install -U "setuptools<52" tomli packaging
7182
- run: python setup.py egg_info
7283
- run: python setup.py sdist
7384
- run: ${{ matrix.installer }} dist/*

CHANGELOG.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
2+
6.3.0
3+
=======
4+
5+
.. warning::
6+
7+
This release explicitly warns on unsupported setuptools.
8+
This unfortunately has to happen as the legacy ``setup_requires`` mechanism
9+
incorrectly configures the setuptools working-set when a more recent setuptools
10+
version than available is required.
11+
12+
As all releases of setuptools are affected as the historic mechanism
13+
for ensuring a working setuptools setup was shipping a ``ez_setup`` file
14+
next to ``setup.py``, which would install the required version of setuptools.
15+
16+
This mechanism has long since been deprecated and removed
17+
as most people haven't been using it
18+
19+
20+
* fix #612: depend on packaging to ensure version parsing parts
21+
* fix #611: correct the typo that hid away the toml extra and add it in ``setup.py`` as well
22+
* fix #615: restore support for the git_archive plugin which doesn't pass over the config
23+
* restore the ability to run on old setuptools while to avoid breaking pipelines
24+
125
v6.2.0
226
=======
327

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ include *.rst
77
include LICENSE
88
include *.toml
99
include mypy.ini
10+
include testing/Dockerfile.busted-buster
1011
recursive-include testing *.bash

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
[build-system]
2-
requires = ["setuptools>=45", "wheel", "tomli"]
2+
requires = [
3+
"setuptools>=45",
4+
"wheel",
5+
"tomli>=1.0",
6+
"packaging>=20.0"
7+
]
38
build-backend = "setuptools.build_meta"

setup.cfg

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ classifiers =
2727
[options]
2828
packages = find:
2929
install_requires =
30-
setuptools>=45
31-
tomli>=1.0
30+
packaging>=20.0
31+
setuptools
3232
python_requires = >=3.6
3333
package_dir =
3434
=src
@@ -68,5 +68,7 @@ setuptools_scm.version_scheme =
6868
no-guess-dev = setuptools_scm.version:no_guess_dev_version
6969
calver-by-date = setuptools_scm.version:calver_by_date
7070

71-
[option.extras_require]
72-
toml = # empty
71+
[options.extras_require]
72+
toml =
73+
setuptools>=42
74+
tomli>=1.0.0

setup.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,56 @@
1313
import sys
1414

1515
import setuptools
16+
from setuptools.command.bdist_egg import bdist_egg as original_bdist_egg
1617

1718

18-
def scm_config():
19+
class bdist_egg(original_bdist_egg):
20+
def run(self):
21+
raise SystemExit(
22+
f"{type(self).__name__} is forbidden, "
23+
"please update to setuptools>=45 which uses pip"
24+
)
25+
26+
27+
def scm_version():
1928

2029
if sys.version_info < (3, 6):
2130
raise RuntimeError(
2231
"support for python < 3.6 has been removed in setuptools_scm>=6.0.0"
2332
)
24-
2533
here = os.path.dirname(os.path.abspath(__file__))
2634
src = os.path.join(here, "src")
27-
egg_info = os.path.join(src, "setuptools_scm.egg-info")
28-
has_entrypoints = os.path.isdir(egg_info)
29-
import pkg_resources
3035

3136
sys.path.insert(0, src)
32-
pkg_resources.working_set.add_entry(src)
3337

38+
from setuptools_scm import get_version
3439
from setuptools_scm.hacks import parse_pkginfo
35-
from setuptools_scm.git import parse as parse_git
40+
from setuptools_scm import git
3641
from setuptools_scm.version import guess_next_dev_version, get_local_node_and_date
3742

38-
def parse(root):
43+
def parse(root, config):
3944
try:
40-
return parse_pkginfo(root)
45+
return parse_pkginfo(root, config)
4146
except OSError:
42-
return parse_git(root)
47+
return git.parse(root, config=config)
4348

44-
config = dict(
45-
version_scheme=guess_next_dev_version, local_scheme=get_local_node_and_date
49+
return get_version(
50+
root=here,
51+
parse=parse,
52+
version_scheme=guess_next_dev_version,
53+
local_scheme=get_local_node_and_date,
4654
)
4755

48-
from setuptools.command.bdist_egg import bdist_egg as original_bdist_egg
49-
50-
class bdist_egg(original_bdist_egg):
51-
def run(self):
52-
raise SystemExit("bdist_egg is forbidden, please update to setuptools>=45")
53-
54-
if has_entrypoints:
55-
return dict(use_scm_version=config, cmdclass={"bdist_egg": bdist_egg})
56-
else:
57-
from setuptools_scm import get_version
58-
59-
return dict(
60-
version=get_version(root=here, parse=parse, **config),
61-
cmdclass={"bdist_egg": bdist_egg},
62-
)
63-
6456

6557
if __name__ == "__main__":
66-
setuptools.setup(setup_requires=["setuptools>=45", "tomli"], **scm_config())
58+
setuptools.setup(
59+
setup_requires=["setuptools"],
60+
version=scm_version(),
61+
extras_require={
62+
"toml": [
63+
"setuptools>=42",
64+
"tomli>=1.0.0",
65+
],
66+
},
67+
cmdclass={"bdist_egg": bdist_egg},
68+
)

src/setuptools_scm/__init__.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,17 @@
55
import os
66
import warnings
77

8-
try:
9-
from packaging.version import parse
10-
except ImportError:
11-
from pkg_resources import parse_version as parse
12-
13-
from .config import (
14-
Configuration,
15-
DEFAULT_VERSION_SCHEME,
16-
DEFAULT_LOCAL_SCHEME,
17-
DEFAULT_TAG_REGEX,
18-
NonNormalizedVersion,
19-
)
20-
from .utils import function_has_arg, trace
21-
from .version import format_version, meta
8+
from ._version_cls import NonNormalizedVersion
9+
from ._version_cls import Version
10+
from .config import Configuration
11+
from .config import DEFAULT_LOCAL_SCHEME
12+
from .config import DEFAULT_TAG_REGEX
13+
from .config import DEFAULT_VERSION_SCHEME
2214
from .discover import iter_matching_entrypoints
15+
from .utils import function_has_arg
16+
from .utils import trace
17+
from .version import format_version
18+
from .version import meta
2319

2420
PRETEND_KEY = "SETUPTOOLS_SCM_PRETEND_VERSION"
2521
PRETEND_KEY_NAMED = PRETEND_KEY + "_FOR_{name}"
@@ -40,9 +36,9 @@ def version_from_scm(root):
4036
warnings.warn(
4137
"version_from_scm is deprecated please use get_version",
4238
category=DeprecationWarning,
39+
stacklevel=2,
4340
)
44-
config = Configuration()
45-
config.root = root
41+
config = Configuration(root=root)
4642
# TODO: Is it API?
4743
return _version_from_entrypoints(config)
4844

@@ -52,15 +48,16 @@ def _call_entrypoint_fn(root, config, fn):
5248
return fn(root, config=config)
5349
else:
5450
warnings.warn(
55-
"parse functions are required to provide a named argument"
56-
" 'config' in the future.",
57-
category=PendingDeprecationWarning,
51+
f"parse function {fn.__module__}.{fn.__name__}"
52+
" are required to provide a named argument"
53+
" 'config', setuptools_scm>=8.0 will remove support.",
54+
category=DeprecationWarning,
5855
stacklevel=2,
5956
)
6057
return fn(root)
6158

6259

63-
def _version_from_entrypoints(config, fallback=False):
60+
def _version_from_entrypoints(config: Configuration, fallback=False):
6461
if fallback:
6562
entrypoint = "setuptools_scm.parse_scm_fallback"
6663
root = config.fallback_root
@@ -70,7 +67,7 @@ def _version_from_entrypoints(config, fallback=False):
7067

7168
for ep in iter_matching_entrypoints(root, entrypoint, config):
7269
version = _call_entrypoint_fn(root, config, ep.load())
73-
70+
trace(ep, version)
7471
if version:
7572
return version
7673

@@ -90,7 +87,7 @@ def dump_version(root, version, write_to, template=None):
9087
)
9188
)
9289

93-
parsed_version = parse(version)
90+
parsed_version = Version(version)
9491
version_fields = parsed_version.release
9592
if parsed_version.dev is not None:
9693
version_fields += (f"dev{parsed_version.dev}",)
@@ -201,10 +198,11 @@ def _get_version(config):
201198
"dump_version",
202199
"version_from_scm",
203200
"Configuration",
204-
"NonNormalizedVersion",
205201
"DEFAULT_VERSION_SCHEME",
206202
"DEFAULT_LOCAL_SCHEME",
207203
"DEFAULT_TAG_REGEX",
204+
"Version",
205+
"NonNormalizedVersion",
208206
# TODO: are the symbols below part of public API ?
209207
"function_has_arg",
210208
"trace",

src/setuptools_scm/_version_cls.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
try:
2+
from packaging.version import Version
3+
4+
assert hasattr(Version, "release")
5+
except ImportError:
6+
from pkg_resources._vendor.packaging.version import Version as SetuptoolsVersion
7+
8+
try:
9+
SetuptoolsVersion.release
10+
Version = SetuptoolsVersion
11+
except AttributeError:
12+
13+
class Version(SetuptoolsVersion): # type: ignore
14+
@property
15+
def release(self):
16+
return self._version.release
17+
18+
@property
19+
def dev(self):
20+
return self._version.dev
21+
22+
@property
23+
def local(self):
24+
return self._version.local
25+
26+
27+
class NonNormalizedVersion(Version):
28+
"""A non-normalizing version handler.
29+
30+
You can use this class to preserve version verification but skip normalization.
31+
For example you can use this to avoid git release candidate version tags
32+
("1.0.0-rc1") to be normalized to "1.0.0rc1". Only use this if you fully
33+
trust the version tags.
34+
"""
35+
36+
def __init__(self, version):
37+
# parse and validate using parent
38+
super().__init__(version)
39+
40+
# store raw for str
41+
self._raw_version = version
42+
43+
def __str__(self):
44+
# return the non-normalized version (parent returns the normalized)
45+
return self._raw_version
46+
47+
def __repr__(self):
48+
# same pattern as parent
49+
return f"<NonNormalizedVersion({self._raw_version!r})>"

0 commit comments

Comments
 (0)