diederikvdv opened a new pull request, #77013:
URL: https://github.com/apache/airflow/pull/77013
With Version 3.4.0 a breaking change got introduced for us, since by default
we use PYTHONOPTIMIZE=2.
Our optimization drops the docstrings which earlier worked fine, but now
causes our deploys to fail.
This oneliner PR handles the case where __doc__ is None resulting in an
attribute error.
I checked locally that the fix works with different PYTHONOPTIMIZE values. I
don't know how to add a test case for this to the repo.
```
python -OO -c 'from airflow.api_fastapi.execution_api.versions.v2026_10_30
import IdentifyArchivedTaskStateUpdates;
print(IdentifyArchivedTaskStateUpdates.description)'
>> None
```
```
python -O -c 'from airflow.api_fastapi.execution_api.versions.v2026_10_30
import IdentifyArchivedTaskStateUpdates;
print(IdentifyArchivedTaskStateUpdates.description)'
>> Reject mutations from an archived attempt with 410.
>> Variable writes and asset-watcher writes to asset state are exempt. Older
>> clients keep each endpoint's own response.
```
The error log in case it helps:
```
Traceback (most recent call last):
File "/opt/venv/bin/airflow", line 8, in <module>
sys.exit(main())
^^^^^^
File "/opt/venv/lib/python3.12/site-packages/airflow/__main__.py", line
61, in main
args.func(args)
File "/opt/venv/lib/python3.12/site-packages/airflow/cli/cli_config.py",
line 49, in command
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/airflow/utils/cli.py", line
119, in wrapper
return f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/utils/providers_configuration_loader.py",
line 54, in wrapped_function
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/api_server_command.py",
line 207, in wrapper
return func(args)
^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/api_server_command.py",
line 251, in api_server
run_command_with_daemon_option(
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/daemon_utils.py",
line 82, in run_command_with_daemon_option
callback()
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/api_server_command.py",
line 254, in <lambda>
callback=lambda: _run_api_server(
^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/utils/memray_utils.py", line
61, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/api_server_command.py",
line 188, in _run_api_server
run(
File
"/opt/venv/lib/python3.12/site-packages/airflow/cli/commands/api_server_command.py",
line 140, in _run_api_server_with_uvicorn
uvicorn.run(
File "/opt/venv/lib/python3.12/site-packages/uvicorn/main.py", line 620,
in run
config.load_app()
File "/opt/venv/lib/python3.12/site-packages/uvicorn/config.py", line 434,
in load_app
return import_from_string(self.app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/uvicorn/importer.py", line
19, in import_from_string
module = importlib.import_module(module_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in
import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 999, in exec_module
File "<frozen importlib._bootstrap>", line 488, in
_call_with_frames_removed
File "/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/main.py",
line 46, in <module>
app = cached_app(apps=os.environ.get("AIRFLOW_API_APPS", "all"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/app.py",
line 169, in cached_app
return create_app(apps=apps)
^^^^^^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/utils/providers_configuration_loader.py",
line 54, in wrapped_function
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/app.py",
line 147, in create_app
task_exec_api_app = create_task_execution_api_app(dag_bag=dag_bag)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/app.py",
line 303, in create_task_execution_api_app
from airflow.api_fastapi.execution_api.routes import execution_api_router
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/routes/__init__.py",
line 22, in <module>
from airflow.api_fastapi.execution_api.routes import (
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/routes/task_instances.py",
line 93, in <module>
from airflow.api_fastapi.execution_api.versions.v2026_10_30 import
IdentifyArchivedTaskStateUpdates
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/versions/__init__.py",
line 24, in <module>
from airflow.api_fastapi.execution_api.versions.v2025_08_10 import (
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/versions/v2025_08_10.py",
line 23, in <module>
from airflow.api_fastapi.execution_api.routes.xcoms import
GetXcomFilterParams, GetXComSliceFilterParams
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/routes/xcoms.py",
line 45, in <module>
from airflow.api_fastapi.execution_api.versions.v2026_10_30 import
IdentifyArchivedTaskStateUpdates
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/versions/v2026_10_30.py",
line 76, in <module>
class IdentifyArchivedTaskStateUpdates(VersionChangeWithSideEffects):
File
"/opt/venv/lib/python3.12/site-packages/airflow/api_fastapi/execution_api/versions/v2026_10_30.py",
line 84, in IdentifyArchivedTaskStateUpdates
description = inspect.cleandoc(__doc__)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/inspect.py", line 888, in cleandoc
lines = doc.expandtabs().split('\n')
^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'expandtabs'
```
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Thank you for contributing!
Please provide above a brief description of the changes made in this pull
request.
Write a good git commit message following this guide:
https://chris.beams.io/posts/git-commit/
Please make sure that your code changes are covered with tests.
And in case of new features or big changes remember to adjust the
documentation.
For user-facing UI changes, please attach before/after screenshots (or a
short
screen recording) so reviewers can assess the visual impact.
Feel free to ping (in general) for the review if you do not see reaction for
a few days
(72 Hours is the minimum reaction time you can expect from volunteers) - we
sometimes miss notifications.
In case of an existing issue, reference it using one of the following:
* closes: #ISSUE
* related: #ISSUE
-->
---
##### Was generative AI tooling used to co-author this PR?
<!--
If generative AI tooling has been used in the process of authoring this PR,
please
change below checkbox to `[X]` followed by the name of the tool, uncomment
the "Generated-by".
-->
- [x] Yes (please specify the tool below)
Generated-by: copilot following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]