Skip to content

Commit

Permalink
Add Python 3.9 support (#15515) (#16883)
Browse files Browse the repository at this point in the history
This includes several things:

* added per-provider support for python version. Each provider
  can now declare python versions it does not support
* excluded ldap core extra from Python 3.9.
* skip relevant tests in Python 3.9

(cherry picked from commit ce44b62)
  • Loading branch information
potiuk authored and jhtimmins committed Jul 8, 2021
1 parent 83863ba commit 826b5c5
Show file tree
Hide file tree
Showing 36 changed files with 166 additions and 61 deletions.
14 changes: 7 additions & 7 deletions BREEZE.rst
Expand Up @@ -1263,7 +1263,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
-a, --install-airflow-version INSTALL_AIRFLOW_VERSION
Uses different version of Airflow when building PROD image.
Expand Down Expand Up @@ -1493,7 +1493,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
-I, --production-image
Use production image for entering the environment and builds (not for tests).
Expand Down Expand Up @@ -1560,7 +1560,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
-v, --verbose
Show verbose information about executed docker, kind, kubectl, helm commands. Useful for
Expand Down Expand Up @@ -1683,7 +1683,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
####################################################################################################
Expand Down Expand Up @@ -1878,7 +1878,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
-b, --backend BACKEND
Backend to use for tests - it determines which database is used.
Expand Down Expand Up @@ -1942,7 +1942,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
-F, --force-build-images
Forces building of the local docker images. The images are rebuilt
Expand Down Expand Up @@ -2349,7 +2349,7 @@ This is the current syntax for `./breeze <./breeze>`_:
One of:
3.6 3.7 3.8
3.6 3.7 3.8 3.9
****************************************************************************************************
Choose backend to run for Airflow
Expand Down
4 changes: 2 additions & 2 deletions CI.rst
Expand Up @@ -57,7 +57,7 @@ Container Registry used as cache
For the CI builds of our we are using Container Registry to store results of the "Build Image" workflow
and pass it to the "CI Build" workflow.

Currently in main version of Airflow we run tests in 3 different versions of Python (3.6, 3.7, 3.8)
Currently in main version of Airflow we run tests in 4 different versions of Python (3.6, 3.7, 3.8, 3.9)
which means that we have to build 6 images (3 CI ones and 3 PROD ones). Yet we run around 12 jobs
with each of the CI images. That is a lot of time to just build the environment to run. Therefore
we are utilising ``pull_request_target`` feature of GitHub Actions.
Expand Down Expand Up @@ -779,7 +779,7 @@ The image names follow the patterns:
+--------------+----------------------------+--------------------------------+--------------------------------------------------------------------------------------------+
* <BRANCH> might be either "main" or "v1-10-test" or "v2-*-test"
* <X.Y> - Python version (Major + Minor). For "main" and "v2-*-test" should be in ["3.6", "3.7", "3.8"].
* <X.Y> - Python version (Major + Minor). For "main" and "v2-*-test" should be in ["3.6", "3.7", "3.8", "3.9"].
* <COMMIT_SHA> - for images that get merged to "main", "v2-*-test" of "v1-10-test", or built as part of a
pull request the images are tagged with the (full lenght) commit SHA of that particular branch. For pull
requests the SHA used is the tip of the pull request branch.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Expand Up @@ -873,7 +873,7 @@ This can be done by running this (it utilizes parallel preparation of the constr

.. code-block:: bash
export CURRENT_PYTHON_MAJOR_MINOR_VERSIONS_AS_STRING="3.6 3.7 3.8"
export CURRENT_PYTHON_MAJOR_MINOR_VERSIONS_AS_STRING="3.6 3.7 3.8 3.9"
for python_version in $(echo "${CURRENT_PYTHON_MAJOR_MINOR_VERSIONS_AS_STRING}")
do
./breeze build-image --upgrade-to-newer-dependencies --python ${python_version} --build-cache-local
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTORS_QUICK_START.rst
Expand Up @@ -119,7 +119,7 @@ Pyenv and setting up virtual-env
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
$ sudo apt install build-essentials python3.6-dev python3.7-dev python3.8-dev python-dev openssl \
$ sudo apt install build-essentials python3.6-dev python3.7-dev python3.8-dev python3.9-dev python-dev openssl \
sqlite sqlite-dev default-libmysqlclient-dev libmysqld-dev postgresql
2. Install pyenv
Expand Down
7 changes: 3 additions & 4 deletions Dockerfile
Expand Up @@ -44,7 +44,7 @@ ARG AIRFLOW_GID="50000"

ARG PYTHON_BASE_IMAGE="python:3.6-slim-buster"

ARG AIRFLOW_PIP_VERSION=21.1.1
ARG AIRFLOW_PIP_VERSION=21.1.2

# By default PIP has progress bar but you can disable it.
ARG PIP_PROGRESS_BAR="on"
Expand Down Expand Up @@ -232,11 +232,10 @@ ARG INSTALL_FROM_DOCKER_CONTEXT_FILES=""
ARG INSTALL_FROM_PYPI="true"
# Those are additional constraints that are needed for some extras but we do not want to
# Force them on the main Airflow package.
# * chardet<4 and certifi<2021.0.0 required to keep snowflake happy
# * urllib3 - required to keep boto3 happy
# * certifi<2021.0.0 required to keep snowflake happy
# * pyjwt<2.0.0: flask-jwt-extended requires it
# * dill<0.3.3 required by apache-beam
ARG EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS="chardet<4 urllib3<1.26 pyjwt<2.0.0 dill<0.3.3 certifi<2021.0.0"
ARG EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS="pyjwt<2.0.0 dill<0.3.3 certifi<2021.0.0"
ARG CONTINUE_ON_PIP_CHECK_FAILURE="false"


Expand Down
8 changes: 3 additions & 5 deletions Dockerfile.ci
Expand Up @@ -207,7 +207,7 @@ ARG AIRFLOW_PRE_CACHED_PIP_PACKAGES="true"
# By default in the image, we are installing all providers when installing from sources
ARG INSTALL_PROVIDERS_FROM_SOURCES="true"
ARG INSTALL_FROM_PYPI="true"
ARG AIRFLOW_PIP_VERSION=21.1.1
ARG AIRFLOW_PIP_VERSION=21.1.2
# Setup PIP
# By default PIP install run without cache to make image smaller
ARG PIP_NO_CACHE_DIR="true"
Expand Down Expand Up @@ -251,13 +251,11 @@ ENV AIRFLOW_REPO=${AIRFLOW_REPO}\

# Those are additional constraints that are needed for some extras but we do not want to
# force them on the main Airflow package. Those limitations are:
# * chardet<4 and certifi<2021.0.0: required by snowflake provider
# * certifi<2021.0.0: required by snowflake provider
# * lazy-object-proxy<1.5.0: required by astroid
# * pyOpenSSL: required by snowflake provider https://github.com/snowflakedb/snowflake-connector-python/blob/v2.3.6/setup.py#L201
# * urllib3<1.26: Required to keep boto3 happy
# * pyjwt<2.0.0: flask-jwt-extended requires it
# * dill<0.3.3 required by apache-beam
ARG EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS="chardet<4 lazy-object-proxy<1.5.0 pyOpenSSL<20.0.0 urllib3<1.26 pyjwt<2.0.0 dill<0.3.3 certifi<2021.0.0"
ARG EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS="lazy-object-proxy<1.5.0 pyjwt<2.0.0 dill<0.3.3 certifi<2021.0.0"
ARG UPGRADE_TO_NEWER_DEPENDENCIES="false"
ENV EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS=${EAGER_UPGRADE_ADDITIONAL_REQUIREMENTS} \
UPGRADE_TO_NEWER_DEPENDENCIES=${UPGRADE_TO_NEWER_DEPENDENCIES}
Expand Down
2 changes: 1 addition & 1 deletion IMAGES.rst
Expand Up @@ -81,7 +81,7 @@ where:
built from branches so they change over time. The ``2.*.*`` labels are built from git tags
and they are "fixed" once built.
* ``PYTHON_MAJOR_MINOR_VERSION`` - version of Python used to build the image. Examples: ``3.6``, ``3.7``,
``3.8``
``3.8``, ``3.9``
* The ``-ci`` suffix is added for CI images
* The ``-manifest`` is added for manifest images (see below for explanation of manifest images)

Expand Down
6 changes: 3 additions & 3 deletions LOCAL_VIRTUALENV.rst
Expand Up @@ -51,8 +51,8 @@ Required Software Packages
Use system-level package managers like yum, apt-get for Linux, or
Homebrew for macOS to install required software packages:

* Python (One of: 3.6, 3.7, 3.8)
* MySQL
* Python (One of: 3.6, 3.7, 3.8, 3.9)
* MySQL 5.7+
* libxml

Refer to the `Dockerfile.ci <Dockerfile.ci>`__ for a comprehensive list
Expand Down Expand Up @@ -102,7 +102,7 @@ Creating a Local virtualenv

To use your IDE for Airflow development and testing, you need to configure a virtual
environment. Ideally you should set up virtualenv for all Python versions that Airflow
supports (3.6, 3.7, 3.8).
supports (3.6, 3.7, 3.8, 3.9).

To create and initialize the local virtualenv:

Expand Down
2 changes: 1 addition & 1 deletion PULL_REQUEST_WORKFLOW.rst
Expand Up @@ -58,7 +58,7 @@ We approached the problem by:
3) Even more optimisation came from limiting the scope of tests to only "default" matrix parameters. So far
in Airflow we always run all tests for all matrix combinations. The primary matrix components are:

* Python versions (currently 3.6, 3.7, 3.8)
* Python versions (currently 3.6, 3.7, 3.8, 3.9)
* Backend types (currently MySQL/Postgres)
* Backed version (currently MySQL 5.7, MySQL 8, Postgres 9.6, Postgres 13

Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -78,9 +78,9 @@ Airflow is not a streaming solution, but it is often used to process real-time d

Apache Airflow is tested with:

| | Main version (dev) | Stable version (2.0.2) |
| | Main version (dev) | Stable version (2.1.0) |
| -------------------- | ------------------------- | ------------------------ |
| Python | 3.6, 3.7, 3.8 | 3.6, 3.7, 3.8 |
| Python | 3.6, 3.7, 3.8, 3.9 | 3.6, 3.7, 3.8 |
| Kubernetes | 1.20, 1.19, 1.18 | 1.20, 1.19, 1.18 |
| PostgreSQL | 9.6, 10, 11, 12, 13 | 9.6, 10, 11, 12, 13 |
| MySQL | 5.7, 8 | 5.7, 8 |
Expand Down
3 changes: 2 additions & 1 deletion airflow/__init__.py
Expand Up @@ -36,7 +36,7 @@

__version__ = version.version

__all__ = ['__version__', 'login', 'DAG']
__all__ = ['__version__', 'login', 'DAG', 'PY36', 'PY37', 'PY38', 'PY39']

# Make `airflow` an namespace package, supporting installing
# airflow.providers.* in different locations (i.e. one in site, and one in user
Expand All @@ -50,6 +50,7 @@
PY36 = sys.version_info >= (3, 6)
PY37 = sys.version_info >= (3, 7)
PY38 = sys.version_info >= (3, 8)
PY39 = sys.version_info >= (3, 9)


def __getattr__(name):
Expand Down
7 changes: 7 additions & 0 deletions airflow/provider.yaml.schema.json
Expand Up @@ -28,6 +28,13 @@
"type": "string"
}
},
"excluded-python-versions": {
"description": "List of python versions excluded for that provider",
"type": "array",
"items": {
"type": "string"
}
},
"integrations": {
"description": "List of integrations supported by the provider.",
"type": "array",
Expand Down
3 changes: 3 additions & 0 deletions airflow/providers/apache/hive/provider.yaml
Expand Up @@ -31,6 +31,9 @@ versions:
additional-dependencies:
- apache-airflow>=2.1.0

excluded-python-versions:
- "3.9"

integrations:
- integration-name: Apache Hive
external-doc-url: https://hive.apache.org/
Expand Down
4 changes: 2 additions & 2 deletions breeze
Expand Up @@ -3507,7 +3507,7 @@ function breeze::run_breeze_command() {
docker_engine_resources::check_all_resources
if [[ ${PRODUCTION_IMAGE} == "true" ]]; then
${run_command} "${dc_run_file}" run --service-ports --rm airflow "${@}"
${run_command} "${SCRIPTS_CI_DIR}/tools/ci_fix_ownership.sh"
${run_command} "${SCRIPTS_CI_DIR}/tools/ci_fix_ownership.sh" || true
else
${run_command} "${dc_run_file}" run --service-ports --rm airflow "${@}"
fi
Expand Down Expand Up @@ -3621,7 +3621,7 @@ function breeze::run_breeze_command() {
# We have different versions of images depending on the python version used. We keep up with the
# Latest patch-level changes in Python (this is done automatically during CI builds) so we have
# To only take into account MAJOR and MINOR version of python. This variable keeps the major/minor
# version of python in X.Y format (3.6, 3.7, 3.8 etc).
# version of python in X.Y format (3.6, 3.7, 3.8, 3.9).
#
# In Breeze the precedence of setting the version is as follows:
# 1. --python flag (if set, it will explicitly override it in the next step)
Expand Down
2 changes: 1 addition & 1 deletion breeze-complete
Expand Up @@ -23,7 +23,7 @@
# by the BATS tests automatically during pre-commit and CI
# Those cannot be made read-only as the breeze-complete must be re-sourceable

_breeze_allowed_python_major_minor_versions="3.6 3.7 3.8"
_breeze_allowed_python_major_minor_versions="3.6 3.7 3.8 3.9"
_breeze_allowed_backends="sqlite mysql postgres"
_breeze_allowed_integrations="cassandra kerberos mongo openldap pinot rabbitmq redis statsd trino all"
_breeze_allowed_generate_constraints_modes="source-providers pypi-providers no-providers"
Expand Down
2 changes: 2 additions & 0 deletions dev/provider_packages/PROVIDER_README_TEMPLATE.rst.jinja2
Expand Up @@ -47,6 +47,8 @@ Installation
You can install this package on top of an existing airflow 2.1+ installation via
``pip install {{PACKAGE_PIP_NAME}}``

The package supports the following python versions: {{ ",".join(SUPPORTED_PYTHON_VERSIONS) }}

{%- if PIP_REQUIREMENTS %}

PIP requirements
Expand Down
8 changes: 4 additions & 4 deletions dev/provider_packages/SETUP_TEMPLATE.py.jinja2
Expand Up @@ -68,16 +68,16 @@ def do_setup():
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
{%- for python_version in SUPPORTED_PYTHON_VERSIONS %}
'Programming Language :: Python :: {{ python_version }}',
{%- endfor %}
'Topic :: System :: Monitoring',
],
author='Apache Software Foundation',
author_email='dev@airflow.apache.org',
url='https://airflow.apache.org/',
download_url='https://archive.apache.org/dist/airflow/{{ PROVIDERS_FOLDER }}',
python_requires='~=3.6',
python_requires='{{ PYTHON_REQUIRES }}',
project_urls={
'Documentation': 'https://airflow.apache.org/docs/{{ PACKAGE_PIP_NAME }}/{{RELEASE}}/',
'Bug Tracker': 'https://github.com/apache/airflow/issues',
Expand Down
12 changes: 12 additions & 0 deletions dev/provider_packages/prepare_provider_packages.py
Expand Up @@ -51,6 +51,8 @@
from rich.progress import Progress
from rich.syntax import Syntax

ALL_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]

try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
Expand Down Expand Up @@ -208,6 +210,7 @@ class ProviderPackageDetails(NamedTuple):
documentation_provider_package_path: str
provider_description: str
versions: List[str]
excluded_python_versions: List[str]


ENTITY_NAMES = {
Expand Down Expand Up @@ -1445,6 +1448,7 @@ def get_provider_details(provider_package_id: str) -> ProviderPackageDetails:
documentation_provider_package_path=get_documentation_package_path(provider_package_id),
provider_description=provider_info['description'],
versions=provider_info['versions'],
excluded_python_versions=provider_info.get("excluded-python-versions") or [],
)


Expand Down Expand Up @@ -1483,6 +1487,12 @@ def get_provider_jinja_context(
)
with open(changelog_path) as changelog_file:
changelog = changelog_file.read()
supported_python_versions = [
p for p in ALL_PYTHON_VERSIONS if p not in provider_details.excluded_python_versions
]
python_requires = "~=3.6"
for p in provider_details.excluded_python_versions:
python_requires += f", !={p}"
context: Dict[str, Any] = {
"ENTITY_TYPES": list(EntityType),
"README_FILE": "README.rst",
Expand Down Expand Up @@ -1517,6 +1527,8 @@ def get_provider_jinja_context(
provider_details.documentation_provider_package_path,
),
"CHANGELOG": changelog,
"SUPPORTED_PYTHON_VERSIONS": supported_python_versions,
"PYTHON_REQUIRES": python_requires,
}
return context

Expand Down
2 changes: 1 addition & 1 deletion dev/retag_docker_images.py
Expand Up @@ -47,7 +47,7 @@

import click

PYTHON_VERSIONS = ["3.6", "3.7", "3.8"]
PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]

DOCKERHUB_IMAGES = [
"{prefix}:python{python_version}-{branch}",
Expand Down
3 changes: 1 addition & 2 deletions scripts/ci/libraries/_build_images.sh
Expand Up @@ -495,7 +495,6 @@ function build_images::rebuild_ci_image_if_needed() {
push_pull_remove_images::pull_ci_images_if_needed
return
fi

local needs_docker_build="false"
md5sum::check_if_docker_build_is_needed
build_images::get_local_build_cache_hash
Expand Down Expand Up @@ -526,7 +525,7 @@ function build_images::rebuild_ci_image_if_needed() {
local root_files_count
root_files_count=$(find "airflow" "tests" -user root | wc -l | xargs)
if [[ ${root_files_count} != "0" ]]; then
./scripts/ci/tools/ci_fix_ownership.sh
./scripts/ci/tools/ci_fix_ownership.sh || true
fi
fi
verbosity::print_info
Expand Down
4 changes: 2 additions & 2 deletions scripts/ci/libraries/_initialization.sh
Expand Up @@ -87,11 +87,11 @@ function initialization::initialize_base_variables() {
export PRODUCTION_IMAGE="false"

# All supported major/minor versions of python in all versions of Airflow
ALL_PYTHON_MAJOR_MINOR_VERSIONS+=("3.6" "3.7" "3.8")
ALL_PYTHON_MAJOR_MINOR_VERSIONS+=("3.6" "3.7" "3.8" "3.9")
export ALL_PYTHON_MAJOR_MINOR_VERSIONS

# Currently supported major/minor versions of python
CURRENT_PYTHON_MAJOR_MINOR_VERSIONS+=("3.6" "3.7" "3.8")
CURRENT_PYTHON_MAJOR_MINOR_VERSIONS+=("3.6" "3.7" "3.8" "3.9")
export CURRENT_PYTHON_MAJOR_MINOR_VERSIONS

# Currently supported versions of Postgres
Expand Down
4 changes: 2 additions & 2 deletions scripts/ci/libraries/_push_pull_remove_images.sh
Expand Up @@ -144,7 +144,7 @@ function push_pull_remove_images::pull_base_python_image() {
push_pull_remove_images::pull_image_github_dockerhub "${AIRFLOW_PYTHON_BASE_IMAGE}" \
"${GITHUB_REGISTRY_PYTHON_BASE_IMAGE}${python_tag_suffix}"
else
docker_v pull "${AIRFLOW_PYTHON_BASE_IMAGE}"
docker_v pull "${AIRFLOW_PYTHON_BASE_IMAGE}" || true
fi
}

Expand All @@ -161,7 +161,7 @@ function push_pull_remove_images::pull_ci_images_if_needed() {
push_pull_remove_images::pull_image_github_dockerhub "${AIRFLOW_CI_IMAGE}" \
"${GITHUB_REGISTRY_AIRFLOW_CI_IMAGE}:${GITHUB_REGISTRY_PULL_IMAGE_TAG}"
else
push_pull_remove_images::pull_image_if_not_present_or_forced "${AIRFLOW_CI_IMAGE}"
push_pull_remove_images::pull_image_if_not_present_or_forced "${AIRFLOW_CI_IMAGE}" || true
fi
fi
}
Expand Down

0 comments on commit 826b5c5

Please sign in to comment.