Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deprecation messages for namespace_packages #3262

Merged
merged 3 commits into from May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -305,6 +313,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