Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-opentelemetry-instrumentation 
for openSUSE:Factory checked in at 2026-07-21 22:55:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-opentelemetry-instrumentation (Old)
 and      
/work/SRC/openSUSE:Factory/.python-opentelemetry-instrumentation.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-instrumentation"

Tue Jul 21 22:55:42 2026 rev:12 rq:1365748 version:0.64b0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-instrumentation/python-opentelemetry-instrumentation.changes
        2026-06-27 18:05:53.179545192 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-instrumentation.new.24530/python-opentelemetry-instrumentation.changes
     2026-07-21 22:56:24.229503917 +0200
@@ -1,0 +2,43 @@
+Tue Jul  7 19:03:44 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.64b0:
+  * ### Added
+  * `opentelemetry-instrumentation-exceptions`: add
+    instrumentation to emit OpenTelemetry logs for uncaught
+    process, thread, and asyncio exceptions.
+  * `opentelemetry-instrumentation-botocore`: loosen aiobotocore
+    version constraints to allow for 3.x
+  * `opentelemetry-instrumentation-logging`: add optional
+    `inject_trace_context` argument for injecting trace context
+    attributes
+  * `opentelemetry-instrumentation-redis`: gracefully handle hook
+    exceptions
+  * ### Changed
+  * opentelemetry-instrumentation-requests: remove multiple calls
+    to sanitize_method
+  * ### Fixed
+  * `opentelemetry-instrumentation-django`: Remove duplicate
+    query logging in SQLCommenter middleware that broke Django's
+    `assertNumQueries`
+  * `opentelemetry-instrumentation-flask`: wrap wsgi_app call in
+    try/except to prevent active_requests gauge leak
+  * `opentelemetry-instrumentation-asyncpg`: instrument prepared
+    statements
+  * `opentelemetry-instrumentation-aiokafka`, `opentelemetry-
+    instrumentation-confluent-kafka`, `opentelemetry-
+    instrumentation-kafka-python`: fix malformed RST formatting
+    in module docstrings
+  * `opentelemetry-instrumentation-dbapi`: Fix pyodbc DB-API
+    instrumentation examples to wrap `connect`.
+  * `opentelemetry-instrumentation-tornado`: reduce cardinality
+    of `http.target` metrics attribute with old semantic
+    conventions
+  * `opentelemetry-instrumentation-dbapi`: implement proper
+    handling of t-string queries
+  * `opentelemetry-instrumentation-fastapi`: fix `AttributeError`
+    when resolving routes added via `include_router` on FastAPI
+    0.137+
+  * `opentelemetry-instrumentation-tornado`: sanitize the request
+    http method in server and client spans and metrics
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_instrumentation-0.63b1.tar.gz

New:
----
  opentelemetry_instrumentation-0.64b0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-opentelemetry-instrumentation.spec ++++++
--- /var/tmp/diff_new_pack.ejuQ92/_old  2026-07-21 22:56:24.749521826 +0200
+++ /var/tmp/diff_new_pack.ejuQ92/_new  2026-07-21 22:56:24.753521963 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-opentelemetry-instrumentation
-Version:        0.63b1
+Version:        0.64b0
 Release:        0
 Summary:        Instrumentation Tools & Auto Instrumentation for OpenTelemetry 
Python
 License:        Apache-2.0

++++++ opentelemetry_instrumentation-0.63b1.tar.gz -> 
opentelemetry_instrumentation-0.64b0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/opentelemetry_instrumentation-0.63b1/PKG-INFO 
new/opentelemetry_instrumentation-0.64b0/PKG-INFO
--- old/opentelemetry_instrumentation-0.63b1/PKG-INFO   2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_instrumentation-0.64b0/PKG-INFO   2020-02-02 
01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: opentelemetry-instrumentation
-Version: 0.63b1
+Version: 0.64b0
 Summary: Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation
 Project-URL: Repository, 
https://github.com/open-telemetry/opentelemetry-python-contrib
@@ -19,7 +19,7 @@
 Classifier: Programming Language :: Python :: 3.14
 Requires-Python: >=3.10
 Requires-Dist: opentelemetry-api~=1.4
-Requires-Dist: opentelemetry-semantic-conventions==0.63b1
+Requires-Dist: opentelemetry-semantic-conventions==0.64b0
 Requires-Dist: packaging>=18.0
 Requires-Dist: wrapt<3.0.0,>=1.0.0
 Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/opentelemetry_instrumentation-0.63b1/pyproject.toml 
