Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix regressions #607

Merged
merged 7 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
fail-fast: false
matrix:
python_version: [ '3.6', '3.9', 'pypy3' ]
installer: ["pip install", easy_install]
installer: ["pip install"]
name: check self install - Python ${{ matrix.python_version }} via ${{ matrix.installer }}
steps:
- uses: actions/checkout@v1
Expand All @@ -67,7 +67,7 @@ jobs:
# 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: pip install -U "setuptools<52" tomli
- run: python setup.py egg_info
- run: python setup.py sdist
- run: ${{ matrix.installer }} dist/*
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
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
======

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[build-system]
requires = ["setuptools>=45", "wheel"]
requires = ["setuptools>=45", "wheel", "tomli"]
build-backend = "setuptools.build_meta"
20 changes: 12 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,8 @@ def scm_config():
has_entrypoints = os.path.isdir(egg_info)
import pkg_resources

pkg_resources.require("setuptools>=45")

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.hacks import parse_pkginfo
from setuptools_scm.git import parse as parse_git
Expand All @@ -50,13 +45,22 @@ def parse(root):
version_scheme=guess_next_dev_version, local_scheme=get_local_node_and_date
)

from setuptools.command.bdist_egg import bdist_egg as original_bdist_egg

class bdist_egg(original_bdist_egg):
def run(self):
raise SystemExit("bdist_egg is forbidden, please update to setuptools>=45")

if has_entrypoints:
return dict(use_scm_version=config)
return dict(use_scm_version=config, cmdclass={"bdist_egg": bdist_egg})
else:
from setuptools_scm import get_version

return dict(version=get_version(root=here, parse=parse, **config))
return dict(
version=get_version(root=here, parse=parse, **config),
cmdclass={"bdist_egg": bdist_egg},
)


if __name__ == "__main__":
setuptools.setup(**scm_config())
setuptools.setup(setup_requires=["setuptools>=45", "tomli"], **scm_config())
42 changes: 39 additions & 3 deletions src/setuptools_scm/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ def _check_absolute_root(root, relative_to):
return os.path.abspath(root)


def _lazy_tomli_load(data):
from tomli import loads

return loads(data)


class Configuration:
"""Global configuration model"""

Expand Down Expand Up @@ -163,16 +169,46 @@ def tag_regex(self, value):
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,
):
"""
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, encoding="UTF-8") as strm:
defn = __import__("toml").load(strm)
section = defn.get("tool", {})["setuptools_scm"]
data = strm.read()
defn = _load_toml(data)
try:
section = defn.get("tool", {})["setuptools_scm"]
except LookupError:
raise FileNotFoundError(
f"{name} does not contain a tool.setuptools_scm section"
) from None
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:
# 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 cls(dist_name=dist_name, **section)


Expand Down
26 changes: 10 additions & 16 deletions src/setuptools_scm/integration.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import warnings

import setuptools

from . import _get_version
from . import Configuration
from .utils import do
from .utils import iter_entry_points
from .utils import trace
from .utils import trace_exception


def version_keyword(dist, keyword, value):
def version_keyword(dist: setuptools.Distribution, keyword, value):
if not value:
return
if value is True:
Expand Down Expand Up @@ -39,24 +42,15 @@ def find_files(path=""):
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
import tomli

with open(name, encoding="UTF-8") as strm:
defn = tomli.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
try:
config = Configuration.from_file(dist_name=dist_name)
except Exception:
return trace_exception()
dist.metadata.version = _get_version(config)
except FileNotFoundError as e:
warnings.warn(str(e))
else:
dist.metadata.version = _get_version(config)
58 changes: 46 additions & 12 deletions testing/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,64 @@ def test_pyproject_support(tmpdir, monkeypatch):
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'\n[tool.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_FILES[metadata_in])
wd.write("setup.py", SETUP_PY_FILES[metadata_in])
wd.write("setup.cfg", SETUP_CFG_FILES[metadata_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")


Expand Down