Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion airflow/cli/commands/remote_commands/config_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,9 @@ def lint_config(args) -> None:
if configuration.config.section in ignore_sections or configuration.config.option in ignore_options:
continue

if conf.has_option(configuration.config.section, configuration.config.option):
if conf.has_option(
configuration.config.section, configuration.config.option, lookup_from_deprecated_options=False
):
lint_issues.append(configuration.message)

if lint_issues:
Expand Down
9 changes: 0 additions & 9 deletions airflow/config_templates/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1854,15 +1854,6 @@ webserver:
type: string
example: ~
default: "False"
cookie_samesite:
description: |
Set samesite policy on session cookies.
As `recommended <https://flask.palletsprojects.com/en/1.1.x/config/#SESSION_COOKIE_SAMESITE>`_
by Flask, the default is set to ``Lax`` and not a empty string.
version_added: 1.10.3
type: string
example: ~
default: "Lax"
default_wrap:
description: |
Default setting for wrap toggle on DAG code and TI log views.
Expand Down
95 changes: 52 additions & 43 deletions airflow/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,58 +891,60 @@ def get( # type: ignore[override,misc]
section: str,
key: str,
suppress_warnings: bool = False,
lookup_from_deprecated_options: bool = True,
_extra_stacklevel: int = 0,
**kwargs,
) -> str | None:
section = section.lower()
key = key.lower()
warning_emitted = False
deprecated_section: str | None
deprecated_key: str | None
deprecated_section: str | None = None
deprecated_key: str | None = None

option_description = self.configuration_description.get(section, {}).get(key, {})
if option_description.get("deprecated"):
deprecation_reason = option_description.get("deprecation_reason", "")
warnings.warn(
f"The '{key}' option in section {section} is deprecated. {deprecation_reason}",
DeprecationWarning,
stacklevel=2 + _extra_stacklevel,
)
# For when we rename whole sections
if section in self.inversed_deprecated_sections:
deprecated_section, deprecated_key = (section, key)
section = self.inversed_deprecated_sections[section]
if not self._suppress_future_warnings:
if lookup_from_deprecated_options:
option_description = self.configuration_description.get(section, {}).get(key, {})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Lee-W @jason810496 So it turns out this was inaddequately tested before, and was already not working.

This should be self.configuration_description.get(section, {}).get("options", {}).get(key, {})

@jason810496 Would you mind fixing this and adding tests for it?

Copy link
Member Author

@jason810496 jason810496 Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will create a PR to fix it I the weekend ( currently out of laptop. If this is very urgent then I might not be able to solve it immediately. )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, no rush! It's been broken for a some unknown time, you were just the unfortunate soul who touched it last 😁

