Skip to content

Commit

Permalink
Add deprecation messages for namespace_packages (#3262)
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed May 16, 2022
2 parents 42d940f + 269f3ac commit 73bc126
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 8 deletions.
8 changes: 8 additions & 0 deletions changelog.d/3262.deprecation.rst
@@ -0,0 +1,8 @@
Formally added deprecation messages for ``namespace_packages``.
The methodology that uses ``pkg_resources`` and ``namespace_packages`` for
creating namespaces was already discouraged by the :doc:`setuptools docs
</userguide/package_discovery>` and the
:doc:`Python Packaging User Guide <PyPUG:guides/packaging-namespace-packages>`,
therefore this change just make the deprecation more official.
Users can consider migrating to native/implicit namespaces (as introduced in
:pep:`420`).
5 changes: 5 additions & 0 deletions docs/references/keywords.rst
Expand Up @@ -353,6 +353,11 @@ extensions).
.. _keyword/namespace_packages:

``namespace_packages``
.. warning::
``namespace_packages`` is deprecated in favor of native/implicit
namespaces (:pep:`420`). Check :doc:`the Python Packaging User Guide
<PyPUG:guides/packaging-namespace-packages>` for more information.

A list of strings naming the project's "namespace packages". A namespace
package is a package that may be split across multiple project
distributions. For example, Zope 3's ``zope`` package is a namespace
Expand Down
6 changes: 5 additions & 1 deletion docs/userguide/declarative_config.rst
Expand Up @@ -210,7 +210,7 @@ packages find:, find_namespace:, list-comma [#
package_dir dict
package_data section [#opt-1]_
exclude_package_data section
namespace_packages list-comma
namespace_packages list-comma [#opt-5]_
py_modules list-comma 34.4.0
data_files section 40.6.0 [#opt-4]_
======================= =================================== =============== =========
Expand Down Expand Up @@ -243,6 +243,10 @@ data_files section 40.6.0 [#
.. [#opt-4] ``data_files`` is deprecated and should be avoided.
Please check :doc:`/userguide/datafiles` for more information.
.. [#opt-5] ``namespace_packages`` is deprecated in favour of native/implicit
namespaces (:pep:`420`). Check :doc:`the Python Packaging User Guide
<PyPUG:guides/packaging-namespace-packages>` for more information.
Compatibility with other tools
==============================
Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/pyproject_config.rst
Expand Up @@ -94,7 +94,7 @@ Key Value Type (TOML) Notes
``py-modules`` array See tip below
``packages`` array or ``find`` directive See tip below
``package-dir`` table/inline-table Used when explicitly listing ``packages``
``namespace-packages`` array Not necessary if you use :pep:`420`
``namespace-packages`` array **Deprecated** - Use implicit namespaces instead (:pep:`420`)
``package-data`` table/inline-table See :doc:`/userguide/datafiles`
``include-package-data`` boolean ``True`` by default
``exclude-package-data`` table/inline-table
Expand Down
11 changes: 11 additions & 0 deletions setuptools/config/_apply_pyprojecttoml.py
Expand Up @@ -16,6 +16,8 @@
from typing import (TYPE_CHECKING, Any, Callable, Dict, List, Optional, Set, Tuple,
Type, Union)

from setuptools._deprecation_warning import SetuptoolsDeprecationWarning

if TYPE_CHECKING:
from setuptools._importlib import metadata # noqa
from setuptools.dist import Distribution # noqa
Expand Down Expand Up @@ -75,6 +77,12 @@ def _apply_tool_table(dist: "Distribution", config: dict, filename: _Path):

for field, value in tool_table.items():
norm_key = json_compatible_key(field)

if norm_key in TOOL_TABLE_DEPRECATIONS:
suggestion = TOOL_TABLE_DEPRECATIONS[norm_key]
msg = f"The parameter `{norm_key}` is deprecated, {suggestion}"
warnings.warn(msg, SetuptoolsDeprecationWarning)

norm_key = TOOL_TABLE_RENAMES.get(norm_key, norm_key)
_set_config(dist, norm_key, value)

Expand Down Expand Up @@ -307,6 +315,9 @@ def _acessor(obj):
}

TOOL_TABLE_RENAMES = {"script_files": "scripts"}
TOOL_TABLE_DEPRECATIONS = {
"namespace_packages": "consider using implicit namespaces instead (PEP 420)."
}

SETUPTOOLS_PATCHES = {"long_description_content_type", "project_urls",
"provides_extras", "license_file", "license_files"}
Expand Down
12 changes: 9 additions & 3 deletions setuptools/config/setupcfg.py
Expand Up @@ -12,6 +12,7 @@
from distutils.errors import DistutilsOptionError, DistutilsFileError
from setuptools.extern.packaging.version import Version, InvalidVersion
from setuptools.extern.packaging.specifiers import SpecifierSet
from setuptools._deprecation_warning import SetuptoolsDeprecationWarning

from . import expand

Expand Down Expand Up @@ -507,7 +508,7 @@ def parsers(self):
parse_list,
"The requires parameter is deprecated, please use "
"install_requires for runtime dependencies.",
DeprecationWarning,
SetuptoolsDeprecationWarning,
),
'obsoletes': parse_list,
'classifiers': self._get_parser_compound(parse_file, parse_list),
Expand All @@ -516,7 +517,7 @@ def parsers(self):
exclude_files_parser('license_file'),
"The license_file parameter is deprecated, "
"use license_files instead.",
DeprecationWarning,
SetuptoolsDeprecationWarning,
),
'license_files': parse_list,
'description': parse_file,
Expand Down Expand Up @@ -584,7 +585,12 @@ def parsers(self):
'scripts': parse_list,
'eager_resources': parse_list,
'dependency_links': parse_list,
'namespace_packages': parse_list,
'namespace_packages': self._deprecated_config_handler(
parse_list,
"The namespace_packages parameter is deprecated, "
"consider using implicit namespaces instead (PEP 420).",
SetuptoolsDeprecationWarning,
),
'install_requires': parse_list_semicolon,
'setup_requires': parse_list_semicolon,
'tests_require': parse_list_semicolon,
Expand Down
5 changes: 5 additions & 0 deletions setuptools/dist.py
Expand Up @@ -280,6 +280,11 @@ def check_nsp(dist, attr, value):
nsp,
parent,
)
msg = (
"The namespace_packages parameter is deprecated, "
"consider using implicit namespaces instead (PEP 420).",
)
warnings.warn(msg, SetuptoolsDeprecationWarning)


def check_extras(dist, attr, value):
Expand Down
17 changes: 17 additions & 0 deletions setuptools/tests/config/test_apply_pyprojecttoml.py
Expand Up @@ -6,6 +6,7 @@
import io
import re
import tarfile
from inspect import cleandoc
from pathlib import Path
from unittest.mock import Mock
from zipfile import ZipFile
Expand All @@ -14,6 +15,7 @@
from ini2toml.api import Translator

import setuptools # noqa ensure monkey patch to metadata
from setuptools._deprecation_warning import SetuptoolsDeprecationWarning
from setuptools.dist import Distribution
from setuptools.config import setupcfg, pyprojecttoml
from setuptools.config import expand
Expand Down Expand Up @@ -211,6 +213,21 @@ def test_license_and_license_files(tmp_path):
assert dist.metadata.license == "LicenseRef-Proprietary\n"


class TestDeprecatedFields:
def test_namespace_packages(self, tmp_path):
pyproject = tmp_path / "pyproject.toml"
config = """
[project]
name = "myproj"
version = "42"
[tool.setuptools]
namespace-packages = ["myproj.pkg"]
"""
pyproject.write_text(cleandoc(config), encoding="utf-8")
with pytest.warns(SetuptoolsDeprecationWarning, match="namespace_packages"):
pyprojecttoml.apply_configuration(makedist(tmp_path), pyproject)


class TestPresetField:
def pyproject(self, tmp_path, dynamic, extra_content=""):
content = f"[project]\nname = 'proj'\ndynamic = {dynamic!r}\n"
Expand Down
9 changes: 6 additions & 3 deletions setuptools/tests/config/test_setupcfg.py
Expand Up @@ -7,6 +7,7 @@
import pytest

from distutils.errors import DistutilsOptionError, DistutilsFileError
from setuptools._deprecation_warning import SetuptoolsDeprecationWarning
from setuptools.dist import Distribution, _Distribution
from setuptools.config.setupcfg import ConfigHandler, read_configuration
from ..textwrap import DALS
Expand Down Expand Up @@ -409,7 +410,7 @@ def test_deprecated_config_handlers(self, tmpdir):
'requires = some, requirement\n',
)

with pytest.deprecated_call():
with pytest.warns(SetuptoolsDeprecationWarning, match="requires"):
with get_dist(tmpdir) as dist:
metadata = dist.metadata

Expand Down Expand Up @@ -518,7 +519,8 @@ def test_basic(self, tmpdir):
'python_requires = >=1.0, !=2.8\n'
'py_modules = module1, module2\n',
)
with get_dist(tmpdir) as dist:
deprec = pytest.warns(SetuptoolsDeprecationWarning, match="namespace_packages")
with deprec, get_dist(tmpdir) as dist:
assert dist.zip_safe
assert dist.include_package_data
assert dist.package_dir == {'': 'src', 'b': 'c'}
Expand Down Expand Up @@ -572,7 +574,8 @@ def test_multiline(self, tmpdir):
' http://some.com/here/1\n'
' http://some.com/there/2\n',
)
with get_dist(tmpdir) as dist:
deprec = pytest.warns(SetuptoolsDeprecationWarning, match="namespace_packages")
with deprec, get_dist(tmpdir) as dist:
assert dist.package_dir == {'': 'src', 'b': 'c'}
assert dist.packages == ['pack_a', 'pack_b.subpack']
assert dist.namespace_packages == ['pack1', 'pack2']
Expand Down

0 comments on commit 73bc126

Please sign in to comment.