This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new fe13eeb25ac Keep Named*Logger.name working across structlog releases
(#66875)
fe13eeb25ac is described below
commit fe13eeb25ac14e2c97e4a22a84324a88a4c2289f
Author: Ash Berlin-Taylor <[email protected]>
AuthorDate: Mon May 18 05:52:43 2026 +0100
Keep Named*Logger.name working across structlog releases (#66875)
A pre-emptive change to support - structlog 26.1.0 (most likely version -
merged in hynek/structlog#786) adds a `name` slot and a kwarg-only `name`
argument to `BytesLogger`, and its `__init__` now assigns `self.name =
name`.
In NamedBytesLogger we were setting `self.name` *before* calling
`super().__init__`, so on the new release the parent would overwrite the
caller-supplied name with `None`, breaking the per-logger level lookup in
`make_filtering_logger` and any other consumer that reads `logger.name`.
Since this is not yet released, I can't be certain if it will be in 26.1.0
or
something else, but it's merged to structlog's main, so lets cope with it
when
ever it lands.
---
.../src/airflow_shared/logging/structlog.py | 26 +++++++++++++++++-----
shared/logging/tests/logging/test_structlog.py | 21 +++++++++++++++++
2 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/shared/logging/src/airflow_shared/logging/structlog.py
b/shared/logging/src/airflow_shared/logging/structlog.py
index 5441913ec19..74cb6dc1966 100644
--- a/shared/logging/src/airflow_shared/logging/structlog.py
+++ b/shared/logging/src/airflow_shared/logging/structlog.py
@@ -204,24 +204,38 @@ def make_filtering_logger() -> Callable[...,
BindableLogger]:
return maker
+# structlog >= 26.1.0 added a `name` slot + kwarg to BytesLogger
+# (hynek/structlog#786). Detect it once so we can avoid a redundant slot and
+# forward `name` through the parent init. The same detection is applied to
+# WriteLogger so the analogous upstream change lands without a regression.
+_BYTES_LOGGER_HAS_NAME = "name" in getattr(structlog.BytesLogger, "__slots__",
())
+_WRITE_LOGGER_HAS_NAME = "name" in getattr(structlog.WriteLogger, "__slots__",
())
+
+
class NamedBytesLogger(structlog.BytesLogger):
- __slots__ = ("name",)
+ __slots__ = () if _BYTES_LOGGER_HAS_NAME else ("name",)
def __init__(self, name: str | None = None, file: BinaryIO | None = None):
- self.name = name
if file is not None:
file = make_file_io_non_caching(file)
- super().__init__(file)
+ if _BYTES_LOGGER_HAS_NAME:
+ super().__init__(file, name=name) # type: ignore[call-arg]
+ else:
+ super().__init__(file)
+ self.name = name
class NamedWriteLogger(structlog.WriteLogger):
- __slots__ = ("name",)
+ __slots__ = () if _WRITE_LOGGER_HAS_NAME else ("name",)
def __init__(self, name: str | None = None, file: TextIO | None = None):
- self.name = name
if file is not None:
file = make_file_io_non_caching(file)
- super().__init__(file)
+ if _WRITE_LOGGER_HAS_NAME:
+ super().__init__(file, name=name) # type: ignore[call-arg]
+ else:
+ super().__init__(file)
+ self.name = name
LogOutputType = TypeVar("LogOutputType", bound=TextIO | BinaryIO)
diff --git a/shared/logging/tests/logging/test_structlog.py
b/shared/logging/tests/logging/test_structlog.py
index 5b5514b6864..a723467c3d4 100644
--- a/shared/logging/tests/logging/test_structlog.py
+++ b/shared/logging/tests/logging/test_structlog.py
@@ -707,3 +707,24 @@ def test_dict_positional_arg_formatting(structlog_config,
get_logger, message, a
written = json.load(bio)
assert written["event"] == expected_event
+
+
+def test_named_bytes_logger_preserves_name():
+ """
+ structlog 26.1.0 (hynek/structlog#786) gives ``BytesLogger`` its own
``name``
+ slot and sets ``self.name`` in ``__init__``; older releases do not. This
test
+ runs against whichever version is installed and pins the contract that the
+ supplied name survives construction on both.
+ """
+ from airflow_shared.logging.structlog import NamedBytesLogger
+
+ assert NamedBytesLogger("my.logger").name == "my.logger"
+ assert NamedBytesLogger().name is None
+
+
+def test_named_write_logger_preserves_name():
+ """Same contract for NamedWriteLogger in case structlog mirrors #786 for
WriteLogger."""
+ from airflow_shared.logging.structlog import NamedWriteLogger
+
+ assert NamedWriteLogger("my.logger").name == "my.logger"
+ assert NamedWriteLogger().name is None