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

Reply via email to