diff --git a/scripts/populate_tox/README.md b/scripts/populate_tox/README.md index 8014acff3f..68e72a8ca7 100644 --- a/scripts/populate_tox/README.md +++ b/scripts/populate_tox/README.md @@ -16,8 +16,8 @@ The `populate_tox.py` script fills out the auto-generated part of that template. It does this by querying PyPI for each framework's package and its metadata and then determining which versions make sense to test to get good coverage. -The lowest supported and latest version of a framework are always tested, with -a number of releases in between: +By default, the lowest supported and latest version of a framework are always +tested, with a number of releases in between: - If the package has majors, we pick the highest version of each major. - If the package doesn't have multiple majors, we pick two versions in between lowest and highest. @@ -34,7 +34,8 @@ the main package (framework, library) to test with; any additional test dependencies, optionally gated behind specific conditions; and optionally the Python versions to test on. -Constraints are defined using the format specified below. The following sections describe each key. +Constraints are defined using the format specified below. The following sections +describe each key. ``` integration_name: { @@ -43,7 +44,7 @@ integration_name: { rule1: [package1, package2, ...], rule2: [package3, package4, ...], }, - "python": python_version_specifier, + "python": python_version_specifier | dict[package_version_specifier, python_version_specifier], "include": package_version_specifier, "integration_name": integration_name, "num_versions": int, @@ -102,15 +103,14 @@ Python versions, you can say: ... } ``` + This key is optional. ### `python` Sometimes, the whole test suite should only run on specific Python versions. -This can be achieved via the `python` key. - -There are two variants how to define the Python versions to run the test suite -on. +This can be achieved via the `python` key. There are two variants how to define +the Python versions to run the test suite on. If you want the test suite to only be run on specific Python versions, you can set `python` to a version specifier. For example, if you want AIOHTTP tests to @@ -142,18 +142,17 @@ say: The `python` key is optional, and when possible, it should be omitted. The script should automatically detect which Python versions the package supports. However, if a package has broken metadata or the SDK is explicitly not supporting some -packages on specific Python versions (because of, for example, broken context -vars), the `python` key can be used. +packages on specific Python versions, the `python` key can be used. ### `include` -Sometimes we only want to consider testing some specific versions of packages. -For example, the Starlite package has two alpha prereleases of version 2.0.0, but -we do not want to test these, since Starlite 2.0 was renamed to Litestar. +Sometimes we only want to test specific versions of packages. For example, the +Starlite package has two alpha prereleases of version 2.0.0, but we do not want +to test these, since Starlite 2.0 was renamed to Litestar. The value of the `include` key expects a version specifier defining which versions should be considered for testing. For example, since we only want to test -versions below 2.x in Starlite, we can use +versions below 2.x in Starlite, we can use: ```python "starlite": { @@ -178,13 +177,21 @@ be expressed like so: Sometimes, the name of the test suite doesn't match the name of the integration. For example, we have the `openai_base` and `openai_notiktoken` test suites, both -of which are actually testing the `openai` integration. If this is the case, you can use the `integration_name` key to define the name of the integration. If not provided, it will default to the name of the test suite. +of which are actually testing the `openai` integration. If this is the case, you +can use the `integration_name` key to define the name of the integration. If not +provided, it will default to the name of the test suite. -Linking an integration to a test suite allows the script to access integration configuration like for example the minimum version defined in `sentry_sdk/integrations/__init__.py`. +Linking an integration to a test suite allows the script to access integration +configuration like, for example, the minimum supported version defined in +`sentry_sdk/integrations/__init__.py`. ### `num_versions` -With this option you can tweak the default version picking behavior by specifying how many package versions should be tested. It accepts an integer equal to or greater than 2, as the oldest and latest supported versions will always be picked. Additionally, if there is a recent prerelease, it'll also always be picked (this doesn't count towards `num_versions`). +With this option you can tweak the default version picking behavior by specifying +how many package versions should be tested. It accepts an integer equal to or +greater than 2, as the oldest and latest supported versions will always be +picked. Additionally, if there is a recent prerelease, it'll also always be +picked (this doesn't count towards `num_versions`). ## How-Tos @@ -202,26 +209,3 @@ With this option you can tweak the default version picking behavior by specifyin `scripts/split_tox_gh_actions/split_tox_gh_actions.py`. 4. Add the `TESTPATH` for the test suite in `tox.jinja`'s `setenv` section. 5. Run `scripts/generate-test-files.sh` and commit the changes. - -### Migrate a test suite to populate_tox.py - -A handful of integration test suites are still hardcoded. The goal is to migrate -them all to `populate_tox.py` over time. - -1. Remove the integration from the `IGNORE` list in `populate_tox.py`. -2. Remove the hardcoded entries for the integration from the `envlist` and `deps` sections of `tox.jinja`. -3. Run `scripts/generate-test-files.sh`. -4. Run the test suite, either locally or by creating a PR. -5. Address any test failures that happen. - -You might have to introduce additional version bounds on the dependencies of the -package. Try to determine the source of the failure and address it. - -Common scenarios: -- An old version of the tested package installs a dependency without defining - an upper version bound on it. A new version of the dependency is installed that - is incompatible with the package. In this case you need to determine which - versions of the dependency don't contain the breaking change and restrict this - in `TEST_SUITE_CONFIG`. -- Tests are failing on an old Python version. In this case first double-check - whether we were even testing them on that version in the original `tox.ini`. diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 28a9fe8334..070ce82492 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -1,5 +1,7 @@ """ This script populates tox.ini automatically using release data from PyPI. + +See scripts/populate_tox/README.md for more info. """ import functools @@ -123,6 +125,7 @@ def _save_to_cache(package: str, version: Version, release: Optional[dict]) -> N releases_cache.write(json.dumps(_normalize_release(release)) + "\n") CACHE[_normalize_name(package)][str(version)] = release + CACHE[_normalize_name(package)][str(version)]["_accessed"] = True def _prefilter_releases( @@ -150,7 +153,8 @@ def _prefilter_releases( min_supported = Version(".".join(map(str, min_supported))) else: print( - f" {integration} doesn't have a minimum version defined in sentry_sdk/integrations/__init__.py. Consider defining one" + f" {integration} doesn't have a minimum version defined in " + f"sentry_sdk/integrations/__init__.py. Consider defining one" ) include_versions = None @@ -225,7 +229,8 @@ def get_supported_releases( Get a list of releases that are currently supported by the SDK. This takes into account a handful of parameters (Python support, the lowest - version we've defined for the framework, the date of the release). + supported version we've defined for the framework, optionally the date + of the release). We return the list of supported releases and optionally also the newest prerelease, if it should be tested (meaning it's for a version higher than @@ -272,9 +277,9 @@ def pick_releases_to_test( ) -> list[Version]: """Pick a handful of releases to test from a sorted list of supported releases.""" # If the package has majors (or major-like releases, even if they don't do - # semver), we want to make sure we're testing them all (unless there's too - # many). If not, we just pick the oldest, the newest, and a couple - # in between. + # semver), we want to make sure we're testing them all. If it doesn't have + # multiple majors, we just pick the oldest, the newest, and a couple of + # releases in between. # # If there is a relevant prerelease, also test that in addition to the above. num_versions = TEST_SUITE_CONFIG[integration].get("num_versions") @@ -342,7 +347,7 @@ def supported_python_versions( custom_supported_versions: Optional[ Union[SpecifierSet, dict[SpecifierSet, SpecifierSet]] ] = None, - version: Optional[Version] = None, + release_version: Optional[Version] = None, ) -> list[Version]: """ Get the intersection of Python versions supported by the package and the SDK. @@ -362,6 +367,12 @@ def supported_python_versions( on Python 3.7, so we can provide this as `custom_supported_versions`. The result of this function will then by the intersection of all three, i.e., [3.7]. + - The Python SDK supports Python 3.6-3.13. The package supports 3.5-3.8. + Additionally, we have a limitation in place to only test this framework on + Python 3.5 if the framework version is <2.0. `custom_supported_versions` + will contain this restriction, and `release_version` will contain the + version of the package we're currently looking at, to determine whether the + <2.0 restriction applies in this case. """ supported = [] @@ -377,11 +388,11 @@ def supported_python_versions( if curr in custom_supported_versions: supported.append(curr) - elif version is not None and isinstance( + elif release_version is not None and isinstance( custom_supported_versions, dict ): for v, py in custom_supported_versions.items(): - if version in v: + if release_version in v: if curr in py: supported.append(curr) break @@ -435,8 +446,10 @@ def _parse_python_versions_from_classifiers(classifiers: list[str]) -> list[Vers def determine_python_versions(pypi_data: dict) -> Union[SpecifierSet, list[Version]]: """ - Given data from PyPI's release endpoint, determine the Python versions supported by the package - from the Python version classifiers, when present, or from `requires_python` if there are no classifiers. + Determine the Python versions supported by the package from PyPI data. + + We're looking at Python version classifiers, if present, and + `requires_python` if there are no classifiers. """ try: classifiers = pypi_data["info"]["classifiers"] @@ -453,7 +466,7 @@ def determine_python_versions(pypi_data: dict) -> Union[SpecifierSet, list[Versi # We only use `requires_python` if there are no classifiers. This is because # `requires_python` doesn't tell us anything about the upper bound, which - # depends on when the release first came out + # implicitly depends on when the release first came out. try: requires_python = pypi_data["info"]["requires_python"] except (AttributeError, KeyError): @@ -666,7 +679,8 @@ def main(fail_on_changes: bool = False) -> None: # timestamp so that we don't fail CI on a PR just because a new package # version was released, leading to unrelated changes in tox.ini. print( - f"Since we're in fail_on_changes mode, we're only considering releases before the last tox.ini update at {last_updated.isoformat()}." + f"Since we're in fail_on_changes mode, we're only considering " + f"releases before the last tox.ini update at {last_updated.isoformat()}." ) global MIN_PYTHON_VERSION, MAX_PYTHON_VERSION @@ -789,19 +803,16 @@ def main(fail_on_changes: bool = False) -> None: Please don't make manual changes to `tox.ini`. Instead, make the changes to the `tox.jinja` template and/or the `populate_tox.py` - script (as applicable) and regenerate the `tox.ini` file with: - - python -m venv toxgen.env - . toxgen.env/bin/activate - pip install -r scripts/populate_tox/requirements.txt - python scripts/populate_tox/populate_tox.py + script (as applicable) and regenerate the `tox.ini` file by + running scripts/generate-test-files.sh """ ) ) print("Done checking tox.ini. Looking good!") else: print( - "Done generating tox.ini. Make sure to also update the CI YAML files to reflect the new test targets." + "Done generating tox.ini. Make sure to also update the CI YAML " + "files to reflect the new test targets." ) diff --git a/scripts/populate_tox/releases.jsonl b/scripts/populate_tox/releases.jsonl index 814d0c15b9..5940eb28c1 100644 --- a/scripts/populate_tox/releases.jsonl +++ b/scripts/populate_tox/releases.jsonl @@ -56,7 +56,7 @@ {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7"], "name": "boto3", "requires_python": "", "version": "1.12.49", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9"], "name": "boto3", "requires_python": ">= 3.6", "version": "1.20.54", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9"], "name": "boto3", "requires_python": ">= 3.7", "version": "1.28.85", "yanked": false}} -{"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "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.9"], "name": "boto3", "requires_python": ">=3.9", "version": "1.40.36", "yanked": false}} +{"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "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.9"], "name": "boto3", "requires_python": ">=3.9", "version": "1.40.37", "yanked": false}} {"info": {"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", "Topic :: Software Development :: Libraries :: Application Frameworks"], "name": "bottle", "requires_python": "", "version": "0.12.25", "yanked": false}} {"info": {"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", "Topic :: Software Development :: Libraries :: Application Frameworks"], "name": "bottle", "requires_python": null, "version": "0.13.4", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Object Brokering", "Topic :: System :: Distributed Computing"], "name": "celery", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", "version": "4.4.7", "yanked": false}} @@ -110,7 +110,7 @@ {"info": {"classifiers": ["Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering :: Artificial Intelligence"], "name": "huggingface-hub", "requires_python": ">=3.8.0", "version": "0.24.7", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering :: Artificial Intelligence"], "name": "huggingface-hub", "requires_python": ">=3.8.0", "version": "0.28.1", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering :: Artificial Intelligence"], "name": "huggingface-hub", "requires_python": ">=3.8.0", "version": "0.32.6", "yanked": false}} -{"info": {"classifiers": ["Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering :: Artificial Intelligence"], "name": "huggingface-hub", "requires_python": ">=3.8.0", "version": "0.35.0", "yanked": false}} +{"info": {"classifiers": ["Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering :: Artificial Intelligence"], "name": "huggingface-hub", "requires_python": ">=3.8.0", "version": "0.35.1", "yanked": false}} {"info": {"classifiers": ["License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.9"], "name": "langchain", "requires_python": "<4.0,>=3.8.1", "version": "0.1.20", "yanked": false}} {"info": {"classifiers": ["License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.9"], "name": "langchain", "requires_python": "<4.0,>=3.8.1", "version": "0.2.17", "yanked": false}} {"info": {"classifiers": [], "name": "langchain", "requires_python": "<4.0,>=3.9", "version": "0.3.27", "yanked": false}} @@ -126,13 +126,13 @@ {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "litestar", "requires_python": "<4.0,>=3.8", "version": "2.6.4", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: System :: Logging"], "name": "loguru", "requires_python": "<4.0,>=3.5", "version": "0.7.3", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.7.1", "version": "1.0.1", "yanked": false}} -{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.108.2", "yanked": false}} +{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.109.0", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.7.1", "version": "1.37.2", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai", "requires_python": ">=3.8", "version": "1.73.0", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.0.19", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.1.0", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.2.11", "yanked": false}} -{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.3.1", "yanked": false}} +{"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed"], "name": "openai-agents", "requires_python": ">=3.9", "version": "0.3.2", "yanked": false}} {"info": {"classifiers": ["License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3"], "name": "openfeature-sdk", "requires_python": ">=3.8", "version": "0.7.5", "yanked": false}} {"info": {"classifiers": ["License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3"], "name": "openfeature-sdk", "requires_python": ">=3.9", "version": "0.8.3", "yanked": false}} {"info": {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8"], "name": "pure-eval", "requires_python": "", "version": "0.0.3", "yanked": false}} @@ -159,7 +159,7 @@ {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "name": "pyspark", "requires_python": "", "version": "2.4.8", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "name": "pyspark", "requires_python": "", "version": "3.0.3", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Typing :: Typed"], "name": "pyspark", "requires_python": ">=3.6", "version": "3.1.3", "yanked": false}} -{"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Typing :: Typed"], "name": "pyspark", "requires_python": ">=3.8", "version": "3.5.6", "yanked": false}} +{"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Typing :: Typed"], "name": "pyspark", "requires_python": ">=3.8", "version": "3.5.7", "yanked": false}} {"info": {"classifiers": ["Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Typing :: Typed"], "name": "pyspark", "requires_python": ">=3.9", "version": "4.0.1", "yanked": false}} {"info": {"classifiers": ["Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.9"], "name": "ray", "requires_python": ">=3.9", "version": "2.49.2", "yanked": false}} {"info": {"classifiers": ["Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9"], "name": "ray", "requires_python": "", "version": "2.7.2", "yanked": false}} diff --git a/scripts/populate_tox/tox.jinja b/scripts/populate_tox/tox.jinja index 98e14adb20..9aa942ebe4 100755 --- a/scripts/populate_tox/tox.jinja +++ b/scripts/populate_tox/tox.jinja @@ -24,17 +24,6 @@ envlist = {py3.6,py3.8,py3.10,py3.11,py3.12}-gevent # === Integrations === - # General format is {pythonversion}-{integrationname}-v{frameworkversion} - # 1 blank line between different integrations - # Each framework version should only be mentioned once. I.e: - # {py3.7,py3.10}-django-v{3.2} - # {py3.10}-django-v{4.0} - # instead of: - # {py3.7}-django-v{3.2} - # {py3.7,py3.10}-django-v{3.2,4.0} - # - # At a minimum, we should test against at least the lowest - # and the latest supported version of a framework. # Asgi {py3.7,py3.12,py3.13}-asgi @@ -55,8 +44,7 @@ envlist = {py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-potel # === Integrations - Auto-generated === - # These come from the populate_tox.py script. Eventually we should move all - # integration tests there. + # These come from the populate_tox.py script. {% for group, integrations in groups.items() %} # ~~~ {{ group }} ~~~ @@ -121,8 +109,7 @@ deps = potel: -e .[opentelemetry-experimental] # === Integrations - Auto-generated === - # These come from the populate_tox.py script. Eventually we should move all - # integration tests there. + # These come from the populate_tox.py script. {% for group, integrations in groups.items() %} # ~~~ {{ group }} ~~~ diff --git a/tox.ini b/tox.ini index f80c86b51e..7520a4cb1f 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ # The file (and all resulting CI YAMLs) then need to be regenerated via # "scripts/generate-test-files.sh". # -# Last generated: 2025-09-23T13:41:50.551689+00:00 +# Last generated: 2025-09-24T08:25:49.003370+00:00 [tox] requires = @@ -24,17 +24,6 @@ envlist = {py3.6,py3.8,py3.10,py3.11,py3.12}-gevent # === Integrations === - # General format is {pythonversion}-{integrationname}-v{frameworkversion} - # 1 blank line between different integrations - # Each framework version should only be mentioned once. I.e: - # {py3.7,py3.10}-django-v{3.2} - # {py3.10}-django-v{4.0} - # instead of: - # {py3.7}-django-v{3.2} - # {py3.7,py3.10}-django-v{3.2,4.0} - # - # At a minimum, we should test against at least the lowest - # and the latest supported version of a framework. # Asgi {py3.7,py3.12,py3.13}-asgi @@ -55,8 +44,7 @@ envlist = {py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-potel # === Integrations - Auto-generated === - # These come from the populate_tox.py script. Eventually we should move all - # integration tests there. + # These come from the populate_tox.py script. # ~~~ AI ~~~ {py3.8,py3.11,py3.12}-anthropic-v0.16.0 @@ -80,12 +68,12 @@ envlist = {py3.8,py3.11,py3.12}-openai-base-v1.0.1 {py3.8,py3.11,py3.12}-openai-base-v1.37.2 {py3.8,py3.11,py3.12}-openai-base-v1.73.0 - {py3.8,py3.12,py3.13}-openai-base-v1.108.2 + {py3.8,py3.12,py3.13}-openai-base-v1.109.0 {py3.8,py3.11,py3.12}-openai-notiktoken-v1.0.1 {py3.8,py3.11,py3.12}-openai-notiktoken-v1.37.2 {py3.8,py3.11,py3.12}-openai-notiktoken-v1.73.0 - {py3.8,py3.12,py3.13}-openai-notiktoken-v1.108.2 + {py3.8,py3.12,py3.13}-openai-notiktoken-v1.109.0 {py3.9,py3.12,py3.13}-langgraph-v0.6.7 {py3.10,py3.12,py3.13}-langgraph-v1.0.0a3 @@ -93,19 +81,19 @@ envlist = {py3.10,py3.11,py3.12}-openai_agents-v0.0.19 {py3.10,py3.12,py3.13}-openai_agents-v0.1.0 {py3.10,py3.12,py3.13}-openai_agents-v0.2.11 - {py3.10,py3.12,py3.13}-openai_agents-v0.3.1 + {py3.10,py3.12,py3.13}-openai_agents-v0.3.2 {py3.8,py3.10,py3.11}-huggingface_hub-v0.24.7 {py3.8,py3.12,py3.13}-huggingface_hub-v0.28.1 {py3.8,py3.12,py3.13}-huggingface_hub-v0.32.6 - {py3.8,py3.12,py3.13}-huggingface_hub-v0.35.0 + {py3.8,py3.12,py3.13}-huggingface_hub-v0.35.1 # ~~~ Cloud ~~~ {py3.6,py3.7}-boto3-v1.12.49 {py3.6,py3.9,py3.10}-boto3-v1.20.54 {py3.7,py3.11,py3.12}-boto3-v1.28.85 - {py3.9,py3.12,py3.13}-boto3-v1.40.36 + {py3.9,py3.12,py3.13}-boto3-v1.40.37 {py3.6,py3.7,py3.8}-chalice-v1.16.0 {py3.6,py3.7,py3.8}-chalice-v1.21.9 @@ -229,7 +217,7 @@ envlist = {py3.9,py3.12,py3.13}-rq-v2.6.0 {py3.8,py3.9}-spark-v3.0.3 - {py3.8,py3.10,py3.11}-spark-v3.5.6 + {py3.8,py3.10,py3.11}-spark-v3.5.7 {py3.9,py3.12,py3.13}-spark-v4.0.1 @@ -372,8 +360,7 @@ deps = potel: -e .[opentelemetry-experimental] # === Integrations - Auto-generated === - # These come from the populate_tox.py script. Eventually we should move all - # integration tests there. + # These come from the populate_tox.py script. # ~~~ AI ~~~ anthropic-v0.16.0: anthropic==0.16.0 @@ -407,7 +394,7 @@ deps = openai-base-v1.0.1: openai==1.0.1 openai-base-v1.37.2: openai==1.37.2 openai-base-v1.73.0: openai==1.73.0 - openai-base-v1.108.2: openai==1.108.2 + openai-base-v1.109.0: openai==1.109.0 openai-base: pytest-asyncio openai-base: tiktoken openai-base-v1.0.1: httpx<0.28 @@ -416,7 +403,7 @@ deps = openai-notiktoken-v1.0.1: openai==1.0.1 openai-notiktoken-v1.37.2: openai==1.37.2 openai-notiktoken-v1.73.0: openai==1.73.0 - openai-notiktoken-v1.108.2: openai==1.108.2 + openai-notiktoken-v1.109.0: openai==1.109.0 openai-notiktoken: pytest-asyncio openai-notiktoken-v1.0.1: httpx<0.28 openai-notiktoken-v1.37.2: httpx<0.28 @@ -427,13 +414,13 @@ deps = openai_agents-v0.0.19: openai-agents==0.0.19 openai_agents-v0.1.0: openai-agents==0.1.0 openai_agents-v0.2.11: openai-agents==0.2.11 - openai_agents-v0.3.1: openai-agents==0.3.1 + openai_agents-v0.3.2: openai-agents==0.3.2 openai_agents: pytest-asyncio huggingface_hub-v0.24.7: huggingface_hub==0.24.7 huggingface_hub-v0.28.1: huggingface_hub==0.28.1 huggingface_hub-v0.32.6: huggingface_hub==0.32.6 - huggingface_hub-v0.35.0: huggingface_hub==0.35.0 + huggingface_hub-v0.35.1: huggingface_hub==0.35.1 huggingface_hub: responses @@ -441,7 +428,7 @@ deps = boto3-v1.12.49: boto3==1.12.49 boto3-v1.20.54: boto3==1.20.54 boto3-v1.28.85: boto3==1.28.85 - boto3-v1.40.36: boto3==1.40.36 + boto3-v1.40.37: boto3==1.40.37 {py3.7,py3.8}-boto3: urllib3<2.0.0 chalice-v1.16.0: chalice==1.16.0 @@ -608,7 +595,7 @@ deps = {py3.6,py3.7}-rq: fakeredis!=2.26.0 spark-v3.0.3: pyspark==3.0.3 - spark-v3.5.6: pyspark==3.5.6 + spark-v3.5.7: pyspark==3.5.7 spark-v4.0.1: pyspark==4.0.1