diff --git a/.github/common.env b/.github/common.env index 1bd0bc72b..152504fd6 100644 --- a/.github/common.env +++ b/.github/common.env @@ -1,6 +1,6 @@ # Shared common variables CI_IMAGE_VERSION=master-2057058575 -CI_TOXENV_MAIN=py39,py310,py311,py312,py313,py314 -CI_TOXENV_PLUGINS=py39-plugins,py310-plugins,py311-plugins,py312-plugins,py313-plugins,py314-plugins +CI_TOXENV_MAIN=py310,py311,py312,py313,py314 +CI_TOXENV_PLUGINS=py310-plugins,py311-plugins,py312-plugins,py313-plugins,py314-plugins CI_TOXENV_ALL="${CI_TOXENV_MAIN},${CI_TOXENV_PLUGINS}" diff --git a/.github/compose/ci.docker-compose.yml b/.github/compose/ci.docker-compose.yml index 75ecc995f..e9797bd58 100644 --- a/.github/compose/ci.docker-compose.yml +++ b/.github/compose/ci.docker-compose.yml @@ -22,10 +22,6 @@ x-tests-template: &tests-template services: - debian-11: - <<: *tests-template - image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-debian:11-${CI_IMAGE_VERSION:-latest} - debian-12: <<: *tests-template image: registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-debian:12-${CI_IMAGE_VERSION:-latest} @@ -102,11 +98,6 @@ services: # on the PyPA official 'manylinux' images that define the base ABI for # Python binary packages. - wheels-manylinux_2_28-cp39: - <<: *tests-template - image: quay.io/pypa/manylinux_2_28_x86_64 - command: .github/wheel-helpers/test-wheel-manylinux.sh cp39 /opt/python/cp39-cp39/bin/python3 - wheels-manylinux_2_28-cp310: <<: *tests-template image: quay.io/pypa/manylinux_2_28_x86_64 diff --git a/.github/run-ci.sh b/.github/run-ci.sh index 9c6164249..8118d0abd 100755 --- a/.github/run-ci.sh +++ b/.github/run-ci.sh @@ -102,7 +102,7 @@ function runServiceTest() { if [ -z "${test_names}" ]; then - for test_name in mypy debian-11 debian-12 debian-13 fedora-42 fedora-43 fedora-missing-deps ubuntu-22.04; do + for test_name in mypy debian-12 debian-13 fedora-42 fedora-43 fedora-missing-deps ubuntu-22.04; do if ! runTest "${test_name}"; then echo "Tests failed" exit 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17d4f1b90..07faedc0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,6 @@ jobs: # The names here should map to a valid service defined in # "../compose/ci.docker-compose.yml" test-name: - - debian-11 - debian-12 - debian-13 - fedora-42 @@ -154,7 +153,6 @@ jobs: # The names here should map to a valid service defined in # "../compose/ci.docker-compose.yml" test-name: - - wheels-manylinux_2_28-cp39 - wheels-manylinux_2_28-cp310 - wheels-manylinux_2_28-cp311 - wheels-manylinux_2_28-cp312 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b81151f6..7de62f6e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,7 +89,6 @@ jobs: # The names here should map to a valid service defined in # "../compose/ci.docker-compose.yml" test-name: - - wheels-manylinux_2_28-cp39 - wheels-manylinux_2_28-cp310 - wheels-manylinux_2_28-cp311 - wheels-manylinux_2_28-cp312 diff --git a/.pylintrc b/.pylintrc index 1f7fff44c..2e416f936 100644 --- a/.pylintrc +++ b/.pylintrc @@ -57,10 +57,6 @@ persistent=yes # source root. source-roots=src -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages -suggestion-mode=yes - # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no diff --git a/doc/source/main_install.rst b/doc/source/main_install.rst index 6bf635811..7714c6cd6 100644 --- a/doc/source/main_install.rst +++ b/doc/source/main_install.rst @@ -35,7 +35,7 @@ Runtime requirements BuildStream requires the following Python environment to run: -- python3 >= 3.9 +- python3 >= 3.10 - PyPI packages as specified in `requirements.in `_. diff --git a/pyproject.toml b/pyproject.toml index 7c6008b57..0c0516731 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ build-frontend = "build" environment = { BST_BUNDLE_BUILDBOX = "1" } # The BuildBox binaries produced in buildbox-integration are linked against GLIBC 2.28 -# from Debian 10. See: https://gitlab.com/BuildGrid/buildbox/buildbox-integration. +# from Rocky Linux 8.10. See: https://gitlab.com/BuildGrid/buildbox/buildbox-integration. # # The PyPA manylinux_2_28 platform tag identifies that our wheel will run on any x86_64 # OS with GLIBC >= 2.28. Following this setting, `cibuildwheel` builds the packages in @@ -53,10 +53,6 @@ environment = { BST_BUNDLE_BUILDBOX = "1" } manylinux-x86_64-image = "manylinux_2_28" skip = [ - # BuildStream supports Python >= 3.9 - "cp36-*", - "cp37-*", - "cp38-*", # PyPy may work, but nobody is testing it so avoid distributing prebuilt binaries. "pp*", # Skipping this niche archicture ~halves overall build time. diff --git a/requirements/cov-requirements.txt b/requirements/cov-requirements.txt index df985cbbc..d8a6a63fb 100644 --- a/requirements/cov-requirements.txt +++ b/requirements/cov-requirements.txt @@ -1,12 +1,12 @@ -coverage==7.10.7 +coverage==7.11.0 pytest-cov==7.0.0 pytest==8.4.2 -Cython==3.1.4 +Cython==3.1.6 ## The following requirements were added by pip freeze: exceptiongroup==1.3.0 -iniconfig==2.1.0 +iniconfig==2.3.0 packaging==25.0 pluggy==1.6.0 Pygments==2.19.2 -tomli==2.2.1 +tomli==2.3.0 typing_extensions==4.15.0 diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index a813f964c..b75f2a1da 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -1,25 +1,25 @@ pexpect==4.9.0 -pylint==3.3.8 +pylint==4.0.2 # Pytest 6.0.0 doesn't play well with pylint pytest==8.4.2 pytest-datafiles==3.0.0 -pytest-env==1.1.5 +pytest-env==1.2.0 pytest-xdist==3.8.0 pytest-timeout==2.4.0 -pyftpdlib==2.0.1 +pyftpdlib==2.1.0 ## The following requirements were added by pip freeze: -astroid==3.3.11 +astroid==4.0.1 dill==0.4.0 exceptiongroup==1.3.0 execnet==2.1.1 -iniconfig==2.1.0 -isort==6.0.1 +iniconfig==2.3.0 +isort==7.0.0 mccabe==0.7.0 packaging==25.0 -platformdirs==4.4.0 +platformdirs==4.5.0 pluggy==1.6.0 ptyprocess==0.7.0 Pygments==2.19.2 -tomli==2.2.1 +tomli==2.3.0 tomlkit==0.13.3 typing_extensions==4.15.0 diff --git a/requirements/requirements.in b/requirements/requirements.in index 232bbc4b2..73b011fda 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -1,7 +1,6 @@ Click >= 7.0, != 8.2.2 grpcio Jinja2 >= 2.10 -importlib_metadata >= 3.6; python_version < "3.10" packaging pluginbase protobuf <9,>=5.29 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 1aa46885c..bccec9ed4 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,16 +1,14 @@ -click==8.1.8 -grpcio==1.75.0 +click==8.3.0 +grpcio==1.76.0 Jinja2==3.1.6 -importlib_metadata==8.7.0 packaging==25.0 pluginbase==1.0.1 -protobuf==6.32.1 -psutil==7.1.0 -ruamel.yaml==0.18.15 +protobuf==6.33.0 +psutil==7.1.3 +ruamel.yaml==0.18.16 ruamel.yaml.clib==0.2.14 -pyroaring==1.0.2 +pyroaring==1.0.3 ujson==5.11.0 ## The following requirements were added by pip freeze: -MarkupSafe==3.0.2 +MarkupSafe==3.0.3 typing_extensions==4.15.0 -zipp==3.23.0 diff --git a/setup.cfg b/setup.cfg index 469e2b257..f421d161d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,6 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +[options] +python_requires = >=3.10 + [versioneer] VCS = git style = pep440 diff --git a/setup.py b/setup.py index 3c6aecb95..4628f299e 100755 --- a/setup.py +++ b/setup.py @@ -44,10 +44,10 @@ # Python requirements ################################################################## REQUIRED_PYTHON_MAJOR = 3 -REQUIRED_PYTHON_MINOR = 9 +REQUIRED_PYTHON_MINOR = 10 if sys.version_info[0] != REQUIRED_PYTHON_MAJOR or sys.version_info[1] < REQUIRED_PYTHON_MINOR: - print("BuildStream requires Python >= 3.9") + print("BuildStream requires Python >= " + str(REQUIRED_PYTHON_MAJOR) + "." + str(REQUIRED_PYTHON_MINOR)) sys.exit(1) try: @@ -322,7 +322,6 @@ def files_from_module(modname): "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/src/buildstream/_frontend/complete.py b/src/buildstream/_frontend/complete.py index 787db6d30..5622ce612 100644 --- a/src/buildstream/_frontend/complete.py +++ b/src/buildstream/_frontend/complete.py @@ -36,7 +36,13 @@ import click from click.core import Option, Argument -from click.parser import split_arg_string + +try: + # Click >= 8.2 + from click.shell_completion import split_arg_string +except ImportError: + # Click < 8.2 + from click.parser import split_arg_string # type: ignore if TYPE_CHECKING or click.Command.__bases__ == (object,): # Click >= 8.2 diff --git a/src/buildstream/_pluginfactory/pluginoriginpip.py b/src/buildstream/_pluginfactory/pluginoriginpip.py index 2fe4563cd..9c566bef6 100644 --- a/src/buildstream/_pluginfactory/pluginoriginpip.py +++ b/src/buildstream/_pluginfactory/pluginoriginpip.py @@ -12,7 +12,6 @@ # limitations under the License. # import os -import sys from .._exceptions import PluginError @@ -34,11 +33,7 @@ def __init__(self): def get_plugin_paths(self, kind, plugin_type): from packaging.requirements import Requirement, InvalidRequirement - - if sys.version_info >= (3, 10): - from importlib.metadata import distribution, PackageNotFoundError - else: - from importlib_metadata import distribution, PackageNotFoundError + from importlib.metadata import distribution, PackageNotFoundError # Sources and elements are looked up in separate # entrypoint groups from the same package. diff --git a/tests/conftest.py b/tests/conftest.py index aa8e60838..f151bfdc7 100755 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,8 +15,8 @@ # Authors: # Tristan Maat # +from importlib.metadata import entry_points import os -import sys import pytest @@ -29,11 +29,6 @@ from tests.testutils.repo.tar import Tar -if sys.version_info >= (3, 10): - from importlib.metadata import entry_points -else: - from importlib_metadata import entry_points - # # This file is loaded by pytest, we use it to add a custom diff --git a/tox.ini b/tox.ini index 62362f64e..bb67161da 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,7 @@ # Tox global configuration # [tox] -envlist = py{39,310,311,312,313,314} +envlist = py{310,311,312,313,314} skip_missing_interpreters = true isolated_build = true @@ -33,30 +33,30 @@ BST_PLUGINS_VERSION = 79649529cffb695d0d22195ed9a4910c80ca6907 # 2.5.0 [testenv] usedevelop = # This is required by Cython in order to get coverage for cython files. - py{39,310,311,312,313,314}-!nocover: True + py{310,311,312,313,314}-!nocover: True commands = # Running with coverage reporting enabled - py{39,310,311,312,313,314}-!plugins-!nocover: pytest --basetemp {envtmpdir} --cov=buildstream --cov-config .coveragerc {posargs} + py{310,311,312,313,314}-!plugins-!nocover: pytest --basetemp {envtmpdir} --cov=buildstream --cov-config .coveragerc {posargs} # Running with coverage reporting disabled - py{39,310,311,312,313,314}-!plugins-nocover: pytest --basetemp {envtmpdir} {posargs} + py{310,311,312,313,314}-!plugins-nocover: pytest --basetemp {envtmpdir} {posargs} # Running external plugins tests with coverage reporting enabled - py{39,310,311,312,313,314}-plugins-!nocover: pytest --basetemp {envtmpdir} --cov=buildstream --cov-config .coveragerc --plugins {posargs} + py{310,311,312,313,314}-plugins-!nocover: pytest --basetemp {envtmpdir} --cov=buildstream --cov-config .coveragerc --plugins {posargs} # Running external plugins tests with coverage disabled - py{39,310,311,312,313,314}-plugins-nocover: pytest --basetemp {envtmpdir} --plugins {posargs} + py{310,311,312,313,314}-plugins-nocover: pytest --basetemp {envtmpdir} --plugins {posargs} commands_post: - py{39,310,311,312,313,314}-!nocover: mkdir -p .coverage-reports - py{39,310,311,312,313,314}-!nocover: mv {envtmpdir}/.coverage {toxinidir}/.coverage-reports/.coverage.{env:COVERAGE_PREFIX:}{envname} + py{310,311,312,313,314}-!nocover: mkdir -p .coverage-reports + py{310,311,312,313,314}-!nocover: mv {envtmpdir}/.coverage {toxinidir}/.coverage-reports/.coverage.{env:COVERAGE_PREFIX:}{envname} deps = - py{39,310,311,312,313,314}: -rrequirements/requirements.txt - py{39,310,311,312,313,314}: -rrequirements/dev-requirements.txt - py{39,310,311,312,313,314}: git+https://github.com/apache/buildstream-plugins.git@{env:BST_PLUGINS_VERSION:{[config]BST_PLUGINS_VERSION}} + py{310,311,312,313,314}: -rrequirements/requirements.txt + py{310,311,312,313,314}: -rrequirements/dev-requirements.txt + py{310,311,312,313,314}: git+https://github.com/apache/buildstream-plugins.git@{env:BST_PLUGINS_VERSION:{[config]BST_PLUGINS_VERSION}} # Install local sample plugins for testing pip plugin origins - py{39,310,311,312,313,314}: {toxinidir}/tests/plugins/sample-plugins + py{310,311,312,313,314}: {toxinidir}/tests/plugins/sample-plugins # Install external plugins for plugin tests - py{39,310,311,312,313,314}-plugins: git+https://gitlab.com/buildstream/buildstream-plugins-community.git@{env:BST_PLUGINS_COMMUNITY_VERSION:{[config]BST_PLUGINS_COMMUNITY_VERSION}}#egg=bst_plugins_community[deb] + py{310,311,312,313,314}-plugins: git+https://gitlab.com/buildstream/buildstream-plugins-community.git@{env:BST_PLUGINS_COMMUNITY_VERSION:{[config]BST_PLUGINS_COMMUNITY_VERSION}}#egg=bst_plugins_community[deb] # Only require coverage and pytest-cov when using it !nocover: -rrequirements/cov-requirements.txt @@ -84,18 +84,18 @@ passenv = # These keys are not inherited by any other sections # setenv = - py{39,310,311,312,313,314}: COVERAGE_FILE = {envtmpdir}/.coverage - py{39,310,311,312,313,314}: BST_TEST_HOME = {envtmpdir} - py{39,310,311,312,313,314}: BST_TEST_XDG_CACHE_HOME = {envtmpdir}/cache - py{39,310,311,312,313,314}: BST_TEST_XDG_CONFIG_HOME = {envtmpdir}/config - py{39,310,311,312,313,314}: BST_TEST_XDG_DATA_HOME = {envtmpdir}/share + py{310,311,312,313,314}: COVERAGE_FILE = {envtmpdir}/.coverage + py{310,311,312,313,314}: BST_TEST_HOME = {envtmpdir} + py{310,311,312,313,314}: BST_TEST_XDG_CACHE_HOME = {envtmpdir}/cache + py{310,311,312,313,314}: BST_TEST_XDG_CONFIG_HOME = {envtmpdir}/config + py{310,311,312,313,314}: BST_TEST_XDG_DATA_HOME = {envtmpdir}/share # This is required to get coverage for Cython - py{39,310,311,312,313,314}-!nocover: BST_CYTHON_TRACE = 1 + py{310,311,312,313,314}-!nocover: BST_CYTHON_TRACE = 1 randomized: PYTEST_ADDOPTS="--random-order-bucket=global" allowlist_externals = - py{39,310,311,312,313,314}: + py{310,311,312,313,314}: mv mkdir