summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimone Pierazzini <s.pierazzini@nextworks.it>2021-02-18 06:40:17 +0100
committerSimone Pierazzini <s.pierazzini@nextworks.it>2021-02-18 06:40:17 +0100
commitcb00954729e1deaef431697bae8b8a6a7198c2ce (patch)
tree376810f7e9e0a6ca10a25e5dd4eab5f9328b81b9
parentc121d289da5d19cf6df2bf6b64ac28916a060161 (diff)
downloadpython-setuptools-git-cb00954729e1deaef431697bae8b8a6a7198c2ce.tar.gz
Correctly parse cmdclass in setup.cfg. Fixes #2570
-rw-r--r--changelog.d/2570.change.rst1
-rw-r--r--setuptools/config.py17
-rw-r--r--setuptools/tests/test_config.py24
3 files changed, 42 insertions, 0 deletions
diff --git a/changelog.d/2570.change.rst b/changelog.d/2570.change.rst
new file mode 100644
index 00000000..165089ed
--- /dev/null
+++ b/changelog.d/2570.change.rst
@@ -0,0 +1 @@
+Correctly parse cmdclass in setup.cfg.
diff --git a/setuptools/config.py b/setuptools/config.py
index af3a3bcb..4a6cd469 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -574,6 +574,7 @@ class ConfigOptionsHandler(ConfigHandler):
parse_list_semicolon = partial(self._parse_list, separator=';')
parse_bool = self._parse_bool
parse_dict = self._parse_dict
+ parse_cmdclass = self._parse_cmdclass
return {
'zip_safe': parse_bool,
@@ -594,6 +595,22 @@ class ConfigOptionsHandler(ConfigHandler):
'entry_points': self._parse_file,
'py_modules': parse_list,
'python_requires': SpecifierSet,
+ 'cmdclass': parse_cmdclass,
+ }
+
+ def _parse_cmdclass(self, value):
+ def resolve_class(qualified_class_name):
+ idx = qualified_class_name.rfind('.')
+ class_name = qualified_class_name[idx+1:]
+ pkg_name = qualified_class_name[:idx]
+
+ module = __import__(pkg_name)
+
+ return getattr(module, class_name)
+
+ return {
+ k: resolve_class(v)
+ for k, v in self._parse_dict(value).items()
}
def _parse_packages(self, value):
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 1dee1271..16892cb1 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -1,3 +1,6 @@
+import types
+import sys
+
import contextlib
import configparser
@@ -7,6 +10,7 @@ from distutils.errors import DistutilsOptionError, DistutilsFileError
from mock import patch
from setuptools.dist import Distribution, _Distribution
from setuptools.config import ConfigHandler, read_configuration
+from distutils.core import Command
from .textwrap import DALS
@@ -853,6 +857,26 @@ class TestOptions:
with get_dist(tmpdir) as dist:
dist.parse_config_files()
+ def test_cmdclass(self, tmpdir):
+ class CustomCmd(Command):
+ pass
+
+ m = types.ModuleType('custom_build', 'test package')
+
+ m.__dict__['CustomCmd'] = CustomCmd
+
+ sys.modules['custom_build'] = m
+
+ fake_env(
+ tmpdir,
+ '[options]\n'
+ 'cmdclass =\n'
+ ' customcmd = custom_build.CustomCmd\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.cmdclass == {'customcmd': CustomCmd}
+
saved_dist_init = _Distribution.__init__