if option_description.get("deprecated"):
deprecation_reason = option_description.get("deprecation_reason", "")
warnings.warn(
f"The config section [{deprecated_section}] has been renamed to "
f"[{section}]. Please update your `conf.get*` call to use the new name",
FutureWarning,
stacklevel=2 + _extra_stacklevel,
)
# Don't warn about individual rename if the whole section is renamed
warning_emitted = True
elif (section, key) in self.inversed_deprecated_options:
# Handle using deprecated section/key instead of the new section/key
new_section, new_key = self.inversed_deprecated_options[(section, key)]
if not self._suppress_future_warnings and not warning_emitted:
warnings.warn(
f"section/key [{section}/{key}] has been deprecated, you should use"
f"[{new_section}/{new_key}] instead. Please update your `conf.get*` call to use the "
"new name",
FutureWarning,
f"The '{key}' option in section {section} is deprecated. {deprecation_reason}",
DeprecationWarning,
stacklevel=2 + _extra_stacklevel,
)
# For the cases in which we rename whole sections
if section in self.inversed_deprecated_sections:
deprecated_section, deprecated_key = (section, key)
section = self.inversed_deprecated_sections[section]
if not self._suppress_future_warnings:
warnings.warn(
f"The config section [{deprecated_section}] has been renamed to "
f"[{section}]. Please update your `conf.get*` call to use the new name",
FutureWarning,
stacklevel=2 + _extra_stacklevel,
)
# Don't warn about individual rename if the whole section is renamed
warning_emitted = True
deprecated_section, deprecated_key = section, key
section, key = (new_section, new_key)
elif section in self.deprecated_sections:
# When accessing the new section name, make sure we check under the old config name
deprecated_key = key
deprecated_section = self.deprecated_sections[section][0]
else:
deprecated_section, deprecated_key, _ = self.deprecated_options.get(
(section, key), (None, None, None)
)
elif (section, key) in self.inversed_deprecated_options:
# Handle using deprecated section/key instead of the new section/key
new_section, new_key = self.inversed_deprecated_options[(section, key)]
if not self._suppress_future_warnings and not warning_emitted:
warnings.warn(
f"section/key [{section}/{key}] has been deprecated, you should use"
f"[{new_section}/{new_key}] instead. Please update your `conf.get*` call to use the "
"new name",
FutureWarning,
stacklevel=2 + _extra_stacklevel,
)
warning_emitted = True
deprecated_section, deprecated_key = section, key
section, key = (new_section, new_key)
elif section in self.deprecated_sections:
# When accessing the new section name, make sure we check under the old config name
deprecated_key = key
deprecated_section = self.deprecated_sections[section][0]
else:
deprecated_section, deprecated_key, _ = self.deprecated_options.get(
(section, key), (None, None, None)
)
# first check environment variables
option = self._get_environment_variables(
deprecated_key,
Expand Down Expand Up @@ -1247,7 +1249,7 @@ def read_dict( # type: ignore[override]
"""
super().read_dict(dictionary=dictionary, source=source)

def has_option(self, section: str, option: str) -> bool:
def has_option(self, section: str, option: str, lookup_from_deprecated_options: bool = True) -> bool:
"""
Check if option is defined.

Expand All @@ -1259,7 +1261,14 @@ def has_option(self, section: str, option: str) -> bool:
:return:
"""
try:
value = self.get(section, option, fallback=None, _extra_stacklevel=1, suppress_warnings=True)
value = self.get(
section,
option,
fallback=None,
_extra_stacklevel=1,
suppress_warnings=True,
lookup_from_deprecated_options=lookup_from_deprecated_options,
)
if value is None:
return False
return True
Expand Down
2 changes: 1 addition & 1 deletion airflow/models/serialized_dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SerializedDagModel(Base):
* ``[core] min_serialized_dag_update_interval = 30`` (s):
serialized DAGs are updated in DB when a file gets processed by scheduler,
to reduce DB write rate, there is a minimal interval of updating serialized DAGs.
* ``[scheduler] dag_dir_list_interval = 300`` (s):
* ``[dag_processor] refresh_interval = 300`` (s):
interval of deleting serialized DAGs in DB when the files are deleted, suggest
to use a smaller interval such as 60
* ``[core] compress_serialized_dags``:
Expand Down
4 changes: 3 additions & 1 deletion airflow/www/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ def create_app(config=None, testing=False):
flask_app.config["SESSION_COOKIE_SECURE"] = conf.getboolean("webserver", "COOKIE_SECURE")

# Note: Ensure "Lax" is the default if config not specified
flask_app.config["SESSION_COOKIE_SAMESITE"] = conf.get("webserver", "COOKIE_SAMESITE") or "Lax"
flask_app.config["SESSION_COOKIE_SAMESITE"] = (
conf.get("webserver", "COOKIE_SAMESITE", fallback=None) or "Lax"
)

# Above Flask 2.0.x, default value of SEND_FILE_MAX_AGE_DEFAULT changed 12 hours to None.
# for static file caching, it needs to set value explicitly.
Expand Down
3 changes: 2 additions & 1 deletion tests/cli/commands/remote_commands/test_config_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,8 @@ def test_lint_with_invalid_section_option(self):
def test_lint_detects_multiple_issues(self):
with mock.patch(
"airflow.configuration.conf.has_option",
side_effect=lambda s, o: o in ["check_slas", "strict_dataset_uri_validation"],
side_effect=lambda section, option, lookup_from_deprecated_options: option
in ["check_slas", "strict_dataset_uri_validation"],
):
with contextlib.redirect_stdout(StringIO()) as temp_stdout:
config_command.lint_config(cli_parser.get_parser().parse_args(["config", "lint"]))
Expand Down
Loading