Skip to content

Commit

Permalink
Correctly parse cmdclass in setup.cfg. Fixes pypa#2570
Browse files Browse the repository at this point in the history
  • Loading branch information
Simone Pierazzini committed Feb 18, 2021
1 parent c121d28 commit cb00954
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.d/2570.change.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correctly parse cmdclass in setup.cfg.
17 changes: 17 additions & 0 deletions setuptools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ def parsers(self):
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,
Expand All @@ -594,6 +595,22 @@ def parsers(self):
'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):
Expand Down
24 changes: 24 additions & 0 deletions setuptools/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import types
import sys

import contextlib
import configparser

Expand All @@ -7,6 +10,7 @@
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


Expand Down Expand Up @@ -853,6 +857,26 @@ def test_python_requires_invalid(self, tmpdir):
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__

Expand Down

0 comments on commit cb00954

Please sign in to comment.