From b9e4d1257f958bf68239c6820d3a1737c40a2733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 24 Dec 2025 16:43:51 +0100 Subject: [PATCH] chore: migrate the project to uv --- .coveragerc | 20 ----- .github/workflows/ci-tests.yml | 39 +++++----- .gitignore | 1 + CHANGELOG.rst | 1 + MANIFEST.in | 9 --- docs/contributing.rst | 81 ++++++++------------ pyproject.toml | 132 +++++++++++++++++++++++++++++++++ setup.cfg | 18 ----- setup.py | 73 ------------------ tox.ini | 40 ---------- 10 files changed, 185 insertions(+), 229 deletions(-) delete mode 100644 .coveragerc delete mode 100644 MANIFEST.in create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 45a256d..0000000 --- a/.coveragerc +++ /dev/null @@ -1,20 +0,0 @@ -[run] -include = - */webtest/*.py -omit = - */tests* - */docs/*.py - */site-packages* - */lib/python* - */lib-python* - */lib_pypy* - */src* - -[report] -exclude_lines = - pragma: no cover - def __repr__ - raise NotImplementedError - if __name__ == .__main__.: - def parse_args - diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 09a846a..6741475 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -36,14 +36,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Setup python - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.py }} - architecture: ${{ matrix.architecture }} - - run: pip install tox - - name: Running tox - run: tox -e py + enable-cache: true + - name: Run tests + run: uv run pytest + coverage: runs-on: ubuntu-latest name: Validate coverage @@ -51,22 +51,25 @@ jobs: # Choose the latest Python. steps: - uses: actions/checkout@v4 - - name: Setup python - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v5 with: - python-version: 3.12 - architecture: x64 - - run: pip install tox - - run: tox -e py312,coverage + python-version: "3.12" + enable-cache: true + - name: Run tests with coverage + run: uv run pytest --cov + - name: Check coverage + run: uv run coverage report --show-missing --fail-under=95 + docs: runs-on: ubuntu-latest name: Build the documentation steps: - uses: actions/checkout@v4 - - name: Setup python - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v5 with: - python-version: 3.12 - architecture: x64 - - run: pip install tox - - run: tox -e docs + python-version: "3.12" + enable-cache: true + - name: Build docs + run: uv run --group docs sphinx-build -W -E -b html docs docs/_build/html diff --git a/.gitignore b/.gitignore index 4b93d68..c42d537 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ docs/_themes/ .settings/ .coverage* eggs +uv.lock diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 774ed40..b98c53f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ News ------------------ - Nothing changed yet. +- Migrate the project to uv. 3.0.7 (2025-10-06) diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 0a259cb..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -graft docs -prune docs/_build -graft webtest -graft tests -graft .github -include *.md *.txt *.rst *.cfg *.ini .coveragerc -global-exclude *.pyc -global-exclude *.swp -global-exclude __pycache__ diff --git a/docs/contributing.rst b/docs/contributing.rst index f2acbbb..67bbd61 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -11,9 +11,7 @@ Get your working copy : $ git clone https://github.com/Pylons/webtest.git $ cd webtest - $ virtualenv . - $ . bin/activate - $ python setup.py dev + $ uv sync Now, you can hack. @@ -23,55 +21,42 @@ Execute tests .. code-block:: bash - $ bin/pytest - Doctest: forms.rst ... ok - Doctest: index.rst ... ok - - ... - - test_url_class (tests.test_testing.TestTesting) ... ok - tests.test_testing.test_print_unicode ... °C - ok - - Name Stmts Miss Cover Missing - ------------------------------------------------ - webtest 18 0 100% - webtest.app 603 92 85% 48, 61-62, 94, 98, 212-221, 264-265, 268-272, 347, 379-386, 422, 426-428, 432-434, 455, 463, 471, 473, 488, 496-497, 515, 520-527, 548, 553-554, 558-559, 577, 592, 597-598, 618, 624, 661-664, 742, 808, 872, 940-941, 945-948, 961-964, 975, 982, 995, 1000, 1006, 1010, 1049, 1051, 1095-1096, 1118-1119, 1122-1127, 1135-1136, 1148, 1155-1160, 1175 - webtest.compat 50 11 78% 28-34, 55-56, 61-62 - webtest.debugapp 58 0 100% - webtest.ext 80 0 100% - webtest.forms 324 23 93% 23, 49, 58, 61, 92, 116, 177, 205, 411, 478, 482-486, 491-493, 522, 538, 558-561 - webtest.http 78 0 100% - webtest.lint 215 45 79% 135, 176, 214-216, 219-224, 227-231, 234, 243-244, 247, 250-251, 254, 263-264, 270, 274, 307, 311, 335, 359, 407, 424-427, 441-444, 476-479, 493, 508 - webtest.sel 479 318 34% 38-39, 45-46, 64-78, 88-108, 120, 126, 151-153, 156-158, 164-165, 168-191, 194-201, 219-231, 236, 240, 243-259, 263-297, 301-306, 316-326, 331-336, 340, 344, 347-352, 357-359, 364, 392-394, 397-404, 408, 412-417, 421, 425-426, 430, 434, 438, 442, 445, 448-457, 470-480, 483-485, 488, 492, 495, 503, 506, 515-516, 520, 524, 528, 533, 538, 542-544, 547, 560-565, 576, 579, 582, 593-596, 599-602, 605-606, 617-620, 623-642, 668-677, 680-688, 715, 720, 732, 735, 744-754, 757-762, 770-779, 791, 794, 805-809, 813-826, 838-842 - webtest.utils 99 11 89% 19-20, 23, 26, 32, 38, 100, 109, 152-154 - ------------------------------------------------ - TOTAL 2004 500 75% - ---------------------------------------------------------------------- - Ran 70 tests in 14.940s + $ uv run pytest + ============================= test session starts ============================== + platform linux -- Python 3.14.0, pytest-9.0.2, pluggy-1.6.0 + rootdir: /home/user/webtest + configfile: pyproject.toml + plugins: cov-7.0.0 + collected 206 items + + tests/test_app.py ............................................ [ 21%] + tests/test_authorisation.py ... [ 22%] + tests/test_debugapp.py ...................... [ 33%] + tests/test_ext.py . [ 33%] + tests/test_forms.py .................................................... [ 59%] + . [ 59%] + tests/test_http.py .... [ 61%] + tests/test_lint.py ............................ [ 75%] + tests/test_response.py ............................... [ 90%] + tests/test_sel.py . [ 90%] + tests/test_utils.py .................. [ 99%] + webtest/forms.py . [100%] + + ============================= 206 passed in 3.81s ============================== Use tox to test many Python versions ==================================== -`Tox `_ installation : - -.. code-block:: bash - - $ pip install tox - $ tox - -Launch tests with *tox* : - .. code-block:: bash - $ bin/tox - py26: commands succeeded - py27: commands succeeded - py32: commands succeeded - py33: commands succeeded + $ uvx --with tox-uv tox + py39: commands succeeded + py310: commands succeeded + py311: commands succeeded + py312: commands succeeded -To execute test on all python versions, you need to have ``python2.6``, ``python2.7``, ``python3.2`` and ``python3.3`` in your ``PATH``. +To execute tests on all Python versions, you need to have ``python3.9``, ``python3.10``, ``python3.11`` and ``python3.12`` in your ``PATH``. Generate documentation @@ -79,16 +64,10 @@ Generate documentation .. code-block:: bash - $ pip install Sphinx $ cd docs $ make html - ../bin/sphinx-build -b html -d _build/doctrees . _build/html - Running Sphinx v1.1.3 - loading pickled environment... done - ... - - build succeeded, 3 warnings. + build succeeded. Build finished. The HTML pages are in _build/html. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..903bcd6 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,132 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "WebTest" +version = "3.0.8.dev0" +description = "Helper to test WSGI applications" +readme = "README.rst" +license = "MIT" +requires-python = ">=3.9" +authors = [ + { name = "Ian Bicking" }, +] +maintainers = [ + { name = "Gael Pasgrimaud", email = "gael@gawel.org" }, +] +keywords = ["wsgi", "test", "unit", "tests", "web"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Framework :: Paste", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "WebOb>=1.2", + "waitress>=3.0.2", + "beautifulsoup4", +] + +[project.urls] +Homepage = "https://docs.pylonsproject.org/projects/webtest/en/latest/" + +[dependency-groups] +dev = [ + "coverage", + "PasteDeploy", + "pyquery", + "pytest", + "pytest-cov", + "WSGIProxy2", +] +docs = [ + "docutils", + "pylons-sphinx-themes>=1.0.8", + "Sphinx>=3.0.0", +] + +[project.entry-points."paste.app_factory"] +debug = "webtest.debugapp:make_debug_app" + +[tool.pytest.ini_options] +addopts = [ + "-p", "no:warnings", + "--doctest-modules", + "--doctest-glob=*.rst", + "--ignore=docs/", + "--ignore=CHANGES.rst", + "--ignore=setup.py", + "--ignore=bootstrap.py", + "--ignore=examples/", + "--ignore=docs/conf.py", + "-W", "always", +] +doctest_optionflags = ["NORMALIZE_WHITESPACE", "ELLIPSIS"] + +[tool.hatch.build.targets.sdist] +include = [ + "webtest/", + "tests/", + "docs/", + "pyproject.toml", + "README.rst", + "CHANGELOG.rst", + "license.rst", +] + +[tool.hatch.build.targets.wheel] +packages = ["webtest"] + +[tool.coverage.run] +source_pkgs = ["webtest"] +branch = true +relative_files = true + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "raise NotImplementedError", + "if __name__ == .__main__.:", + "def parse_args", +] + +[tool.tox] +env_list = ["py39", "py310", "py311", "py312", "coverage", "docs"] +skip_missing_interpreters = true + +[tool.tox.env_run_base] +dependency_groups = ["dev"] +set_env = { LC_ALL = "C", LANG = "C", COVERAGE_FILE = ".coverage.{env_name}" } +commands = [ + ["python", "--version"], + ["pytest", "--cov", "{posargs}"], +] + +[tool.tox.env.coverage] +depends = ["py39", "py310", "py311", "py312"] +skip_install = true +deps = ["coverage"] +set_env = { COVERAGE_FILE = ".coverage" } +commands = [ + ["coverage", "combine"], + ["coverage", "xml"], + ["coverage", "report", "--show-missing", "--fail-under=95"], +] + +[tool.tox.env.docs] +base_python = ["python3.12"] +dependency_groups = ["docs"] +allowlist_externals = ["make"] +commands = [ + ["make", "-C", "docs", "html", "BUILDDIR={env_dir}", "SPHINXOPTS=-W -E"], +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 48413f8..0000000 --- a/setup.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[aliases] -dev = develop easy_install webtest[tests] - -[bdist_wheel] -universal=0 - -[tool:pytest] -addopts = -p no:warnings - --doctest-modules - --doctest-glob='*.rst' - --ignore=docs/ - --ignore=CHANGES.rst - --ignore=setup.py - --ignore=bootstrap.py - --ignore=examples/ - --ignore=docs/conf.py - -W always -doctest_optionflags= NORMALIZE_WHITESPACE ELLIPSIS diff --git a/setup.py b/setup.py deleted file mode 100644 index 6e195ab..0000000 --- a/setup.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup -from setuptools import find_packages - -version = '3.0.8.dev0' - -install_requires = [ - 'WebOb>=1.2', - 'waitress>=3.0.2', - 'beautifulsoup4', -] - -tests_require = [ - 'coverage', - 'PasteDeploy', - 'pyquery', - 'pytest', - 'pytest-cov', - 'WSGIProxy2', -] - -docs_extras = [ - 'docutils', - 'pylons-sphinx-themes >= 1.0.8', - 'Sphinx >= 3.0.0', -] - -setup(name='WebTest', - version=version, - description="Helper to test WSGI applications", - long_description=open('README.rst').read(), - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Framework :: Paste", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - ], - keywords='wsgi test unit tests web', - author='Ian Bicking', - maintainer='Gael Pasgrimaud', - maintainer_email='gael@gawel.org', - url='https://docs.pylonsproject.org/projects/webtest/en/latest/', - license='MIT', - packages=find_packages(exclude=[ - 'ez_setup', - 'examples', - 'tests', - 'bootstrap', - 'bootstrap-py3k', - ]), - include_package_data=True, - zip_safe=False, - python_requires='>=3.9', - install_requires=install_requires, - tests_require=tests_require, - extras_require={ - 'tests': tests_require, - 'docs': docs_extras, - }, - entry_points=""" - [paste.app_factory] - debug = webtest.debugapp:make_debug_app - """, - ) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 3aa74b3..0000000 --- a/tox.ini +++ /dev/null @@ -1,40 +0,0 @@ -[tox] -skip_missing_interpreters = true -envlist = - py39,py310,py311,py312 - coverage, - docs - -[testenv] -setenv = - LC_ALL=C - LANG=C - COVERAGE_FILE=.coverage.{envname} -extras = - tests -commands = - python --version - pip freeze - pytest --cov {posargs:} - -[testenv:coverage] -skip_install = true -deps = - coverage -setenv = - COVERAGE_FILE=.coverage -commands = - coverage combine - coverage xml - # We want to get this to 100, but for now we compromise. - # See https://github.com/Pylons/webtest/pull/231#issuecomment-729574898 - coverage report --show-missing --fail-under=96 - -[testenv:docs] -basepython = python3.12 -allowlist_externals = - make -commands = - make -C docs html BUILDDIR={envdir} "SPHINXOPTS=-W -E" -extras = - docs