This is an automated email from the ASF dual-hosted git repository.
potiuk 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 06c75db1ec7 fix(connection-model): RFC3896 `conn_type` warning (#63167)
06c75db1ec7 is described below
commit 06c75db1ec759abb6c3417eb05f84bcc323d0695
Author: Michael Trossbach <[email protected]>
AuthorDate: Sun Mar 29 11:24:26 2026 -0700
fix(connection-model): RFC3896 `conn_type` warning (#63167)
* fix(connection): check pre-normalized conn_type when warning about
presence of underscores in conn_type
* feat(connection): added test_get_uri_conn_type_warning method to
TestConnection
* fix(connection): use conn_type attr as default value when checking
conn_type for presence of underscores in get_uri
* fix(connection): generalized test cases used by
test_get_uri_conn_type_warning test to include connections instantiated using a
URI and connections instantiated not using a URI
* fix(connection): coalesce conn_type value to an empty string before
checking for presence of underscores in conn_type in get_uri
* refactor(connection): updated assertion messages in
test_get_uri_conn_type_warning method
* style(connection): formatting changes according to prek static checks
---
airflow-core/src/airflow/models/connection.py | 13 +++---
airflow-core/tests/unit/models/test_connection.py | 50 +++++++++++++++++++++++
2 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/airflow-core/src/airflow/models/connection.py
b/airflow-core/src/airflow/models/connection.py
index d58f2b3202d..3032636f1b1 100644
--- a/airflow-core/src/airflow/models/connection.py
+++ b/airflow-core/src/airflow/models/connection.py
@@ -228,9 +228,11 @@ class Connection(Base, LoggingMixin):
raise AirflowException("Invalid connection string.")
host_with_protocol = schemes_count_in_uri == 2
uri_parts = urlsplit(uri)
- conn_type = uri_parts.scheme
- self.conn_type = self._normalize_conn_type(conn_type)
- rest_of_the_url = uri.replace(f"{conn_type}://", ("" if
host_with_protocol else "//"))
+ self._prenormalized_conn_type = uri_parts.scheme
+ self.conn_type =
self._normalize_conn_type(self._prenormalized_conn_type)
+ rest_of_the_url = uri.replace(
+ f"{self._prenormalized_conn_type}://", ("" if host_with_protocol
else "//")
+ )
if host_with_protocol:
uri_splits = rest_of_the_url.split("://", 1)
if "@" in uri_splits[0] or ":" in uri_splits[0]:
@@ -273,10 +275,11 @@ class Connection(Base, LoggingMixin):
Note that the URI returned by this method is **not**
SQLAlchemy-compatible, if you need a SQLAlchemy-compatible URI, use the
:attr:`~airflow.providers.common.sql.hooks.sql.DbApiHook.sqlalchemy_url`
"""
- if self.conn_type and "_" in self.conn_type:
+ conn_type = getattr(self, "_prenormalized_conn_type", self.conn_type)
or ""
+ if "_" in conn_type:
self.log.warning(
"Connection schemes (type: %s) shall not contain '_' according
to RFC3986.",
- self.conn_type,
+ conn_type,
)
if self.conn_type:
diff --git a/airflow-core/tests/unit/models/test_connection.py
b/airflow-core/tests/unit/models/test_connection.py
index 6e0f9efbcd3..94cabe5e4da 100644
--- a/airflow-core/tests/unit/models/test_connection.py
+++ b/airflow-core/tests/unit/models/test_connection.py
@@ -23,6 +23,7 @@ from typing import TYPE_CHECKING
from unittest import mock
import pytest
+from structlog.testing import capture_logs
from airflow.exceptions import AirflowException, AirflowNotFoundException
from airflow.models import Connection
@@ -270,6 +271,55 @@ class TestConnection:
def test_get_uri(self, connection, expected_uri):
assert connection.get_uri() == expected_uri
+ @pytest.mark.parametrize(
+ ("connection", "expected_warned"),
+ [
+ (Connection(conn_id="test-uri-1",
uri="google-cloud-platform://testlogin:testpassword@"), False),
+ (Connection(conn_id="test-uri-2", uri="amazon://test:test@"),
False),
+ (
+ Connection(
+ conn_id="test-non-uri-1",
+ conn_type="google-cloud-platform",
+ login="testlogin",
+ password="testpassword",
+ ),
+ False,
+ ),
+ (
+ Connection(
+ conn_id="test-non-uri-2",
+ conn_type="google_cloud_platform",
+ login="testlogin",
+ password="testpassword",
+ ),
+ True,
+ ),
+ (
+ Connection(
+ conn_id="test-non-uri-3", conn_type="amazon",
login="testlogin", password="testpassword"
+ ),
+ False,
+ ),
+ ],
+ )
+ def test_get_uri_conn_type_warning(self, connection: Connection,
expected_warned: bool):
+ with capture_logs() as captured_logs:
+ connection.get_uri()
+ conn_type_warnings = list(
+ filter(
+ lambda captured_log: (
+ captured_log["log_level"] == "warning" and "RFC3986" in
captured_log["event"]
+ ),
+ captured_logs,
+ )
+ )
+ if expected_warned:
+ assert conn_type_warnings, f"RFC3986 warning expected for
connection '{connection.conn_id}'."
+ else:
+ assert not conn_type_warnings, (
+ f"RFC3986 warning not expected for connection
'{connection.conn_id}'."
+ )
+
@pytest.mark.parametrize(
("connection", "expected_conn_id"),
[