diff --git a/.circleci/config.yml b/.circleci/config.yml index 10c257c3..aa2d99ea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -150,6 +150,33 @@ commands: - store_artifacts: path: htmlcov + install_librdkafka: + steps: + - run: + name: Instal pre-requirement to build confluent-kafka + command: | + mkdir -p /etc/apt/keyrings + wget -qO - https://packages.confluent.io/deb/8.1/archive.key | gpg --dearmor -o /etc/apt/keyrings/confluent.gpg + echo "Types: deb + URIs: https://packages.confluent.io/deb/8.3 + Suites: stable + Components: main + Architectures: $(dpkg --print-architecture) + Signed-by: /etc/apt/keyrings/confluent.gpg + + Types: deb + URIs: https://packages.confluent.io/clients/deb/ + Suites: trixie + Components: main + Architectures: $(dpkg --print-architecture) + Signed-By: /etc/apt/keyrings/confluent.gpg" | tee /etc/apt/sources.list.d/confluent-platform.sources > /dev/null + + - run: + name: Instal librdkafka + command: | + apt-get update + apt-get install -y --no-install-recommends build-essential python3-dev librdkafka-dev + jobs: python3x: parameters: @@ -196,9 +223,9 @@ jobs: - store-pytest-results - store-coverage-report - py39gevent: + py312gevent: docker: - - image: public.ecr.aws/docker/library/python:3.9 + - image: public.ecr.aws/docker/library/python:3.12 working_directory: ~/repo steps: - checkout @@ -214,9 +241,12 @@ jobs: - store-pytest-results - store-coverage-report - py312aws: + pyaws: + parameters: + py-version: + type: string docker: - - image: public.ecr.aws/docker/library/python:3.12 + - image: public.ecr.aws/docker/library/python:<> working_directory: ~/repo steps: - checkout @@ -227,7 +257,7 @@ jobs: - run-tests-with-coverage-report: tests: "tests_aws" - capture-installed-versions: - label: "aws" + label: "aws-<>" - store-pytest-results - store-coverage-report @@ -291,6 +321,7 @@ jobs: steps: - checkout - check-if-tests-needed + - install_librdkafka - pip-install-deps - pip-install-tests-deps: requirements: "tests/requirements-kafka.txt" @@ -324,7 +355,7 @@ jobs: final_job: docker: - - image: public.ecr.aws/docker/library/python:3.13 + - image: public.ecr.aws/docker/library/python:latest working_directory: ~/repo steps: - checkout @@ -354,23 +385,26 @@ workflows: - python3x: matrix: parameters: - py-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] - - py39gevent - - py312aws + py-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + - py312gevent + - pyaws: + matrix: + parameters: + py-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] - py312cassandra - pykafka: matrix: parameters: - py-version: ["3.9", "3.12", "3.14"] + py-version: ["3.10", "3.12", "3.14", "3.15"] - autowrapt: matrix: parameters: - py-version: ["3.11", "3.12", "3.13", "3.14"] + py-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] - final_job: requires: - python3x - - py39gevent - - py312aws + - py312gevent + - pyaws - py312cassandra - pykafka - autowrapt @@ -381,8 +415,8 @@ workflows: - main requires: - python3x - - py39gevent - - py312aws + - py312gevent + - pyaws - py312cassandra - pykafka - final_job diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0d6ae7c..ee582874 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -120,7 +120,7 @@ linter + test suite). ## Coding Style -- Python 3.9+ compatible code +- Python 3.10+ compatible code - Follow PEP 8 style guidelines (enforced by Ruff) - Include copyright headers in new files (see [Legal](#legal) section) - Use type hints where appropriate diff --git a/Dockerfile b/Dockerfile index ba04c9c6..e79d33a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Development Container -FROM public.ecr.aws/docker/library/python:3.14-slim +FROM public.ecr.aws/docker/library/python:3.15-slim RUN apt-get -y -qq update && \ apt-get -y -qq upgrade && \ diff --git a/bin/aws-lambda/build_and_publish_lambda_layer.py b/bin/aws-lambda/build_and_publish_lambda_layer.py index 3b598ba2..b0e0db6c 100755 --- a/bin/aws-lambda/build_and_publish_lambda_layer.py +++ b/bin/aws-lambda/build_and_publish_lambda_layer.py @@ -173,11 +173,12 @@ "--zip-file", aws_zip_filename, "--compatible-runtimes", - "python3.9", "python3.10", "python3.11", "python3.12", "python3.13", + "python3.14", + "python3.15", "--compatible-architectures", "x86_64", "arm64", diff --git a/pyproject.toml b/pyproject.toml index 8fa29c53..f02378ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ dynamic = [ ] description = "Python Distributed Tracing & Metrics Sensor for Instana." readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" license = "MIT" keywords = [ "performance", @@ -31,12 +31,12 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", - "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 :: 3.14", + "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", "Topic :: System :: Monitoring", @@ -47,7 +47,7 @@ dependencies = [ "autowrapt>=1.0", "fysom>=2.1.2", "requests>=2.6.0", - "urllib3>=1.26.5", + "urllib3>=2.7.0", "opentelemetry-api>=1.27.0", "opentelemetry-semantic-conventions>=0.48b0", "typing_extensions>=4.12.2", @@ -98,7 +98,7 @@ exclude_also = [ [tool.ruff] # https://docs.astral.sh/ruff/configuration/ -target-version = "py39" +target-version = "py310" # In addition to the standard set of exclusions, omit all tests, plus a specific file. extend-exclude = [".bob", "bin", ".github", ".circleci", ".tekton"] preview = true diff --git a/src/instana/autoprofile/profiler.py b/src/instana/autoprofile/profiler.py index dc417c46..b4f82f2a 100644 --- a/src/instana/autoprofile/profiler.py +++ b/src/instana/autoprofile/profiler.py @@ -53,8 +53,8 @@ def start(self, **kwargs: Dict[str, Any]) -> None: return try: - if not min_version(3, 9): - raise EnvironmentError("Supported Python versions: 3.9 or higher.") + if not min_version(3, 10): + raise EnvironmentError("Supported Python versions: 3.10 or higher.") if platform.python_implementation() != "CPython": raise EnvironmentError("Supported Python interpreter: CPython.") diff --git a/tests/conftest.py b/tests/conftest.py index 8e87abf3..e9b1ca23 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,12 +32,10 @@ # ppc64le and s390x have limitations with some supported libraries. if is_ppc64() or is_s390x(): - collect_ignore_glob.extend( - [ - "*test_google-cloud*", - "*test_pymongo*", - ] - ) + collect_ignore_glob.extend([ + "*test_google-cloud*", + "*test_pymongo*", + ]) if is_ppc64(): collect_ignore_glob.append("*test_grpcio*") @@ -51,42 +49,18 @@ collect_ignore_glob.append("*test_couchbase*") if not os.environ.get("GEVENT_TEST"): - collect_ignore_glob.extend( - [ - "*test_gevent*", - ] - ) + collect_ignore_glob.extend([ + "*test_gevent*", + ]) if not os.environ.get("KAFKA_TEST"): collect_ignore_glob.append("*kafka/test*") -# Currently asyncio and tornado_server depends on aiohttp and -# since aiohttp versions < 3.12.14 have vulnerability we skip the tests below -if sys.version_info < (3, 9): - collect_ignore_glob.extend( - [ - "*test_aiohttp*", - "*test_asyncio*", - "*test_tornado_server*", - ] - ) - +# Spyne does not support python > 3.12 if sys.version_info >= (3, 12): - # Currently Spyne does not support python > 3.12 collect_ignore_glob.append("*test_spyne*") -if sys.version_info >= (3, 15): - collect_ignore_glob.extend( - [ - # Currently not installable dependencies because of 3.15 incompatibilities - "*test_fastapi*", - # Development version of Python always break logging tests, so we skip then - "*test_logging*", - ] - ) - - @pytest.fixture(scope="session") def celery_config(): return { diff --git a/tests/frameworks/test_fastapi.py b/tests/frameworks/test_fastapi.py index ab62245b..f1f06536 100644 --- a/tests/frameworks/test_fastapi.py +++ b/tests/frameworks/test_fastapi.py @@ -2,7 +2,6 @@ # (c) Copyright Instana Inc. 2020 -import sys from typing import Generator import pytest @@ -64,10 +63,6 @@ def assert_fastapi_otel_spans( assert tags["http.response.status_code"] == http_status_code -@pytest.mark.skipif( - sys.version_info < (3, 10), - reason="FastAPI >= 0.115.0 (required for OTel span assertions) only supports Python 3.10+", -) class TestFastAPI: @pytest.fixture(autouse=True) def _resource(self) -> Generator[None, None, None]: diff --git a/tests/requirements-pre315.txt b/tests/requirements-pre315.txt deleted file mode 100644 index 6a6bcd98..00000000 --- a/tests/requirements-pre315.txt +++ /dev/null @@ -1,49 +0,0 @@ -# requirements-minimal.txt --r requirements-minimal.txt -pytest-timeout>=2.4.0 -# setuptools upperbound pinning is temporary and will remain in place until -# packages resolve the failures caused by the pkg_resources deprecation. -setuptools<=81.0.0 -# requirements.txt -aioamqp>=0.15.0 -aiofiles>=0.5.0 -aiohttp>=3.12.14 -aio-pika>=9.5.2 -boto3>=1.17.74 -bottle>=0.12.25 -celery>=5.2.7 -Django>=4.2.16 -# fastapi>=0.115.0 -flask>=2.3.2 -grpcio>=1.14.1 -google-cloud-pubsub>=2.0.0 -google-cloud-storage>=1.24.0 -legacy-cgi>=2.6.1 -lxml>=4.9.2 -mock>=4.0.3 -moto>=4.1.2 -mysqlclient>=2.0.3 -PyMySQL[rsa]>=1.0.2 -psycopg2-binary>=2.9.12 -pika>=1.2.0 -# protobuf<=6.30.2 -pymongo>=3.11.4 -pyramid>=2.0.1 -pytest-mock>=3.12.0 -pytz>=2024.1 -redis>=3.5.3 -requests-mock -responses<=0.17.0 -sanic>=19.9.0 -sanic-testing>=24.6.0 -spyne>=2.14.0 -sqlalchemy>=2.0.0 -starlette>=0.38.2; -tornado>=6.4.1 -uvicorn>=0.13.4 -urllib3>=1.26.5 -httpx>=0.27.0 -gevent>=23.9.0.post1 -confluent-kafka>=2.0.0 -kafka-python>=2.0.0 - diff --git a/tests/requirements.txt b/tests/requirements.txt index 57b47522..6017fc46 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,7 +1,7 @@ -r requirements-minimal.txt aioamqp>=0.15.0 aiofiles>=0.5.0 -aiohttp>=3.12.14; python_version >= "3.9" +aiohttp>=3.12.14 aio-pika>=9.5.2 boto3>=1.17.74 bottle>=0.12.25 @@ -14,7 +14,7 @@ flask>=2.3.2 grpcio>=1.14.1 google-cloud-pubsub>=2.0.0 google-cloud-storage>=1.24.0 -legacy-cgi>=2.6.1; python_version == "3.13" +legacy-cgi>=2.6.1; python_version >= "3.13" lxml>=4.9.2 mock>=4.0.3 moto>=4.1.2 @@ -31,15 +31,13 @@ elasticsearch>=8.0.0 redis>=3.5.3 requests-mock responses<=0.17.0 -sanic<=24.6.0; python_version < "3.9" -sanic>=19.9.0; python_version >= "3.9" +sanic>=19.9.0 sanic-testing>=24.6.0 spyne>=2.14.0; python_version < "3.12" sqlalchemy>=2.0.0 -starlette>=0.38.2; python_version == "3.13" +starlette>=0.38.2; python_version >= "3.13" tornado>=6.4.1 twisted>=24.3.0 -tracerite<=1.1.1; python_version < "3.9" uvicorn>=0.13.4 urllib3>=1.26.5 httpx>=0.27.0 diff --git a/tests_aws/01_lambda/conftest.py b/tests_aws/01_lambda/conftest.py index a7b217c6..8489a26c 100644 --- a/tests_aws/01_lambda/conftest.py +++ b/tests_aws/01_lambda/conftest.py @@ -6,11 +6,11 @@ import pytest -os.environ["AWS_EXECUTION_ENV"] = "AWS_Lambda_python_3.10" +os.environ["AWS_EXECUTION_ENV"] = "AWS_Lambda_python_3.11" from instana.collector.base import BaseCollector -if sys.version_info <= (3, 8): +if sys.version_info <= (3, 11): print("Python runtime version not supported by AWS Lambda.") exit(1)