]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Switch to PEP517 build with Hatch modern-build 1226/head
authorAarni Koskela <akx@iki.fi>
Mon, 8 Sep 2025 16:11:12 +0000 (19:11 +0300)
committerAarni Koskela <akx@iki.fi>
Mon, 8 Sep 2025 17:20:55 +0000 (20:20 +0300)
.github/workflows/ci.yml
MANIFEST.in [deleted file]
babel/core.py
conftest.py
docs/installation.rst
hatch_build.py [new file with mode: 0644]
pyproject.toml
setup.cfg [deleted file]
setup.py [deleted file]

index a5ed97f22248aeb92a27253d8d2763bdcd6d72e9..8b4b90421fe19f7d99eb61d8af556fcb7493d5f7 100644 (file)
@@ -51,7 +51,7 @@ jobs:
         python-version: ${{ matrix.python-version }}
         allow-prereleases: true
         cache: "pip"
-        cache-dependency-path: "**/setup.py"
+        cache-dependency-path: "**/pyproject.toml"
     - name: Install dependencies
       run: |
         python -m pip install --upgrade pip setuptools wheel
@@ -76,7 +76,7 @@ jobs:
         with:
           python-version: "3.13"
           cache: "pip"
-          cache-dependency-path: "**/setup.py"
+          cache-dependency-path: "**/pyproject.toml"
       - run: pip install build -e .
       - run: make import-cldr
       - run: python -m build
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644 (file)
index 82cb37a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-include Makefile CHANGES.rst LICENSE AUTHORS
-include conftest.py tox.ini
-include babel/global.dat
-include babel/locale-data/*.dat
-include babel/locale-data/LICENSE*
-recursive-include docs *
-recursive-exclude docs/_build *
-include scripts/*
-recursive-include tests *
-recursive-exclude tests *.pyc
-recursive-exclude tests *.pyo
index 17bc04236dc46388cef3492070fd173c8948f524..1d258083c527adf1584e8b743a9f63c30d8df548 100644 (file)
@@ -56,12 +56,13 @@ _default_plural_rule = PluralRule({})
 
 
 def _raise_no_data_error():
-    raise RuntimeError('The babel data files are not available. '
-                       'This usually happens because you are using '
-                       'a source checkout from Babel and you did '
-                       'not build the data files.  Just make sure '
-                       'to run "python setup.py import_cldr" before '
-                       'installing the library.')
+    raise RuntimeError(
+        'The babel data files are not available. '
+        'This usually happens because you are using '
+        'a source checkout from Babel and you did '
+        'not build the data files. Please see the '
+        'README.rst file for more information.',
+    )
 
 
 def get_global(key: _GLOBAL_KEY) -> Mapping[str, Any]:
index 79aeecf812b56c3d08134545326fc824e480e760..015a2044071fe34fbd15ed58e778f9ec07520423 100644 (file)
@@ -4,7 +4,6 @@ from _pytest.doctest import DoctestModule
 
 collect_ignore = [
     'babel/messages/setuptools_frontend.py',
-    'setup.py',
     'tests/messages/data',
 ]
 babel_path = Path(__file__).parent / 'babel'
index 8bf614cb6e8f283bb361c618534b5b95bb7f8674..081cd651a819a7517f72778c3bc90f4072bc53ad 100644 (file)
@@ -83,12 +83,12 @@ Get the git checkout in a new virtualenv and run in development mode::
     New python executable in venv/bin/python
     Installing distribute............done.
     $ . venv/bin/activate
-    $ python setup.py import_cldr
+    $ make import-cldr
     $ pip install --editable .
     ...
     Finished processing dependencies for Babel
 
-Make sure to not forget about the ``import_cldr`` step because otherwise
+Make sure to not forget about the CLDR import step because otherwise
 you will be missing the locale data.
 The custom setup command will download the most appropriate CLDR release from the
 official website and convert it for Babel.
@@ -96,4 +96,4 @@ official website and convert it for Babel.
 This will pull also in the dependencies and activate the git head as the
 current version inside the virtualenv.  Then all you have to do is run
 ``git pull origin`` to update to the latest version.  If the CLDR data
-changes you will have to re-run ``python setup.py import_cldr``.
+changes you will have to re-run ``make import-cldr``.
diff --git a/hatch_build.py b/hatch_build.py
new file mode 100644 (file)
index 0000000..ca5d13e
--- /dev/null
@@ -0,0 +1,33 @@
+import os
+import tarfile
+import zipfile
+
+from hatchling.builders.hooks.plugin.interface import BuildHookInterface
+
+DAT_MESSAGE = """
+======
+Package should contain multiple .dat files.
+* Make sure you've imported the CLDR data; `make import-cldr`.
+------
+To skip this check, set the environment variable BABEL_NO_CHECK_BUILD=1
+======
+""".strip()
+
+
+def check_babel_artifact(artifact_path: str):
+    if artifact_path.endswith(".whl"):
+        with zipfile.ZipFile(artifact_path) as whl:
+            filelist = whl.namelist()
+    elif artifact_path.endswith(".tar.gz"):
+        with tarfile.open(artifact_path) as tar:
+            filelist = tar.getnames()
+    if len([f.endswith(".dat") for f in filelist]) < 10:
+        raise ValueError(DAT_MESSAGE)
+
+
+class CustomBuildHook(BuildHookInterface):
+    def finalize(self, version, build_data, artifact_path):
+        if version == "editable":
+            return
+        if not os.environ.get("BABEL_NO_CHECK_BUILD"):
+            check_babel_artifact(artifact_path)
index 4918cc0346912d304e0de98239546d87b8f3e9eb..71fd3c764a737c359b8c2de49e257538cae93b27 100644 (file)
@@ -1,3 +1,116 @@
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[project]
+name = "babel"
+dynamic = ["version"]
+description = "Internationalization utilities"
+readme = "README.rst"
+license = "BSD-3-Clause"
+license-files = ["LICENSE"]
+requires-python = ">=3.8"
+authors = [
+    { name = "Armin Ronacher", email = "armin.ronacher@active-4.com" },
+]
+maintainers = [
+    { name = "Aarni Koskela", email = "akx@iki.fi" },
+]
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Environment :: Web Environment",
+    "Intended Audience :: Developers",
+    "License :: OSI Approved :: BSD License",
+    "Operating System :: OS Independent",
+    "Programming Language :: Python :: 3 :: Only",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.8",
+    "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Programming Language :: Python :: Implementation :: PyPy",
+    "Programming Language :: Python",
+    "Topic :: Software Development :: Internationalization",
+    "Topic :: Software Development :: Libraries :: Python Modules",
+]
+
+dependencies = [
+    # This version identifier is currently necessary as
+    # pytz otherwise does not install on pip 1.4 or higher.
+    # Python 3.9 and later include zoneinfo which replaces pytz.
+    'pytz>=2015.7; python_version<"3.9"',
+]
+
+[project.optional-dependencies]
+# TODO: use a `dev` dependency group instead
+dev = [
+    "backports.zoneinfo; python_version<\"3.9\"",
+    "freezegun~=1.0",
+    "jinja2>=3.0",
+    "pytest-cov",
+    "pytest>=6.0",
+    "pytz",
+    "setuptools",
+    "tzdata;sys_platform == 'win32'",
+]
+
+[project.urls]
+Homepage = "https://babel.pocoo.org/"
+Source = "https://github.com/python-babel/babel"
+
+[tool.hatch.version]
+path = "babel/__init__.py"
+
+[tool.hatch.build.hooks.custom]
+
+[tool.hatch.build.targets.sdist]
+include = [
+    "/Makefile",
+    "/babel",
+    "/docs",
+    "/scripts",
+    "/tests",
+    "AUTHORS",
+    "CHANGES.rst",
+    "conftest.py",
+    "tox.ini",
+]
+
+[tool.hatch.build.targets.wheel]
+include = [
+    "/babel",
+]
+artifacts = [
+    "**.dat",
+]
+exclude = [
+    "/babel/locale-data/.gitignore",
+]
+
+[project.scripts]
+pybabel = "babel.messages.frontend:main"
+
+[project.entry-points."distutils.commands"]
+compile_catalog = "babel.messages.setuptools_frontend:compile_catalog"
+extract_messages = "babel.messages.setuptools_frontend:extract_messages"
+init_catalog = "babel.messages.setuptools_frontend:init_catalog"
+update_catalog = "babel.messages.setuptools_frontend:update_catalog"
+
+[project.entry-points."distutils.setup_keywords"]
+message_extractors = "babel.messages.setuptools_frontend:check_message_extractors"
+
+[project.entry-points."babel.checkers"]
+num_plurals = "babel.messages.checkers:num_plurals"
+python_format = "babel.messages.checkers:python_format"
+
+[project.entry-points."babel.extractors"]
+ignore = "babel.messages.extract:extract_nothing"
+python = "babel.messages.extract:extract_python"
+javascript = "babel.messages.extract:extract_javascript"
+
 [tool.ruff]
 target-version = "py38"
 extend-exclude = [
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644 (file)
index 8183238..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[metadata]
-license_files = LICENSE
diff --git a/setup.py b/setup.py
deleted file mode 100755 (executable)
index 93e0bb7..0000000
--- a/setup.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import subprocess
-import sys
-
-from setuptools import Command, setup
-
-try:
-    from babel import __version__
-except SyntaxError as exc:
-    sys.stderr.write(f"Unable to import Babel ({exc}). Are you running a supported version of Python?\n")
-    sys.exit(1)
-
-
-class import_cldr(Command):
-    description = 'imports and converts the CLDR data'
-    user_options = []
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        subprocess.check_call([sys.executable, 'scripts/download_import_cldr.py'])
-
-
-setup(
-    name='babel',
-    version=__version__,
-    description='Internationalization utilities',
-    long_description='A collection of tools for internationalizing Python applications.',
-    author='Armin Ronacher',
-    author_email='armin.ronacher@active-4.com',
-    maintainer='Aarni Koskela',
-    maintainer_email='akx@iki.fi',
-    license='BSD-3-Clause',
-    url='https://babel.pocoo.org/',
-    project_urls={
-        'Source': 'https://github.com/python-babel/babel',
-    },
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Environment :: Web Environment',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: BSD License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3 :: Only',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'Programming Language :: Python :: 3.10',
-        'Programming Language :: Python :: 3.11',
-        'Programming Language :: Python :: 3.12',
-        'Programming Language :: Python :: 3.13',
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Programming Language :: Python :: Implementation :: PyPy',
-        'Topic :: Software Development :: Internationalization',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-    ],
-    python_requires='>=3.8',
-    packages=['babel', 'babel.messages', 'babel.localtime'],
-    package_data={"babel": ["py.typed"]},
-    include_package_data=True,
-    install_requires=[
-        # This version identifier is currently necessary as
-        # pytz otherwise does not install on pip 1.4 or
-        # higher.
-        # Python 3.9 and later include zoneinfo which replaces pytz
-        'pytz>=2015.7; python_version<"3.9"',
-    ],
-    extras_require={
-        'dev': [
-            "tzdata;sys_platform == 'win32'",
-            'backports.zoneinfo; python_version<"3.9"',
-            'freezegun~=1.0',
-            'jinja2>=3.0',
-            'pytest-cov',
-            'pytest>=6.0',
-            'pytz',
-            'setuptools',
-        ],
-    },
-    cmdclass={'import_cldr': import_cldr},
-    zip_safe=False,
-    # Note when adding extractors: builtin extractors we also want to
-    # work if packages are not installed to simplify testing.  If you
-    # add an extractor here also manually add it to the "extract"
-    # function in babel.messages.extract.
-    entry_points="""
-    [console_scripts]
-    pybabel = babel.messages.frontend:main
-
-    [distutils.commands]
-    compile_catalog = babel.messages.setuptools_frontend:compile_catalog
-    extract_messages = babel.messages.setuptools_frontend:extract_messages
-    init_catalog = babel.messages.setuptools_frontend:init_catalog
-    update_catalog = babel.messages.setuptools_frontend:update_catalog
-
-    [distutils.setup_keywords]
-    message_extractors = babel.messages.setuptools_frontend:check_message_extractors
-
-    [babel.checkers]
-    num_plurals = babel.messages.checkers:num_plurals
-    python_format = babel.messages.checkers:python_format
-
-    [babel.extractors]
-    ignore = babel.messages.extract:extract_nothing
-    python = babel.messages.extract:extract_python
-    javascript = babel.messages.extract:extract_javascript
-    """,
-)