diff --git a/.github/actions/setup-default-test-properties/test-properties.json b/.github/actions/setup-default-test-properties/test-properties.json index f2e1dce9922d..32b449ea1ed9 100644 --- a/.github/actions/setup-default-test-properties/test-properties.json +++ b/.github/actions/setup-default-test-properties/test-properties.json @@ -1,12 +1,12 @@ { "PythonTestProperties": { - "ALL_SUPPORTED_VERSIONS": ["3.7", "3.8", "3.9", "3.10"], + "ALL_SUPPORTED_VERSIONS": ["3.7", "3.8", "3.9", "3.10", "3.11"], "LOWEST_SUPPORTED": ["3.7"], - "HIGHEST_SUPPORTED": ["3.10"], - "ESSENTIAL_VERSIONS": ["3.7", "3.10"], - "CROSS_LANGUAGE_VALIDATES_RUNNER_PYTHON_VERSIONS": ["3.7", "3.10"], - "CROSS_LANGUAGE_VALIDATES_RUNNER_DATAFLOW_USING_SQL_PYTHON_VERSIONS": ["3.10"], - "VALIDATES_CONTAINER_DATAFLOW_PYTHON_VERSIONS": ["3.7", "3.8", "3.9", "3.10"], + "HIGHEST_SUPPORTED": ["3.11"], + "ESSENTIAL_VERSIONS": ["3.7", "3.11"], + "CROSS_LANGUAGE_VALIDATES_RUNNER_PYTHON_VERSIONS": ["3.7", "3.11"], + "CROSS_LANGUAGE_VALIDATES_RUNNER_DATAFLOW_USING_SQL_PYTHON_VERSIONS": ["3.11"], + "VALIDATES_CONTAINER_DATAFLOW_PYTHON_VERSIONS": ["3.7", "3.8", "3.9", "3.10", "3.11" ] "LOAD_TEST_PYTHON_VERSION": "3.7", "CHICAGO_TAXI_EXAMPLE_FLINK_PYTHON_VERSION": "3.7", "DEFAULT_INTERPRETER": "python3.8", diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 040146e12b11..24f464171ac2 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest env: EVENT_NAME: ${{ github.event_name }} - PY_VERSIONS_FULL: "cp37-* cp38-* cp39-* cp310-*" + PY_VERSIONS_FULL: "cp37-* cp38-* cp39-* cp310-* cp311-*" outputs: gcp-variables-set: ${{ steps.check_gcp_variables.outputs.gcp-variables-set }} py-versions-full: ${{ steps.set-py-versions.outputs.py-versions-full }} diff --git a/.github/workflows/python_tests.yml b/.github/workflows/python_tests.yml index 91f26bb3e925..819330d394ad 100644 --- a/.github/workflows/python_tests.yml +++ b/.github/workflows/python_tests.yml @@ -105,6 +105,7 @@ jobs: {"py_ver": "3.8", "tox_env": "py38"}, {"py_ver": "3.9", "tox_env": "py39"}, {"py_ver": "3.10", "tox_env": "py310" }, + { "py_ver": "3.11", "tox_env": "py311" }, ] steps: - name: Checkout code @@ -115,7 +116,7 @@ jobs: python-version: ${{ matrix.params.py_ver }} - name: Get build dependencies working-directory: ./sdks/python - run: pip install -r build-requirements.txt + run: pip install -r build-requirements.txt --use-pep517 - name: Install tox run: pip install tox - name: Run tests basic unix @@ -140,7 +141,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ["3.7", "3.8", "3.9", "3.10"] + python: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - name: Checkout code uses: actions/checkout@v3 @@ -168,7 +169,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ["3.7", "3.8", "3.9", "3.10"] + python: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - name: Checkout code uses: actions/checkout@v3 diff --git a/.test-infra/jenkins/PythonTestProperties.groovy b/.test-infra/jenkins/PythonTestProperties.groovy index f6ea06455608..1ebf7cc84a87 100644 --- a/.test-infra/jenkins/PythonTestProperties.groovy +++ b/.test-infra/jenkins/PythonTestProperties.groovy @@ -23,7 +23,8 @@ class PythonTestProperties { '3.7', '3.8', '3.9', - '3.10' + '3.10', + '3.11' ] final static List SUPPORTED_CONTAINER_TASKS = ALL_SUPPORTED_VERSIONS.collect { "py${it.replace('.', '')}" diff --git a/.test-infra/jenkins/job_PreCommit_Portable_Python.groovy b/.test-infra/jenkins/job_PreCommit_Portable_Python.groovy index b9f0224bf71a..1f502bef5bc1 100644 --- a/.test-infra/jenkins/job_PreCommit_Portable_Python.groovy +++ b/.test-infra/jenkins/job_PreCommit_Portable_Python.groovy @@ -18,6 +18,8 @@ import CommonJobProperties as commonJobProperties import PrecommitJobBuilder +import static PythonTestProperties.LOWEST_SUPPORTED +import static PythonTestProperties.HIGHEST_SUPPORTED PrecommitJobBuilder builder = new PrecommitJobBuilder( scope: this, @@ -40,15 +42,17 @@ builder.build { // Due to BEAM-7993, run multiple Python version of portable precommit // tests in parallel could lead python3 container crash. We manually // config gradle steps here to run tests in sequential. + def lowestSupported = LOWEST_SUPPORTED.replace('.', '') + def highestSupported = HIGHEST_SUPPORTED.replace('.', '') steps { gradle { rootBuildScriptDir(commonJobProperties.checkoutDir) - tasks(':sdks:python:test-suites:portable:py37:preCommitPy37') + tasks(':sdks:python:test-suites:portable:py${lowestSupported}:preCommitPy${lowestSupported}') commonJobProperties.setGradleSwitches(delegate) } gradle { rootBuildScriptDir(commonJobProperties.checkoutDir) - tasks(':sdks:python:test-suites:portable:py310:preCommitPy310') + tasks(':sdks:python:test-suites:portable:${highestSupported}:preCommitPy${highestSupported}') commonJobProperties.setGradleSwitches(delegate) } } diff --git a/CHANGES.md b/CHANGES.md index c5a592114d18..afd2caaf6d53 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -54,8 +54,7 @@ ## Highlights -* New highly anticipated feature X added to Python SDK ([#X](https://github.com/apache/beam/issues/X)). -* New highly anticipated feature Y added to Java SDK ([#Y](https://github.com/apache/beam/issues/Y)). +* Apache Beam adds Python 3.11 support ([#23848](https://github.com/apache/beam/issues/23848)). ## I/Os diff --git a/build.gradle.kts b/build.gradle.kts index 85088a262760..f94f16226320 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -456,6 +456,7 @@ tasks.register("pythonPreCommit") { dependsOn(":sdks:python:test-suites:tox:py38:preCommitPy38") dependsOn(":sdks:python:test-suites:tox:py39:preCommitPy39") dependsOn(":sdks:python:test-suites:tox:py310:preCommitPy310") + dependsOn(":sdks:python:test-suites:tox:py311:preCommitPy311") } tasks.register("pythonPreCommitIT") { @@ -473,6 +474,7 @@ tasks.register("pythonDockerBuildPreCommit") { dependsOn(":sdks:python:container:py38:docker") dependsOn(":sdks:python:container:py39:docker") dependsOn(":sdks:python:container:py310:docker") + dependsOn(":sdks:python:container:py311:docker") } tasks.register("pythonLintPreCommit") { @@ -502,6 +504,9 @@ tasks.register("python38PostCommit") { dependsOn(":sdks:python:test-suites:direct:py38:hdfsIntegrationTest") dependsOn(":sdks:python:test-suites:portable:py38:postCommitPy38") // TODO: https://github.com/apache/beam/issues/22651 + // The default container uses Python 3.8. The goal here is to + // duild Docker images for TensorRT tests during run time for python versions + // other than 3.8 and add these tests in other python postcommit suites. dependsOn(":sdks:python:test-suites:dataflow:py38:inferencePostCommitIT") dependsOn(":sdks:python:test-suites:direct:py38:inferencePostCommitIT") } @@ -523,6 +528,13 @@ tasks.register("python310PostCommit") { dependsOn(":sdks:python:test-suites:portable:py310:postCommitPy310") } +tasks.register("python311PostCommit") { + dependsOn(":sdks:python:test-suites:dataflow:py311:postCommitIT") + dependsOn(":sdks:python:test-suites:direct:py311:postCommitIT") + dependsOn(":sdks:python:test-suites:direct:py311:hdfsIntegrationTest") + dependsOn(":sdks:python:test-suites:portable:py311:postCommitPy311") +} + task("python37SickbayPostCommit") { dependsOn(":sdks:python:test-suites:dataflow:py37:postCommitSickbay") } @@ -537,14 +549,14 @@ task("python39SickbayPostCommit") { tasks.register("portablePythonPreCommit") { dependsOn(":sdks:python:test-suites:portable:py37:preCommitPy37") - dependsOn(":sdks:python:test-suites:portable:py310:preCommitPy310") + dependsOn(":sdks:python:test-suites:portable:py311:preCommitPy311") } tasks.register("pythonSparkPostCommit") { dependsOn(":sdks:python:test-suites:portable:py37:sparkValidatesRunner") dependsOn(":sdks:python:test-suites:portable:py38:sparkValidatesRunner") dependsOn(":sdks:python:test-suites:portable:py39:sparkValidatesRunner") - dependsOn(":sdks:python:test-suites:portable:py310:sparkValidatesRunner") + dependsOn(":sdks:python:test-suites:portable:py311:sparkValidatesRunner") } tasks.register("websitePreCommit") { diff --git a/sdks/python/apache_beam/__init__.py b/sdks/python/apache_beam/__init__.py index 6db495c2137f..a4a13eab9738 100644 --- a/sdks/python/apache_beam/__init__.py +++ b/sdks/python/apache_beam/__init__.py @@ -70,7 +70,7 @@ import warnings if sys.version_info.major == 3: - if sys.version_info.minor <= 6 or sys.version_info.minor >= 11: + if sys.version_info.minor <= 6 or sys.version_info.minor >= 12: warnings.warn( 'This version of Apache Beam has not been sufficiently tested on ' 'Python %s.%s. You may encounter bugs or missing features.' % diff --git a/sdks/python/apache_beam/internal/dill_pickler.py b/sdks/python/apache_beam/internal/dill_pickler.py index 379c10afe2b3..efa736c2a96f 100644 --- a/sdks/python/apache_beam/internal/dill_pickler.py +++ b/sdks/python/apache_beam/internal/dill_pickler.py @@ -46,6 +46,125 @@ settings = {'dill_byref': None} +if sys.version_info >= (3, 11) and dill.__version__ == "0.3.1.1": + # Let's make dill 0.3.1.1 support Python 3.11. + + # The following function is based on 'save_code' from 'dill' + # Author: Mike McKerns (mmckerns @caltech and @uqfoundation) + # Copyright (c) 2008-2015 California Institute of Technology. + # Copyright (c) 2016-2023 The Uncertainty Quantification Foundation. + # License: 3-clause BSD. The full license text is available at: + # - https://github.com/uqfoundation/dill/blob/master/LICENSE + + # The following function is also based on 'save_codeobject' from 'cloudpickle' + # Copyright (c) 2012, Regents of the University of California. + # Copyright (c) 2009 `PiCloud, Inc. `_. + # License: 3-clause BSD. The full license text is available at: + # - https://github.com/cloudpipe/cloudpickle/blob/master/LICENSE + + from types import CodeType + + @dill.register(CodeType) + def save_code(pickler, obj): + if hasattr(obj, "co_endlinetable"): # python 3.11a (20 args) + args = ( + obj.co_argcount, + obj.co_posonlyargcount, + obj.co_kwonlyargcount, + obj.co_nlocals, + obj.co_stacksize, + obj.co_flags, + obj.co_code, + obj.co_consts, + obj.co_names, + obj.co_varnames, + obj.co_filename, + obj.co_name, + obj.co_qualname, + obj.co_firstlineno, + obj.co_linetable, + obj.co_endlinetable, + obj.co_columntable, + obj.co_exceptiontable, + obj.co_freevars, + obj.co_cellvars) + elif hasattr(obj, "co_exceptiontable"): # python 3.11 (18 args) + args = ( + obj.co_argcount, + obj.co_posonlyargcount, + obj.co_kwonlyargcount, + obj.co_nlocals, + obj.co_stacksize, + obj.co_flags, + obj.co_code, + obj.co_consts, + obj.co_names, + obj.co_varnames, + obj.co_filename, + obj.co_name, + obj.co_qualname, + obj.co_firstlineno, + obj.co_linetable, + obj.co_exceptiontable, + obj.co_freevars, + obj.co_cellvars) + elif hasattr(obj, "co_linetable"): # python 3.10 (16 args) + args = ( + obj.co_argcount, + obj.co_posonlyargcount, + obj.co_kwonlyargcount, + obj.co_nlocals, + obj.co_stacksize, + obj.co_flags, + obj.co_code, + obj.co_consts, + obj.co_names, + obj.co_varnames, + obj.co_filename, + obj.co_name, + obj.co_firstlineno, + obj.co_linetable, + obj.co_freevars, + obj.co_cellvars) + elif hasattr(obj, "co_posonlyargcount"): # python 3.8 (16 args) + args = ( + obj.co_argcount, + obj.co_posonlyargcount, + obj.co_kwonlyargcount, + obj.co_nlocals, + obj.co_stacksize, + obj.co_flags, + obj.co_code, + obj.co_consts, + obj.co_names, + obj.co_varnames, + obj.co_filename, + obj.co_name, + obj.co_firstlineno, + obj.co_lnotab, + obj.co_freevars, + obj.co_cellvars) + else: # python 3.7 (15 args) + args = ( + obj.co_argcount, + obj.co_kwonlyargcount, + obj.co_nlocals, + obj.co_stacksize, + obj.co_flags, + obj.co_code, + obj.co_consts, + obj.co_names, + obj.co_varnames, + obj.co_filename, + obj.co_name, + obj.co_firstlineno, + obj.co_lnotab, + obj.co_freevars, + obj.co_cellvars) + pickler.save_reduce(CodeType, args, obj=obj) + + dill._dill.save_code = save_code + class _NoOpContextManager(object): def __enter__(self): diff --git a/sdks/python/apache_beam/runners/dataflow/internal/apiclient.py b/sdks/python/apache_beam/runners/dataflow/internal/apiclient.py index 882617674c83..47b39af8192f 100644 --- a/sdks/python/apache_beam/runners/dataflow/internal/apiclient.py +++ b/sdks/python/apache_beam/runners/dataflow/internal/apiclient.py @@ -83,7 +83,7 @@ _LOGGER = logging.getLogger(__name__) -_PYTHON_VERSIONS_SUPPORTED_BY_DATAFLOW = ['3.7', '3.8', '3.9', '3.10'] +_PYTHON_VERSIONS_SUPPORTED_BY_DATAFLOW = ['3.7', '3.8', '3.9', '3.10', '3.11'] class Step(object): diff --git a/sdks/python/apache_beam/runners/dataflow/internal/apiclient_test.py b/sdks/python/apache_beam/runners/dataflow/internal/apiclient_test.py index 2994b6c5138e..8dfe5555bd27 100644 --- a/sdks/python/apache_beam/runners/dataflow/internal/apiclient_test.py +++ b/sdks/python/apache_beam/runners/dataflow/internal/apiclient_test.py @@ -972,7 +972,7 @@ def test_interpreter_version_check_passes_py38(self): @mock.patch( 'apache_beam.runners.dataflow.internal.apiclient.sys.version_info', - (3, 11, 0)) + (3, 12, 0)) @mock.patch( 'apache_beam.runners.dataflow.internal.apiclient.' 'beam_version.__version__', diff --git a/sdks/python/container/base_image_requirements_manual.txt b/sdks/python/container/base_image_requirements_manual.txt index 17ebd3787ca8..a74878014b5e 100644 --- a/sdks/python/container/base_image_requirements_manual.txt +++ b/sdks/python/container/base_image_requirements_manual.txt @@ -32,11 +32,15 @@ cython<1 # some versions of libraries that launch Beam pipelines, like tensorflow-transform. # Leaving 'future' in our containers for now prevent breaking tft users. future -guppy3 # Memory profiler +# TODO: Uncomment python version once guppy supports it. +# https://github.com/apache/beam/issues/25984 +guppy3;python_version<"3.11" # Memory profiler mmh3 # Optimizes execution of some Beam codepaths. TODO: Make it Beam's dependency. nltk # Commonly used for natural language processing. nose==1.3.7 # For Dataflow internal testing. TODO: remove this. -python-snappy # Optimizes execution of some Beam codepaths. +# TODO: Uncomment python version once python-snappy supports it. +# https://github.com/apache/beam/issues/25985 +python-snappy;python_version<"3.11" # Optimizes execution of some Beam codepaths. scipy scikit-learn tensorflow>=2.12.0;python_version>="3.8" diff --git a/sdks/python/container/build.gradle b/sdks/python/container/build.gradle index e5e4da7fe33a..4a957e9214b6 100644 --- a/sdks/python/container/build.gradle +++ b/sdks/python/container/build.gradle @@ -40,13 +40,15 @@ tasks.register("buildAll") { dependsOn ':sdks:python:container:py38:docker' dependsOn ':sdks:python:container:py39:docker' dependsOn ':sdks:python:container:py310:docker' + dependsOn ':sdks:python:container:py311:docker' } tasks.register("pushAll") { dependsOn ':sdks:python:container:py37:dockerPush' dependsOn ':sdks:python:container:py38:dockerPush' dependsOn ':sdks:python:container:py39:dockerPush' - dependsOn ':sdks:python:container:py310:dockerPush' + dependsOn ':sdks:python:container:py310:docker' + dependsOn ':sdks:python:container:py311:docker' } tasks.register("generatePythonRequirementsAll") { @@ -54,6 +56,7 @@ tasks.register("generatePythonRequirementsAll") { dependsOn ':sdks:python:container:py38:generatePythonRequirements' dependsOn ':sdks:python:container:py39:generatePythonRequirements' dependsOn ':sdks:python:container:py310:generatePythonRequirements' + dependsOn ':sdks:python:container:py311:generatePythonRequirements' } artifacts { diff --git a/sdks/python/container/py310/base_image_requirements.txt b/sdks/python/container/py310/base_image_requirements.txt index 5404cd41e9fe..6ddb5cb8eca9 100644 --- a/sdks/python/container/py310/base_image_requirements.txt +++ b/sdks/python/container/py310/base_image_requirements.txt @@ -34,7 +34,7 @@ click==8.1.3 cloudpickle==2.2.1 crcmod==1.7 cryptography==40.0.1 -Cython==0.29.33 +Cython==0.29.34 deprecation==2.1.0 dill==0.3.1.1 dnspython==2.3.0 @@ -52,7 +52,7 @@ google-api-core==2.11.0 google-apitools==0.5.31 google-auth==2.17.1 google-auth-httplib2==0.1.0 -google-auth-oauthlib==0.4.6 +google-auth-oauthlib==1.0.0 google-cloud-bigquery==3.9.0 google-cloud-bigquery-storage==2.19.1 google-cloud-bigtable==2.17.0 @@ -63,7 +63,7 @@ google-cloud-language==2.9.1 google-cloud-pubsub==2.15.2 google-cloud-pubsublite==1.8.1 google-cloud-recommendations-ai==0.10.3 -google-cloud-spanner==3.29.0 +google-cloud-spanner==3.30.0 google-cloud-videointelligence==2.11.1 google-cloud-vision==3.4.1 google-crc32c==1.5.0 @@ -78,7 +78,7 @@ guppy3==3.1.2 h5py==3.8.0 hdfs==2.7.0 httplib2==0.21.0 -hypothesis==6.70.1 +hypothesis==6.70.2 idna==3.4 iniconfig==2.0.0 jax==0.4.8 @@ -105,8 +105,8 @@ parameterized==0.8.1 pluggy==1.0.0 proto-plus==1.22.2 protobuf==4.22.1 -psycopg2-binary==2.9.5 -pyarrow==9.0.0 +psycopg2-binary==2.9.6 +pyarrow==11.0.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycparser==2.21 @@ -134,8 +134,8 @@ sortedcontainers==2.4.0 soupsieve==2.4 SQLAlchemy==1.4.47 sqlparse==0.4.3 -tenacity==5.1.5 -tensorboard==2.12.0 +tenacity==8.2.2 +tensorboard==2.12.1 tensorboard-data-server==0.7.0 tensorboard-plugin-wit==1.8.1 tensorflow==2.12.0 diff --git a/sdks/python/container/py311/base_image_requirements.txt b/sdks/python/container/py311/base_image_requirements.txt new file mode 100644 index 000000000000..417eedc0d33e --- /dev/null +++ b/sdks/python/container/py311/base_image_requirements.txt @@ -0,0 +1,150 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Autogenerated requirements file for Apache Beam py311 container image. +# Run ./gradlew :sdks:python:container:generatePythonRequirementsAll to update. +# Do not edit manually, adjust ../base_image_requirements_manual.txt or +# Apache Beam's setup.py instead, and regenerate the list. +# You will need Python interpreters for all versions supported by Beam, see: +# https://s.apache.org/beam-python-dev-wiki +# Reach out to a committer if you need help. + +absl-py==1.4.0 +astunparse==1.6.3 +attrs==22.2.0 +beautifulsoup4==4.12.0 +bs4==0.0.1 +cachetools==4.2.4 +certifi==2022.12.7 +cffi==1.15.1 +charset-normalizer==3.1.0 +click==8.1.3 +cloudpickle==2.2.1 +crcmod==1.7 +cryptography==40.0.1 +Cython==0.29.34 +deprecation==2.1.0 +dill==0.3.1.1 +dnspython==2.3.0 +docker==6.0.1 +docopt==0.6.2 +execnet==1.9.0 +fastavro==1.7.3 +fasteners==0.18 +flatbuffers==23.3.3 +freezegun==1.2.2 +future==0.18.3 +gast==0.4.0 +google-api-core==2.11.0 +google-apitools==0.5.31 +google-auth==2.17.1 +google-auth-httplib2==0.1.0 +google-auth-oauthlib==1.0.0 +google-cloud-bigquery==3.9.0 +google-cloud-bigquery-storage==2.19.1 +google-cloud-bigtable==2.17.0 +google-cloud-core==2.3.2 +google-cloud-datastore==2.15.1 +google-cloud-dlp==3.12.1 +google-cloud-language==2.9.1 +google-cloud-pubsub==2.15.2 +google-cloud-pubsublite==1.8.1 +google-cloud-recommendations-ai==0.10.3 +google-cloud-spanner==3.30.0 +google-cloud-videointelligence==2.11.1 +google-cloud-vision==3.4.1 +google-crc32c==1.5.0 +google-pasta==0.2.0 +google-resumable-media==2.4.1 +googleapis-common-protos==1.59.0 +greenlet==2.0.2 +grpc-google-iam-v1==0.12.6 +grpcio==1.53.0 +grpcio-status==1.53.0 +h5py==3.8.0 +hdfs==2.7.0 +httplib2==0.21.0 +hypothesis==6.70.2 +idna==3.4 +iniconfig==2.0.0 +jax==0.4.8 +joblib==1.2.0 +keras==2.12.0 +libclang==16.0.0 +Markdown==3.4.3 +MarkupSafe==2.1.2 +ml-dtypes==0.0.4 +mmh3==3.1.0 +mock==5.0.1 +nltk==3.8.1 +nose==1.3.7 +numpy==1.23.5 +oauth2client==4.1.3 +oauthlib==3.2.2 +objsize==0.6.1 +opt-einsum==3.3.0 +orjson==3.8.9 +overrides==6.5.0 +packaging==23.0 +pandas==1.5.3 +parameterized==0.8.1 +pluggy==1.0.0 +proto-plus==1.22.2 +protobuf==4.22.1 +psycopg2-binary==2.9.6 +pyarrow==11.0.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycparser==2.21 +pydot==1.4.2 +PyHamcrest==1.10.1 +pymongo==4.3.3 +PyMySQL==1.0.3 +pyparsing==3.0.9 +pytest==7.2.2 +pytest-timeout==2.1.0 +pytest-xdist==3.2.1 +python-dateutil==2.8.2 +pytz==2023.3 +PyYAML==6.0 +regex==2023.3.23 +requests==2.28.2 +requests-mock==1.10.0 +requests-oauthlib==1.3.1 +rsa==4.9 +scikit-learn==1.2.2 +scipy==1.10.1 +six==1.16.0 +sortedcontainers==2.4.0 +soupsieve==2.4 +SQLAlchemy==1.4.47 +sqlparse==0.4.3 +tenacity==8.2.2 +tensorboard==2.12.1 +tensorboard-data-server==0.7.0 +tensorboard-plugin-wit==1.8.1 +tensorflow==2.12.0 +tensorflow-estimator==2.12.0 +tensorflow-io-gcs-filesystem==0.32.0 +termcolor==2.2.0 +testcontainers==3.7.1 +threadpoolctl==3.1.0 +tqdm==4.65.0 +typing_extensions==4.5.0 +urllib3==1.26.15 +websocket-client==1.5.1 +Werkzeug==2.2.3 +wrapt==1.14.1 +zstandard==0.20.0 diff --git a/sdks/python/container/py311/build.gradle b/sdks/python/container/py311/build.gradle new file mode 100644 index 000000000000..729686587c55 --- /dev/null +++ b/sdks/python/container/py311/build.gradle @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'base' + id 'org.apache.beam.module' +} +applyDockerNature() +applyPythonNature() + +pythonVersion = '3.11' + +apply from: "../common.gradle" diff --git a/sdks/python/container/py37/base_image_requirements.txt b/sdks/python/container/py37/base_image_requirements.txt index 2e2860a7a1ef..f4a39e957330 100644 --- a/sdks/python/container/py37/base_image_requirements.txt +++ b/sdks/python/container/py37/base_image_requirements.txt @@ -32,7 +32,7 @@ click==8.1.3 cloudpickle==2.2.1 crcmod==1.7 cryptography==40.0.1 -Cython==0.29.33 +Cython==0.29.34 deprecation==2.1.0 dill==0.3.1.1 dnspython==2.3.0 @@ -58,7 +58,7 @@ google-cloud-language==2.9.1 google-cloud-pubsub==2.15.2 google-cloud-pubsublite==1.7.0 google-cloud-recommendations-ai==0.10.3 -google-cloud-spanner==3.29.0 +google-cloud-spanner==3.30.0 google-cloud-videointelligence==2.11.1 google-cloud-vision==3.4.1 google-crc32c==1.5.0 @@ -71,7 +71,7 @@ grpcio-status==1.53.0 guppy3==3.1.2 hdfs==2.7.0 httplib2==0.21.0 -hypothesis==6.70.1 +hypothesis==6.70.2 idna==3.4 importlib-metadata==6.1.0 iniconfig==2.0.0 @@ -91,8 +91,8 @@ parameterized==0.8.1 pluggy==1.0.0 proto-plus==1.22.2 protobuf==4.22.1 -psycopg2-binary==2.9.5 -pyarrow==9.0.0 +psycopg2-binary==2.9.6 +pyarrow==11.0.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycparser==2.21 @@ -119,7 +119,7 @@ sortedcontainers==2.4.0 soupsieve==2.4 SQLAlchemy==1.4.47 sqlparse==0.4.3 -tenacity==5.1.5 +tenacity==8.2.2 testcontainers==3.7.1 threadpoolctl==3.1.0 tomli==2.0.1 diff --git a/sdks/python/container/py38/base_image_requirements.txt b/sdks/python/container/py38/base_image_requirements.txt index 928759556340..3b9559f11e77 100644 --- a/sdks/python/container/py38/base_image_requirements.txt +++ b/sdks/python/container/py38/base_image_requirements.txt @@ -34,7 +34,7 @@ click==8.1.3 cloudpickle==2.2.1 crcmod==1.7 cryptography==40.0.1 -Cython==0.29.33 +Cython==0.29.34 deprecation==2.1.0 dill==0.3.1.1 dnspython==2.3.0 @@ -52,7 +52,7 @@ google-api-core==2.11.0 google-apitools==0.5.31 google-auth==2.17.1 google-auth-httplib2==0.1.0 -google-auth-oauthlib==0.4.6 +google-auth-oauthlib==1.0.0 google-cloud-bigquery==3.9.0 google-cloud-bigquery-storage==2.19.1 google-cloud-bigtable==2.17.0 @@ -63,7 +63,7 @@ google-cloud-language==2.9.1 google-cloud-pubsub==2.15.2 google-cloud-pubsublite==1.8.1 google-cloud-recommendations-ai==0.10.3 -google-cloud-spanner==3.29.0 +google-cloud-spanner==3.30.0 google-cloud-videointelligence==2.11.1 google-cloud-vision==3.4.1 google-crc32c==1.5.0 @@ -78,7 +78,7 @@ guppy3==3.1.2 h5py==3.8.0 hdfs==2.7.0 httplib2==0.21.0 -hypothesis==6.70.1 +hypothesis==6.70.2 idna==3.4 importlib-metadata==6.1.0 iniconfig==2.0.0 @@ -106,8 +106,8 @@ parameterized==0.8.1 pluggy==1.0.0 proto-plus==1.22.2 protobuf==4.22.1 -psycopg2-binary==2.9.5 -pyarrow==9.0.0 +psycopg2-binary==2.9.6 +pyarrow==11.0.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycparser==2.21 @@ -135,8 +135,8 @@ sortedcontainers==2.4.0 soupsieve==2.4 SQLAlchemy==1.4.47 sqlparse==0.4.3 -tenacity==5.1.5 -tensorboard==2.12.0 +tenacity==8.2.2 +tensorboard==2.12.1 tensorboard-data-server==0.7.0 tensorboard-plugin-wit==1.8.1 tensorflow==2.12.0 diff --git a/sdks/python/container/py39/base_image_requirements.txt b/sdks/python/container/py39/base_image_requirements.txt index 272f5e8ad59b..2c725521bdb4 100644 --- a/sdks/python/container/py39/base_image_requirements.txt +++ b/sdks/python/container/py39/base_image_requirements.txt @@ -34,7 +34,7 @@ click==8.1.3 cloudpickle==2.2.1 crcmod==1.7 cryptography==40.0.1 -Cython==0.29.33 +Cython==0.29.34 deprecation==2.1.0 dill==0.3.1.1 dnspython==2.3.0 @@ -52,7 +52,7 @@ google-api-core==2.11.0 google-apitools==0.5.31 google-auth==2.17.1 google-auth-httplib2==0.1.0 -google-auth-oauthlib==0.4.6 +google-auth-oauthlib==1.0.0 google-cloud-bigquery==3.9.0 google-cloud-bigquery-storage==2.19.1 google-cloud-bigtable==2.17.0 @@ -63,7 +63,7 @@ google-cloud-language==2.9.1 google-cloud-pubsub==2.15.2 google-cloud-pubsublite==1.8.1 google-cloud-recommendations-ai==0.10.3 -google-cloud-spanner==3.29.0 +google-cloud-spanner==3.30.0 google-cloud-videointelligence==2.11.1 google-cloud-vision==3.4.1 google-crc32c==1.5.0 @@ -78,7 +78,7 @@ guppy3==3.1.2 h5py==3.8.0 hdfs==2.7.0 httplib2==0.21.0 -hypothesis==6.70.1 +hypothesis==6.70.2 idna==3.4 importlib-metadata==6.1.0 iniconfig==2.0.0 @@ -106,8 +106,8 @@ parameterized==0.8.1 pluggy==1.0.0 proto-plus==1.22.2 protobuf==4.22.1 -psycopg2-binary==2.9.5 -pyarrow==9.0.0 +psycopg2-binary==2.9.6 +pyarrow==11.0.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycparser==2.21 @@ -135,8 +135,8 @@ sortedcontainers==2.4.0 soupsieve==2.4 SQLAlchemy==1.4.47 sqlparse==0.4.3 -tenacity==5.1.5 -tensorboard==2.12.0 +tenacity==8.2.2 +tensorboard==2.12.1 tensorboard-data-server==0.7.0 tensorboard-plugin-wit==1.8.1 tensorflow==2.12.0 diff --git a/sdks/python/setup.py b/sdks/python/setup.py index ea824be7fd29..10795a493d36 100644 --- a/sdks/python/setup.py +++ b/sdks/python/setup.py @@ -141,7 +141,7 @@ def cythonize(*args, **kwargs): if sys.platform == 'win32' and sys.maxsize <= 2**32: pyarrow_dependency = '' else: - pyarrow_dependency = 'pyarrow>=3.0.0,<10.0.0' + pyarrow_dependency = 'pyarrow>=3.0.0,<12.0.0' # We must generate protos after setup_requires are installed. @@ -169,7 +169,7 @@ def get_portability_package_data(): python_requires = '>=3.7' -if sys.version_info.major == 3 and sys.version_info.minor >= 11: +if sys.version_info.major == 3 and sys.version_info.minor >= 12: warnings.warn( 'This version of Apache Beam has not been sufficiently tested on ' 'Python %s.%s. You may encounter bugs or missing features.' % @@ -279,7 +279,7 @@ def get_portability_package_data(): 'pyhamcrest>=1.9,!=1.10.0,<2.0.0', 'pyyaml>=3.12,<7.0.0', 'requests_mock>=1.7,<2.0', - 'tenacity>=5.0.2,<6.0', + 'tenacity>=8.0.0,<9', 'pytest>=7.1.2,<8.0', 'pytest-xdist>=2.5.0,<4', 'pytest-timeout>=2.1.0,<3', @@ -365,6 +365,7 @@ def get_portability_package_data(): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', # When updating version classifiers, also update version warnings # above and in apache_beam/__init__.py. 'Topic :: Software Development :: Libraries', diff --git a/sdks/python/test-suites/dataflow/py311/build.gradle b/sdks/python/test-suites/dataflow/py311/build.gradle new file mode 100644 index 000000000000..67b347516962 --- /dev/null +++ b/sdks/python/test-suites/dataflow/py311/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply plugin: org.apache.beam.gradle.BeamModulePlugin +applyPythonNature() + +// Required to setup a Python 3 virtualenv and task names. +pythonVersion = '3.11' +apply from: "../common.gradle" diff --git a/sdks/python/test-suites/direct/py311/build.gradle b/sdks/python/test-suites/direct/py311/build.gradle new file mode 100644 index 000000000000..234ae00b3e88 --- /dev/null +++ b/sdks/python/test-suites/direct/py311/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { id 'org.apache.beam.module' } +applyPythonNature() + +// Required to setup a Python 3 virtualenv and task names. +pythonVersion = '3.11' +apply from: '../common.gradle' diff --git a/sdks/python/test-suites/gradle.properties b/sdks/python/test-suites/gradle.properties index 055bb484bfa6..cce99ebec946 100644 --- a/sdks/python/test-suites/gradle.properties +++ b/sdks/python/test-suites/gradle.properties @@ -23,7 +23,7 @@ # dataflow test-suites # (TODO): https://github.com/apache/beam/issues/21971 # Add python 3.10 to dataflow test-suites -dataflow_precommit_it_task_py_versions=3.7,3.10 +dataflow_precommit_it_task_py_versions=3.7,3.11 dataflow_mongodbio_it_task_py_versions=3.7 dataflow_chicago_taxi_example_task_py_versions=3.7 @@ -32,24 +32,24 @@ dataflow_chicago_taxi_example_task_py_versions=3.7 dataflow_validates_runner_batch_tests=3.7,3.9 dataflow_validates_runner_streaming_tests=3.7,3.9 -dataflow_validates_container_tests=3.7,3.8,3.9,3.10 +dataflow_validates_container_tests=3.7,3.8,3.9,3.10,3.11 # TODO: Enable following tests after making sure we have enough capacity. -dataflow_validates_runner_batch_tests_V2=3.7,3.10 -dataflow_validates_runner_streaming_tests_V2=3.7,3.10 -dataflow_examples_postcommit_py_versions=3.10 +dataflow_validates_runner_batch_tests_V2=3.7,3.11 +dataflow_validates_runner_streaming_tests_V2=3.7,3.11 +dataflow_examples_postcommit_py_versions=3.11 # TFX_BSL is not yet supported on Python 3.10. dataflow_cloudml_benchmark_tests_py_versions=3.9 # direct runner test-suites -direct_mongodbio_it_task_py_versions=3.10 -direct_examples_postcommit_py_versions=3.7,3.8,3.9,3.10 +direct_mongodbio_it_task_py_versions=3.11 +direct_examples_postcommit_py_versions=3.7,3.8,3.9,3.10,3.11 # flink runner test-suites -flink_validates_runner_precommit_py_versions=3.10 -flink_validates_runner_postcommit_py_versions=3.7,3.10 -flink_examples_postcommit_py_versions=3.7,3.10 +flink_validates_runner_precommit_py_versions=3.11 +flink_validates_runner_postcommit_py_versions=3.7,3.11 +flink_examples_postcommit_py_versions=3.7,3.11 # samza runner test-suites -samza_validates_runner_postcommit_py_versions=3.7,3.10 +samza_validates_runner_postcommit_py_versions=3.7,3.11 # spark runner test-suites -spark_examples_postcommit_py_versions=3.7,3.10 +spark_examples_postcommit_py_versions=3.7,3.11 diff --git a/sdks/python/test-suites/portable/py311/build.gradle b/sdks/python/test-suites/portable/py311/build.gradle new file mode 100644 index 000000000000..9913f7d0bd71 --- /dev/null +++ b/sdks/python/test-suites/portable/py311/build.gradle @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply plugin: org.apache.beam.gradle.BeamModulePlugin +applyPythonNature() + +addPortableWordCountTasks() + +// Required to setup a Python 3 virtualenv and task names. +pythonVersion = '3.11' +apply from: "../common.gradle" diff --git a/sdks/python/test-suites/tox/py311/build.gradle b/sdks/python/test-suites/tox/py311/build.gradle new file mode 100644 index 000000000000..1bb3766500bb --- /dev/null +++ b/sdks/python/test-suites/tox/py311/build.gradle @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Unit tests for Python 3.11 + */ + +plugins { id 'org.apache.beam.module' } +applyPythonNature() + +// Required to setup a Python 3 virtualenv and task names. +pythonVersion = '3.11' + +apply from: "../common.gradle" + +// TODO(https://github.com/apache/beam/issues/20051): Remove this once tox uses isolated builds. +testPy311Cython.mustRunAfter testPython311, testPy311Cloud diff --git a/sdks/python/tox.ini b/sdks/python/tox.ini index 7b6883e4b002..b45ac9e3c1ef 100644 --- a/sdks/python/tox.ini +++ b/sdks/python/tox.ini @@ -17,7 +17,7 @@ [tox] # new environments will be excluded by default unless explicitly added to envlist. -envlist = py37,py38,py39,py310,py37-{cloud,cython,lint,mypy,dask},py38-{cloud,cython,docs,cloudcoverage,dask},py39-{cloud,cython},py310-{cloud,cython,dask},whitespacelint +envlist = py37,py38,py39,py310,py311,py37-{cloud,cython,lint,mypy,dask},py38-{cloud,cython,docs,cloudcoverage,dask},py39-{cloud,cython},py310-{cloud,cython,dask},py311-{cloud,cython,dask},whitespacelint toxworkdir = {toxinidir}/target/{env:ENV_NAME:.tox} [pycodestyle] @@ -38,7 +38,7 @@ allowlist_externals = bash rm deps = - cython: cython==0.29.27 + cython: cython==0.29.33 -r build-requirements.txt setenv = RUN_SKIPPED_PY3_TESTS=0 @@ -62,19 +62,19 @@ commands_post = bash {toxinidir}/scripts/run_tox_cleanup.sh commands = false {envname} is misconfigured -[testenv:py{37,38,39,310}] +[testenv:py{37,38,39,310,311}] commands = python apache_beam/examples/complete/autocomplete_test.py bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}" -[testenv:py{37,38,39,310}-win] +[testenv:py{37,38,39,310,311}-win] commands = python apache_beam/examples/complete/autocomplete_test.py bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}" install_command = {envbindir}/python.exe {envbindir}/pip.exe install --retries 10 {opts} {packages} list_dependencies_command = {envbindir}/python.exe {envbindir}/pip.exe freeze -[testenv:py{37,38,39,310}-cython] +[testenv:py{37,38,39,310,311}-cython] # cython tests are only expected to work in linux (2.x and 3.x) # If we want to add other platforms in the future, it should be: # `platform = linux2|darwin|...` @@ -87,12 +87,12 @@ commands = python apache_beam/examples/complete/autocomplete_test.py bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}" -[testenv:py{37,38,39,310}-cloud] +[testenv:py{37,38,39,310,311}-cloud] extras = test,gcp,interactive,dataframe,aws,azure commands = bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}" -[testenv:py{37,38,39}-dask] +[testenv:py{37,38,39,310,311}-dask] extras = test,dask commands = bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}" @@ -296,7 +296,20 @@ commands = # Allow exit code 5 (no tests run) so that we can run this command safely on arbitrary subdirectories. /bin/sh -c 'pytest -o junit_suite_name={envname} --junitxml=pytest_{envname}.xml -n 6 -m uses_pyarrow {posargs}; ret=$?; [ $ret = 5 ] && exit 0 || exit $ret' -[testenv:py{37,38,39,310}-pandas-{14,15}] +[testenv:py{37,38,39,310,311}-pyarrow-{10,11}] +deps = + 10: pyarrow>=10,<11 + 11: pyarrow>=11,<12 +commands = + # Log pyarrow and numpy version for debugging + /bin/sh -c "pip freeze | grep -E '(pyarrow|numpy)'" + # Run pytest directly rather using run_pytest.sh. It doesn't handle + # selecting tests with -m (BEAM-12985). + # Allow exit code 5 (no tests run) so that we can run this command safely on arbitrary subdirectories. + /bin/sh -c 'pytest -o junit_suite_name={envname} --junitxml=pytest_{envname}.xml -n 6 -m uses_pyarrow {posargs}; ret=$?; [ $ret = 5 ] && exit 0 || exit $ret' + + +[testenv:py{37,38,39,310,311}-pandas-{14,15}] deps = 14: pandas>=1.4.3,<1.5.0 # Exclude 1.5.0 and 1.5.1 because of https://github.com/pandas-dev/pandas/issues/45725 @@ -307,7 +320,7 @@ commands = # Run all DataFrame API unit tests bash {toxinidir}/scripts/run_pytest.sh {envname} 'apache_beam/dataframe' -[testenv:py{37,38,39,310}-pytorch-{19,110,111,112,113}] +[testenv:py{37,38,39,310,311}-pytorch-{19,110,111,112,113}] deps = -r build-requirements.txt 19: torch>=1.9.0,<1.10.0 diff --git a/settings.gradle.kts b/settings.gradle.kts index 4800313f26a5..1781223c7952 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -239,26 +239,31 @@ include(":sdks:python:container:py37") include(":sdks:python:container:py38") include(":sdks:python:container:py39") include(":sdks:python:container:py310") +include(":sdks:python:container:py311") include(":sdks:python:test-suites:dataflow") include(":sdks:python:test-suites:dataflow:py37") include(":sdks:python:test-suites:dataflow:py38") include(":sdks:python:test-suites:dataflow:py39") include(":sdks:python:test-suites:dataflow:py310") +include(":sdks:python:test-suites:dataflow:py311") include(":sdks:python:test-suites:direct") include(":sdks:python:test-suites:direct:py37") include(":sdks:python:test-suites:direct:py38") include(":sdks:python:test-suites:direct:py39") include(":sdks:python:test-suites:direct:py310") +include(":sdks:python:test-suites:direct:py311") include(":sdks:python:test-suites:direct:xlang") include(":sdks:python:test-suites:portable:py37") include(":sdks:python:test-suites:portable:py38") include(":sdks:python:test-suites:portable:py39") include(":sdks:python:test-suites:portable:py310") +include(":sdks:python:test-suites:portable:py311") include(":sdks:python:test-suites:tox:pycommon") include(":sdks:python:test-suites:tox:py37") include(":sdks:python:test-suites:tox:py38") include(":sdks:python:test-suites:tox:py39") include(":sdks:python:test-suites:tox:py310") +include(":sdks:python:test-suites:tox:py311") include(":sdks:python:test-suites:xlang") include(":sdks:typescript") include(":sdks:typescript:container") diff --git a/website/www/site/content/en/documentation/programming-guide.md b/website/www/site/content/en/documentation/programming-guide.md index fc259f9cb81c..16e6ef1a3798 100644 --- a/website/www/site/content/en/documentation/programming-guide.md +++ b/website/www/site/content/en/documentation/programming-guide.md @@ -35,7 +35,7 @@ programming guide, take a look at the {{< language-switcher java py go typescript >}} {{< paragraph class="language-py" >}} -The Python SDK supports Python 3.7, 3.8, 3.9, and 3.10. +The Python SDK supports Python 3.7, 3.8, 3.9, 3.10, and 3.11. {{< /paragraph >}} {{< paragraph class="language-go">}}