Skip to content

Commit

Permalink
Address circular imports complaints by Sphinx 7.2+ (pypa#4023)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Aug 23, 2023
2 parents fdfe711 + 2733fc3 commit 6410fb0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 76 deletions.
2 changes: 2 additions & 0 deletions newsfragments/4023.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Avoid circular imports (particularly between ``setuptools/{__init__,dist,monkey}.py``),
or at least delay them, so tools like ``sphinx`` don't have problems analysing the codebase.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ testing-integration =

docs =
# upstream
sphinx >= 3.5,<=7.1.2 # workaround, see comments in pypa/setuptools#4020
sphinx >= 3.5
jaraco.packaging >= 9.3
rst.linker >= 1.9
furo
Expand Down
18 changes: 7 additions & 11 deletions setuptools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@
import re

import _distutils_hack.override # noqa: F401

import distutils.core
from distutils.errors import DistutilsOptionError
from distutils.util import convert_path as _convert_path

from . import logging, monkey
from . import version as _version_module
from .depends import Require
from .discovery import PackageFinder, PEP420PackageFinder
from .dist import Distribution
from .extension import Extension
from .warnings import SetuptoolsDeprecationWarning

import setuptools.version
from setuptools.extension import Extension
from setuptools.dist import Distribution
from setuptools.depends import Require
from setuptools.discovery import PackageFinder, PEP420PackageFinder
from . import monkey
from . import logging


__all__ = [
'setup',
'Distribution',
Expand All @@ -32,7 +28,7 @@
'find_namespace_packages',
]

__version__ = setuptools.version.__version__
__version__ = _version_module.__version__

bootstrap_install_from = None

Expand Down
6 changes: 3 additions & 3 deletions setuptools/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import contextlib
import dis

from setuptools.extern.packaging import version

from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE
from . import _imp
from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE
from .extern.packaging.version import Version


__all__ = ['Require', 'find_module', 'get_module_constant', 'extract_constant']
Expand All @@ -19,7 +19,7 @@ def __init__(
self, name, requested_version, module, homepage='', attribute=None, format=None
):
if format is None and requested_version is not None:
format = version.Version
format = Version

if format is not None:
requested_version = format(requested_version)
Expand Down
104 changes: 52 additions & 52 deletions setuptools/dist.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,56 @@
__all__ = ['Distribution']


import io
import sys
import re
import os
import numbers
import distutils.log
import distutils.core
import distutils.cmd
import distutils.dist
import distutils.command
from distutils.util import strtobool
from distutils.debug import DEBUG
from distutils.fancy_getopt import translate_longopt
from glob import iglob
import itertools
import numbers
import os
import re
import sys
import textwrap
from contextlib import suppress
from typing import List, Optional, Set, TYPE_CHECKING
from pathlib import Path

from collections import defaultdict
from contextlib import suppress
from email import message_from_file
from glob import iglob
from pathlib import Path
from typing import TYPE_CHECKING, List, Optional, Set

import distutils.cmd
import distutils.command
import distutils.core
import distutils.dist
import distutils.log
from distutils.debug import DEBUG
from distutils.errors import DistutilsOptionError, DistutilsSetupError
from distutils.fancy_getopt import translate_longopt
from distutils.util import rfc822_escape
from distutils.util import strtobool

from setuptools.extern import packaging
from setuptools.extern import ordered_set
from setuptools.extern.more_itertools import unique_everseen, partition

import setuptools
import setuptools.command
from setuptools import windows_support
from setuptools.monkey import get_unpatched
from setuptools.config import setupcfg, pyprojecttoml
from setuptools.discovery import ConfigDiscovery
from .extern.more_itertools import partition, unique_everseen
from .extern.ordered_set import OrderedSet
from .extern.packaging.markers import InvalidMarker, Marker
from .extern.packaging.specifiers import InvalidSpecifier, SpecifierSet
from .extern.packaging.version import InvalidVersion, Version

from setuptools.extern.packaging import version
from . import _reqs
from . import _entry_points
from . import _normalization
from . import _reqs
from . import command as _ # noqa -- imported for side-effects
from ._importlib import metadata
from .config import setupcfg, pyprojecttoml
from .discovery import ConfigDiscovery
from .monkey import get_unpatched
from .warnings import InformationOnly, SetuptoolsDeprecationWarning


if TYPE_CHECKING:
from email.message import Message

__import__('setuptools.extern.packaging.specifiers')
__import__('setuptools.extern.packaging.version')


def get_metadata_version(self):
mv = getattr(self, 'metadata_version', None)
if mv is None:
mv = version.Version('2.1')
mv = Version('2.1')
self.metadata_version = mv
return mv

Expand Down Expand Up @@ -102,7 +98,7 @@ def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = message_from_file(file)

self.metadata_version = version.Version(msg['metadata-version'])
self.metadata_version = Version(msg['metadata-version'])
self.name = _read_field_from_msg(msg, 'name')
self.version = _read_field_from_msg(msg, 'version')
self.description = _read_field_from_msg(msg, 'summary')
Expand All @@ -116,9 +112,7 @@ def read_pkg_file(self, file):
self.license = _read_field_unescaped_from_msg(msg, 'license')

self.long_description = _read_field_unescaped_from_msg(msg, 'description')
if self.long_description is None and self.metadata_version >= version.Version(
'2.1'
):
if self.long_description is None and self.metadata_version >= Version('2.1'):
self.long_description = _read_payload_from_msg(msg)
self.description = _read_field_from_msg(msg, 'summary')

Expand All @@ -129,7 +123,7 @@ def read_pkg_file(self, file):
self.classifiers = _read_list_from_msg(msg, 'classifier')

# PEP 314 - these fields only exist in 1.1
if self.metadata_version == version.Version('1.1'):
if self.metadata_version == Version('1.1'):
self.requires = _read_list_from_msg(msg, 'requires')
self.provides = _read_list_from_msg(msg, 'provides')
self.obsoletes = _read_list_from_msg(msg, 'obsoletes')
Expand Down Expand Up @@ -299,7 +293,7 @@ def _check_extra(extra, reqs):
name, sep, marker = extra.partition(':')
try:
_check_marker(marker)
except packaging.markers.InvalidMarker:
except InvalidMarker:
msg = f"Invalid environment marker: {marker} ({extra!r})"
raise DistutilsSetupError(msg) from None
list(_reqs.parse(reqs))
Expand All @@ -308,7 +302,7 @@ def _check_extra(extra, reqs):
def _check_marker(marker):
if not marker:
return
m = packaging.markers.Marker(marker)
m = Marker(marker)
m.evaluate()


Expand Down Expand Up @@ -344,8 +338,8 @@ def check_requirements(dist, attr, value):
def check_specifier(dist, attr, value):
"""Verify that value is a valid version specifier"""
try:
packaging.specifiers.SpecifierSet(value)
except (packaging.specifiers.InvalidSpecifier, AttributeError) as error:
SpecifierSet(value)
except (InvalidSpecifier, AttributeError) as error:
tmpl = (
"{attr!r} must be a string " "containing valid version specifiers; {error}"
)
Expand Down Expand Up @@ -448,7 +442,7 @@ class Distribution(_Distribution):
_DISTUTILS_UNSUPPORTED_METADATA = {
'long_description_content_type': lambda: None,
'project_urls': dict,
'provides_extras': ordered_set.OrderedSet,
'provides_extras': OrderedSet,
'license_file': lambda: None,
'license_files': lambda: None,
}
Expand Down Expand Up @@ -499,7 +493,7 @@ def __init__(self, attrs=None):
# Save the original dependencies before they are processed into the egg format
self._orig_extras_require = {}
self._orig_install_requires = []
self._tmp_extras_require = defaultdict(ordered_set.OrderedSet)
self._tmp_extras_require = defaultdict(OrderedSet)

self.set_defaults = ConfigDiscovery(self)

Expand Down Expand Up @@ -535,10 +529,12 @@ def _set_metadata_defaults(self, attrs):

@staticmethod
def _normalize_version(version):
if isinstance(version, setuptools.sic) or version is None:
from . import sic

if isinstance(version, sic) or version is None:
return version

normalized = str(packaging.version.Version(version))
normalized = str(Version(version))
if version != normalized:
InformationOnly.emit(f"Normalizing '{version}' to '{normalized}'")
return normalized
Expand All @@ -552,8 +548,10 @@ def _validate_version(version):

if version is not None:
try:
packaging.version.Version(version)
except (packaging.version.InvalidVersion, TypeError):
Version(version)
except (InvalidVersion, TypeError):
from . import sic

SetuptoolsDeprecationWarning.emit(
f"Invalid version: {version!r}.",
"""
Expand All @@ -566,7 +564,7 @@ def _validate_version(version):
# Warning initially introduced in 26 Sept 2014
# pypa/packaging already removed legacy versions.
)
return setuptools.sic(version)
return sic(version)
return version

def _finalize_requires(self):
Expand Down Expand Up @@ -602,7 +600,7 @@ def _convert_extras_requirements(self):
`"extra:{marker}": ["barbazquux"]`.
"""
spec_ext_reqs = getattr(self, 'extras_require', None) or {}
tmp = defaultdict(ordered_set.OrderedSet)
tmp = defaultdict(OrderedSet)
self._tmp_extras_require = getattr(self, '_tmp_extras_require', tmp)
for section, v in spec_ext_reqs.items():
# Do not strip empty sections.
Expand Down Expand Up @@ -903,7 +901,7 @@ def parse_config_files(self, filenames=None, ignore_option_errors=False):

def fetch_build_eggs(self, requires):
"""Resolve pre-setup requirements"""
from setuptools.installer import _fetch_build_eggs
from .installer import _fetch_build_eggs

return _fetch_build_eggs(self, requires)

Expand Down Expand Up @@ -946,6 +944,8 @@ def _finalize_setup_keywords(self):
ep.load()(self, ep.name, value)

def get_egg_cache_dir(self):
from . import windows_support

egg_cache_dir = os.path.join(os.curdir, '.eggs')
if not os.path.exists(egg_cache_dir):
os.mkdir(egg_cache_dir)
Expand All @@ -966,7 +966,7 @@ def get_egg_cache_dir(self):

def fetch_build_egg(self, req):
"""Fetch an egg needed for building"""
from setuptools.installer import fetch_build_egg
from .installer import fetch_build_egg

return fetch_build_egg(self, req)

Expand Down
16 changes: 10 additions & 6 deletions setuptools/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
Monkey patching of distutils.
"""

import sys
import distutils.filelist
import functools
import inspect
import platform
import sys
import types
import functools
from importlib import import_module
import inspect

import setuptools
import distutils.filelist


__all__ = []
"""
Expand Down Expand Up @@ -61,6 +61,8 @@ def get_unpatched_class(cls):


def patch_all():
import setuptools

# we can't patch distutils.cmd, alas
distutils.core.Command = setuptools.Command

Expand Down Expand Up @@ -97,9 +99,11 @@ def patch_all():


def _patch_distribution_metadata():
from . import dist

"""Patch write_pkg_file and read_pkg_file for higher metadata standards"""
for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'):
new_val = getattr(setuptools.dist, attr)
new_val = getattr(dist, attr)
setattr(distutils.dist.DistributionMetadata, attr, new_val)


Expand Down
6 changes: 3 additions & 3 deletions setuptools/tests/test_setuptools.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

import pytest

from setuptools.extern.packaging import version

import setuptools
import setuptools.dist
import setuptools.depends as dep
from setuptools.depends import Require

from setuptools.extern.packaging.version import Version


@pytest.fixture(autouse=True)
def isolated_dir(tmpdir_cwd):
Expand Down Expand Up @@ -94,7 +94,7 @@ def testRequire(self):

assert req.name == 'Json'
assert req.module == 'json'
assert req.requested_version == version.Version('1.0.3')
assert req.requested_version == Version('1.0.3')
assert req.attribute == '__version__'
assert req.full_name() == 'Json-1.0.3'

Expand Down

0 comments on commit 6410fb0

Please sign in to comment.