new/opentelemetry_instrumentation-0.64b0/pyproject.toml
--- old/opentelemetry_instrumentation-0.63b1/pyproject.toml     2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_instrumentation-0.64b0/pyproject.toml     2020-02-02 
01:00:00.000000000 +0100
@@ -26,7 +26,7 @@
 ]
 dependencies = [
   "opentelemetry-api ~= 1.4",
-  "opentelemetry-semantic-conventions == 0.63b1",
+  "opentelemetry-semantic-conventions == 0.64b0",
   "wrapt >= 1.0.0, < 3.0.0",
   "packaging >= 18.0",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/bootstrap_gen.py
 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/bootstrap_gen.py
--- 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/bootstrap_gen.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/bootstrap_gen.py
 2020-02-02 01:00:00.000000000 +0100
@@ -15,199 +15,200 @@
     },
     {
         "library": "aio_pika >= 7.2.0, < 10.0.0",
-        "instrumentation": "opentelemetry-instrumentation-aio-pika==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-aio-pika==0.64b0",
     },
     {
         "library": "aiohttp ~= 3.0",
-        "instrumentation": 
"opentelemetry-instrumentation-aiohttp-client==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-aiohttp-client==0.64b0",
     },
     {
         "library": "aiohttp ~= 3.0",
-        "instrumentation": 
"opentelemetry-instrumentation-aiohttp-server==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-aiohttp-server==0.64b0",
     },
     {
         "library": "aiokafka >= 0.8, < 1.0",
-        "instrumentation": "opentelemetry-instrumentation-aiokafka==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-aiokafka==0.64b0",
     },
     {
         "library": "aiopg >= 0.13.0, < 2.0.0",
-        "instrumentation": "opentelemetry-instrumentation-aiopg==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-aiopg==0.64b0",
     },
     {
         "library": "asgiref ~= 3.0",
-        "instrumentation": "opentelemetry-instrumentation-asgi==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-asgi==0.64b0",
     },
     {
         "library": "asyncclick ~= 8.0",
-        "instrumentation": "opentelemetry-instrumentation-asyncclick==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-asyncclick==0.64b0",
     },
     {
         "library": "asyncpg >= 0.12.0",
-        "instrumentation": "opentelemetry-instrumentation-asyncpg==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-asyncpg==0.64b0",
     },
     {
         "library": "boto3 ~= 1.0",
-        "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.64b0",
     },
     {
         "library": "botocore ~= 1.0",
-        "instrumentation": "opentelemetry-instrumentation-botocore==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-botocore==0.64b0",
     },
     {
-        "library": "aiobotocore ~= 2.0",
-        "instrumentation": "opentelemetry-instrumentation-botocore==0.63b1",
+        "library": "aiobotocore >= 2.0, < 4.0",
+        "instrumentation": "opentelemetry-instrumentation-botocore==0.64b0",
     },
     {
         "library": "cassandra-driver ~= 3.25",
-        "instrumentation": "opentelemetry-instrumentation-cassandra==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-cassandra==0.64b0",
     },
     {
         "library": "scylla-driver ~= 3.25",
-        "instrumentation": "opentelemetry-instrumentation-cassandra==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-cassandra==0.64b0",
     },
     {
         "library": "celery >= 4.0, < 6.0",
-        "instrumentation": "opentelemetry-instrumentation-celery==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-celery==0.64b0",
     },
     {
         "library": "click >= 8.1.3, < 9.0.0",
-        "instrumentation": "opentelemetry-instrumentation-click==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-click==0.64b0",
     },
     {
         "library": "confluent-kafka >= 1.8.2, < 3.0.0",
-        "instrumentation": 
"opentelemetry-instrumentation-confluent-kafka==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-confluent-kafka==0.64b0",
     },
     {
         "library": "django >= 2.0",
-        "instrumentation": "opentelemetry-instrumentation-django==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-django==0.64b0",
     },
     {
         "library": "elasticsearch >= 6.0",
-        "instrumentation": 
"opentelemetry-instrumentation-elasticsearch==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-elasticsearch==0.64b0",
     },
     {
         "library": "falcon >= 1.4.1, < 5.0.0",
-        "instrumentation": "opentelemetry-instrumentation-falcon==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-falcon==0.64b0",
     },
     {
         "library": "fastapi ~= 0.92",
-        "instrumentation": "opentelemetry-instrumentation-fastapi==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-fastapi==0.64b0",
     },
     {
         "library": "flask >= 1.0",
-        "instrumentation": "opentelemetry-instrumentation-flask==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-flask==0.64b0",
     },
     {
         "library": "grpcio >= 1.42.0",
-        "instrumentation": "opentelemetry-instrumentation-grpc==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-grpc==0.64b0",
     },
     {
         "library": "httpx >= 0.18.0",
-        "instrumentation": "opentelemetry-instrumentation-httpx==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-httpx==0.64b0",
     },
     {
         "library": "jinja2 >= 2.7, < 4.0",
-        "instrumentation": "opentelemetry-instrumentation-jinja2==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-jinja2==0.64b0",
     },
     {
         "library": "kafka-python >= 2.0, < 3.0",
-        "instrumentation": 
"opentelemetry-instrumentation-kafka-python==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-kafka-python==0.64b0",
     },
     {
         "library": "kafka-python-ng >= 2.0, < 3.0",
-        "instrumentation": 
"opentelemetry-instrumentation-kafka-python==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-kafka-python==0.64b0",
     },
     {
         "library": "mysql-connector-python >= 8.0, < 10.0",
-        "instrumentation": "opentelemetry-instrumentation-mysql==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-mysql==0.64b0",
     },
     {
         "library": "mysqlclient < 3",
-        "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.64b0",
     },
     {
         "library": "pika >= 0.12.0",
-        "instrumentation": "opentelemetry-instrumentation-pika==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pika==0.64b0",
     },
     {
         "library": "psycopg >= 3.1.0",
-        "instrumentation": "opentelemetry-instrumentation-psycopg==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-psycopg==0.64b0",
     },
     {
         "library": "psycopg2 >= 2.7.3.1",
-        "instrumentation": "opentelemetry-instrumentation-psycopg2==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-psycopg2==0.64b0",
     },
     {
         "library": "psycopg2-binary >= 2.7.3.1",
-        "instrumentation": "opentelemetry-instrumentation-psycopg2==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-psycopg2==0.64b0",
     },
     {
         "library": "pymemcache >= 1.3.5, < 5",
-        "instrumentation": "opentelemetry-instrumentation-pymemcache==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pymemcache==0.64b0",
     },
     {
         "library": "pymongo >= 3.1, < 5.0",
-        "instrumentation": "opentelemetry-instrumentation-pymongo==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pymongo==0.64b0",
     },
     {
         "library": "pymssql >= 2.1.5, < 3",
-        "instrumentation": "opentelemetry-instrumentation-pymssql==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pymssql==0.64b0",
     },
     {
         "library": "PyMySQL < 2",
-        "instrumentation": "opentelemetry-instrumentation-pymysql==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pymysql==0.64b0",
     },
     {
         "library": "pyramid >= 1.7",
-        "instrumentation": "opentelemetry-instrumentation-pyramid==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-pyramid==0.64b0",
     },
     {
         "library": "redis >= 2.6",
-        "instrumentation": "opentelemetry-instrumentation-redis==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-redis==0.64b0",
     },
     {
         "library": "remoulade >= 0.50",
-        "instrumentation": "opentelemetry-instrumentation-remoulade==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-remoulade==0.64b0",
     },
     {
         "library": "requests ~= 2.0",
-        "instrumentation": "opentelemetry-instrumentation-requests==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-requests==0.64b0",
     },
     {
         "library": "sqlalchemy >= 1.0.0, < 2.1.0",
-        "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.64b0",
     },
     {
         "library": "starlette >= 0.13",
-        "instrumentation": "opentelemetry-instrumentation-starlette==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-starlette==0.64b0",
     },
     {
         "library": "psutil >= 5",
-        "instrumentation": 
"opentelemetry-instrumentation-system-metrics==0.63b1",
+        "instrumentation": 
"opentelemetry-instrumentation-system-metrics==0.64b0",
     },
     {
         "library": "tornado >= 5.1.1",
-        "instrumentation": "opentelemetry-instrumentation-tornado==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-tornado==0.64b0",
     },
     {
         "library": "tortoise-orm >= 0.17.0",
-        "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.64b0",
     },
     {
         "library": "pydantic >= 1.10.2",
-        "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.64b0",
     },
     {
         "library": "urllib3 >= 1.0.0, < 3.0.0",
-        "instrumentation": "opentelemetry-instrumentation-urllib3==0.63b1",
+        "instrumentation": "opentelemetry-instrumentation-urllib3==0.64b0",
     },
 ]
 default_instrumentations = [
-    "opentelemetry-instrumentation-asyncio==0.63b1",
-    "opentelemetry-instrumentation-dbapi==0.63b1",
-    "opentelemetry-instrumentation-logging==0.63b1",
-    "opentelemetry-instrumentation-sqlite3==0.63b1",
-    "opentelemetry-instrumentation-threading==0.63b1",
-    "opentelemetry-instrumentation-urllib==0.63b1",
-    "opentelemetry-instrumentation-wsgi==0.63b1",
+    "opentelemetry-instrumentation-asyncio==0.64b0",
+    "opentelemetry-instrumentation-dbapi==0.64b0",
+    "opentelemetry-instrumentation-exceptions==0.64b0",
+    "opentelemetry-instrumentation-logging==0.64b0",
+    "opentelemetry-instrumentation-sqlite3==0.64b0",
+    "opentelemetry-instrumentation-threading==0.64b0",
+    "opentelemetry-instrumentation-urllib==0.64b0",
+    "opentelemetry-instrumentation-wsgi==0.64b0",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/sqlcommenter_utils.py
 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/sqlcommenter_utils.py
--- 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/sqlcommenter_utils.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/sqlcommenter_utils.py
    2020-02-02 01:00:00.000000000 +0100
@@ -1,16 +1,57 @@
 # Copyright The OpenTelemetry Authors
 # SPDX-License-Identifier: Apache-2.0
 
+from __future__ import annotations
+
+import itertools
+import sys
+from typing import TYPE_CHECKING, Any
+
 from opentelemetry import context
 from opentelemetry.instrumentation.utils import _url_quote
 
+if sys.version_info >= (3, 14):
+    from string.templatelib import Template as _Template
+else:
+    _Template = ()
+
+if TYPE_CHECKING:
+    if sys.version_info >= (3, 14):
+        from string.templatelib import Template
+    else:
+        from typing import Never
+
+        Template = Never
+    from typing import overload
+
+    @overload
+    def _add_sql_comment(sql: str, **meta: Any) -> str: ...
 
-def _add_sql_comment(sql, **meta) -> str:
+    @overload
+    def _add_sql_comment(sql: Template, **meta: Any) -> Template: ...
+
+
+def _add_sql_comment(sql: str | Template, **meta: Any) -> str | Template:
     """
     Appends comments to the sql statement and returns it
     """
     meta.update(**_add_framework_tags())
     comment = _generate_sql_comment(**meta)
+
+    if isinstance(sql, _Template):
+        last = sql.strings[-1].rstrip()
+        if last.endswith(";"):
+            last = last[:-1] + comment + ";"
+        else:
+            last += comment
+        args = [
+            *itertools.chain.from_iterable(
+                zip(sql.strings[:-1], sql.interpolations)
+            ),
+            last,
+        ]
+        return _Template(*args)
+
     sql = sql.rstrip()
     if sql.endswith(";"):
         sql = sql[:-1] + comment + ";"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/version.py
 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/version.py
--- 
old/opentelemetry_instrumentation-0.63b1/src/opentelemetry/instrumentation/version.py
       2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_instrumentation-0.64b0/src/opentelemetry/instrumentation/version.py
       2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,4 @@
 # Copyright The OpenTelemetry Authors
 # SPDX-License-Identifier: Apache-2.0
 
-__version__ = "0.63b1"
+__version__ = "0.64b0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_instrumentation-0.63b1/tests/test_utils.py 
new/opentelemetry_instrumentation-0.64b0/tests/test_utils.py
--- old/opentelemetry_instrumentation-0.63b1/tests/test_utils.py        
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_instrumentation-0.64b0/tests/test_utils.py        
2020-02-02 01:00:00.000000000 +0100
@@ -4,7 +4,9 @@
 import sys
 import unittest
 from http import HTTPStatus
+from unittest import mock
 
+import pytest
 from wrapt import wrap_function_wrapper
 
 try:
@@ -32,6 +34,26 @@
 from opentelemetry.trace import StatusCode
 
 
+class _MockInterpolation:
+    def __init__(self, expression: str) -> None:
+        self.expression = expression
+
+
+class _MockTemplate:
+    """Mock for string.templatelib.Template"""
+
+    def __init__(self, *args) -> None:
+        strings: list[str] = []
+        interpolations: list[_MockInterpolation] = []
+        for arg in args:
+            if isinstance(arg, str):
+                strings.append(arg)
+            else:
+                interpolations.append(arg)
+        self.strings = tuple(strings)
+        self.interpolations = interpolations
+
+
 class WrappedClass:
     def method(self):
         pass
@@ -40,6 +62,7 @@
         pass
 
 
+# pylint: disable=too-many-public-methods
 class TestUtils(unittest.TestCase):
     # See 
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status
     def test_http_status_to_status_code(self):
@@ -204,6 +227,96 @@
 
         self.assertEqual(commented_sql_without_semicolon, "Select 1")
 
+    @mock.patch(
+        "opentelemetry.instrumentation.sqlcommenter_utils._Template",
+        _MockTemplate,
+    )
+    def test_add_sql_comment_t_string_without_semicolon(self):
+        template = _MockTemplate(
+            "SELECT ", _MockInterpolation("val"), " FROM foo"
+        )
+        result = _add_sql_comment(template, k="v")
+        self.assertIsInstance(result, _MockTemplate)
+        self.assertEqual(result.strings, ("SELECT ", " FROM foo /*k='v'*/"))
+        self.assertEqual(result.interpolations[0].expression, "val")
+
+    @mock.patch(
+        "opentelemetry.instrumentation.sqlcommenter_utils._Template",
+        _MockTemplate,
+    )
+    def test_add_sql_comment_t_string_with_semicolon(self):
+        template = _MockTemplate(
+            "SELECT ", _MockInterpolation("val"), " FROM foo;"
+        )
+        result = _add_sql_comment(template, k="v")
+        self.assertIsInstance(result, _MockTemplate)
+        self.assertEqual(result.strings, ("SELECT ", " FROM foo /*k='v'*/;"))
+        self.assertEqual(result.interpolations[0].expression, "val")
+
+    @mock.patch(
+        "opentelemetry.instrumentation.sqlcommenter_utils._Template",
+        _MockTemplate,
+    )
+    def test_add_sql_comment_t_string_no_meta(self):
+        template = _MockTemplate(
+            "SELECT ", _MockInterpolation("val"), " FROM foo"
+        )
+        result = _add_sql_comment(template)
+        self.assertIsInstance(result, _MockTemplate)
+        self.assertEqual(result.strings, ("SELECT ", " FROM foo"))
+        self.assertEqual(result.interpolations[0].expression, "val")
+
+    @mock.patch(
+        "opentelemetry.instrumentation.sqlcommenter_utils._Template",
+        _MockTemplate,
+    )
+    def test_add_sql_comment_t_string_multiple_interpolations(self):
+        template = _MockTemplate(
+            "INSERT INTO t (a, b) VALUES (",
+            _MockInterpolation("a"),
+            ", ",
+            _MockInterpolation("b"),
+            ")",
+        )
+        result = _add_sql_comment(template, k="v")
+        self.assertIsInstance(result, _MockTemplate)
+        self.assertEqual(
+            result.strings,
+            ("INSERT INTO t (a, b) VALUES (", ", ", ") /*k='v'*/"),
+        )
+        self.assertEqual(result.interpolations[0].expression, "a")
+        self.assertEqual(result.interpolations[1].expression, "b")
+
+    @pytest.mark.skipif(
+        sys.version_info < (3, 14),
+        reason="requires Python 3.14+ for t-strings",
+    )
+    def test_add_sql_comment_real_t_string_without_semicolon(self):
+        # pylint: disable-next=import-outside-toplevel
+        from string.templatelib import Interpolation, Template  # noqa: PLC0415
+
+        val = 42
+        template = Template("SELECT ", Interpolation(val, "val"), " FROM foo")
+        result = _add_sql_comment(template, k="v")
+        self.assertIsInstance(result, Template)
+        self.assertEqual(result.strings, ("SELECT ", " FROM foo /*k='v'*/"))
+        self.assertEqual(result.interpolations[0].expression, "val")
+
+    @pytest.mark.skipif(
+        sys.version_info < (3, 14),
+        reason="requires Python 3.14+ for t-strings",
+    )
+    def test_add_sql_comment_real_t_string_with_semicolon(self):
+        # pylint: disable-next=import-outside-toplevel
+        from string.templatelib import Interpolation, Template  # noqa: PLC0415
+
+        val = 42
+        template = Template("SELECT ", Interpolation(val, "val"), " FROM foo;")
+        result = _add_sql_comment(template, k="v")
+        self.assertIsInstance(result, Template)
+        self.assertEqual(result.strings, ("SELECT ", " FROM foo /*k='v'*/;"))
+        self.assertEqual(result.interpolations[0].expression, "val")
+
     def test_is_instrumentation_enabled_by_default(self):
         self.assertTrue(is_instrumentation_enabled())
         self.assertTrue(is_http_instrumentation_enabled())

Reply via email to