1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
from __future__ import annotations
import logging
import os
import textwrap
import warnings
from pathlib import Path
from typing import Any
from typing import Callable
from typing import TYPE_CHECKING
import setuptools
from . import _get_version
from . import _types as _t
from . import _version_missing
from . import Configuration
from ._integration.setuptools import (
read_dist_name_from_setup_cfg as _read_dist_name_from_setup_cfg,
)
from ._version_cls import _validate_version_cls
log = logging.getLogger(__name__)
if TYPE_CHECKING:
pass
def _warn_on_old_setuptools(_version: str = setuptools.__version__) -> None:
if int(_version.split(".")[0]) < 61:
warnings.warn(
RuntimeWarning(
f"""
ERROR: setuptools=={_version} is used in combination with setuptools_scm>=8.x
Your build configuration is incomplete and previously worked by accident!
setuptools_scm requires setuptools>=61
Suggested workaround if applicable:
- 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) -> None:
maybe_version = _get_version(config)
if maybe_version is None:
_version_missing(config)
else:
assert dist.metadata.version is None
dist.metadata.version = maybe_version
def version_keyword(
dist: setuptools.Distribution,
keyword: str,
value: bool | dict[str, Any] | Callable[[], dict[str, Any]],
) -> None:
if not value:
return
elif value is True:
value = {}
elif callable(value):
value = value()
assert (
"dist_name" not in value
), "dist_name may not be specified in the setup keyword "
dist_name: str | None = dist.metadata.name
if dist.metadata.version is not None:
warnings.warn(f"version of {dist_name} already set")
return
log.debug(
"version keyword %r",
vars(dist.metadata),
)
log.debug("dist %s %s", id(dist), id(dist.metadata))
if dist_name is None:
dist_name = _read_dist_name_from_setup_cfg()
version_cls = value.pop("version_cls", None)
normalize = value.pop("normalize", True)
final_version = _validate_version_cls(version_cls, normalize)
config = Configuration(dist_name=dist_name, version_cls=final_version, **value)
_assign_version(dist, config)
def infer_version(dist: setuptools.Distribution) -> None:
log.debug(
"finalize hook %r",
vars(dist.metadata),
)
log.debug("dist %s %s", id(dist), id(dist.metadata))
if dist.metadata.version is not None:
return # metadata already added by hook
dist_name = dist.metadata.name
if dist_name is None:
dist_name = _read_dist_name_from_setup_cfg()
if not os.path.isfile("pyproject.toml"):
return
if dist_name == "setuptools_scm":
return
try:
config = Configuration.from_file(dist_name=dist_name)
except LookupError as e:
log.exception(e)
else:
_assign_version(dist, config)
def data_from_mime(path: _t.PathT) -> dict[str, str]:
content = Path(path).read_text(encoding="utf-8")
log.debug("mime %s content:\n%s", path, textwrap.indent(content, " "))
# the complex conditions come from reading pseudo-mime-messages
data = dict(x.split(": ", 1) for x in content.splitlines() if ": " in x)
log.debug("mime %s data:\n%s", path, data)
return data
|