Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package 
python-opentelemetry-exporter-otlp-proto-grpc for openSUSE:Factory checked in 
at 2026-03-30 18:30:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-grpc (Old)
 and      
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-grpc.new.1999
 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-exporter-otlp-proto-grpc"

Mon Mar 30 18:30:44 2026 rev:12 rq:1343483 version:1.40.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-grpc/python-opentelemetry-exporter-otlp-proto-grpc.changes
      2026-01-06 17:43:48.847738220 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-grpc.new.1999/python-opentelemetry-exporter-otlp-proto-grpc.changes
    2026-03-30 18:33:47.589313891 +0200
@@ -1,0 +2,11 @@
+Mon Mar 23 22:06:45 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.40.0:
+  * Fix re-initialization of gRPC channel on UNAVAILABLE error
+  * Allow loading all resource detectors by setting
+    `OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` to `*`
+  * Regenerate opentelemetry-proto code with v1.9.0 release
+  * Add python 3.14 support
+  * Silence events API warnings for internal users
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_exporter_otlp_proto_grpc-1.39.1.tar.gz

New:
----
  opentelemetry_exporter_otlp_proto_grpc-1.40.0.tar.gz

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

Other differences:
------------------
++++++ python-opentelemetry-exporter-otlp-proto-grpc.spec ++++++
--- /var/tmp/diff_new_pack.rREylo/_old  2026-03-30 18:33:48.377346836 +0200
+++ /var/tmp/diff_new_pack.rREylo/_new  2026-03-30 18:33:48.381347003 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-opentelemetry-exporter-otlp-proto-grpc
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-opentelemetry-exporter-otlp-proto-grpc
-Version:        1.39.1
+Version:        1.40.0
 Release:        0
 Summary:        OpenTelemetry Collector Protobuf over gRPC Exporter
 License:        Apache-2.0

++++++ opentelemetry_exporter_otlp_proto_grpc-1.39.1.tar.gz -> 
opentelemetry_exporter_otlp_proto_grpc-1.40.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/PKG-INFO 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/PKG-INFO
--- old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/PKG-INFO  2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/PKG-INFO  2020-02-02 
01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: opentelemetry-exporter-otlp-proto-grpc
-Version: 1.39.1
+Version: 1.40.0
 Summary: OpenTelemetry Collector Protobuf over gRPC Exporter
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-grpc
 Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python
@@ -18,14 +18,16 @@
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
 Requires-Python: >=3.9
 Requires-Dist: googleapis-common-protos~=1.57
 Requires-Dist: grpcio<2.0.0,>=1.63.2; python_version < '3.13'
-Requires-Dist: grpcio<2.0.0,>=1.66.2; python_version >= '3.13'
+Requires-Dist: grpcio<2.0.0,>=1.66.2; python_version == '3.13'
+Requires-Dist: grpcio<2.0.0,>=1.75.1; python_version >= '3.14'
 Requires-Dist: opentelemetry-api~=1.15
-Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.39.1
-Requires-Dist: opentelemetry-proto==1.39.1
-Requires-Dist: opentelemetry-sdk~=1.39.1
+Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.40.0
+Requires-Dist: opentelemetry-proto==1.40.0
+Requires-Dist: opentelemetry-sdk~=1.40.0
 Requires-Dist: typing-extensions>=4.6.0
 Provides-Extra: gcp-auth
 Requires-Dist: opentelemetry-exporter-credential-provider-gcp>=0.59b0; extra 
== 'gcp-auth'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/pyproject.toml 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/pyproject.toml
--- old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/pyproject.toml    
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/pyproject.toml    
2020-02-02 01:00:00.000000000 +0100
@@ -24,15 +24,17 @@
   "Programming Language :: Python :: 3.11",
   "Programming Language :: Python :: 3.12",
   "Programming Language :: Python :: 3.13",
+  "Programming Language :: Python :: 3.14",
 ]
 dependencies = [
   "googleapis-common-protos ~= 1.57",
   "grpcio >= 1.63.2, < 2.0.0; python_version < '3.13'",
-  "grpcio >= 1.66.2, < 2.0.0; python_version >= '3.13'",
+  "grpcio >= 1.66.2, < 2.0.0; python_version == '3.13'",
+  "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'",
   "opentelemetry-api ~= 1.15",
-  "opentelemetry-proto == 1.39.1",
-  "opentelemetry-sdk ~= 1.39.1",
-  "opentelemetry-exporter-otlp-proto-common == 1.39.1",
+  "opentelemetry-proto == 1.40.0",
+  "opentelemetry-sdk ~= 1.40.0",
+  "opentelemetry-exporter-otlp-proto-common == 1.40.0",
   "typing-extensions >= 4.6.0",
 ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/__init__.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/__init__.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/__init__.py
    2020-02-02 01:00:00.000000000 +0100
@@ -50,7 +50,7 @@
 
     # Resource can be required for some backends, e.g. Jaeger
     # If resource wouldn't be set - traces wouldn't appears in Jaeger
-    resource = Resource(attributes={
+    resource = Resource.create({
         "service.name": "service"
     })
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
    2020-02-02 01:00:00.000000000 +0100
@@ -12,7 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""OTLP Exporter"""
+"""OTLP Exporter
+
+This module provides a mixin class for OTLP exporters that send telemetry data
+to an OTLP-compatible receiver via gRPC. It includes a configurable 
reconnection
+logic to handle transient collector outages.
+
+"""
 
 import random
 import threading
@@ -251,9 +257,11 @@
     if certificate_file:
         client_key_file = environ.get(client_key_file_env_key)
         client_certificate_file = environ.get(client_certificate_file_env_key)
-        return _load_credentials(
+        credentials = _load_credentials(
             certificate_file, client_key_file, client_certificate_file
         )
+        if credentials is not None:
+            return credentials
     return ssl_channel_credentials()
 
 
@@ -261,10 +269,15 @@
 class OTLPExporterMixin(
     ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT, ExportStubT]
 ):
-    """OTLP span exporter
+    """OTLP gRPC exporter mixin.
+
+    This class provides the base functionality for OTLP exporters that send
+    telemetry data (spans or metrics) to an OTLP-compatible receiver via gRPC.
+    It includes a configurable reconnection mechanism to handle transient
+    receiver outages.
 
     Args:
-        endpoint: OpenTelemetry Collector receiver endpoint
+        endpoint: OTLP-compatible receiver endpoint
         insecure: Connection type
         credentials: ChannelCredentials object for server authentication
         headers: Headers to send when exporting
@@ -308,6 +321,8 @@
         if parsed_url.netloc:
             self._endpoint = parsed_url.netloc
 
+        self._insecure = insecure
+        self._credentials = credentials
         self._headers = headers or environ.get(OTEL_EXPORTER_OTLP_HEADERS)
         if isinstance(self._headers, str):
             temp_headers = parse_env_headers(self._headers, liberal=True)
@@ -336,37 +351,52 @@
         )
         self._collector_kwargs = None
 
-        compression = (
+        self._compression = (
             environ_to_compression(OTEL_EXPORTER_OTLP_COMPRESSION)
             if compression is None
             else compression
         ) or Compression.NoCompression
 
-        if insecure:
-            self._channel = insecure_channel(
-                self._endpoint,
-                compression=compression,
-                options=self._channel_options,
-            )
-        else:
+        self._channel = None
+        self._client = None
+
+        self._shutdown_in_progress = threading.Event()
+        self._shutdown = False
+
+        if not self._insecure:
             self._credentials = _get_credentials(
-                credentials,
+                self._credentials,
                 _OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER,
                 OTEL_EXPORTER_OTLP_CERTIFICATE,
                 OTEL_EXPORTER_OTLP_CLIENT_KEY,
                 OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
             )
+
+        self._initialize_channel_and_stub()
+
+    def _initialize_channel_and_stub(self):
+        """
+        Create a new gRPC channel and stub.
+
+        This method is used during initialization and by the reconnection
+        mechanism to reinitialize the channel on transient errors.
+        """
+        if self._insecure:
+            self._channel = insecure_channel(
+                self._endpoint,
+                compression=self._compression,
+                options=self._channel_options,
+            )
+        else:
+            assert self._credentials is not None
             self._channel = secure_channel(
                 self._endpoint,
                 self._credentials,
-                compression=compression,
+                compression=self._compression,
                 options=self._channel_options,
             )
         self._client = self._stub(self._channel)  # type: ignore 
[reportCallIssue]
 
-        self._shutdown_in_progress = threading.Event()
-        self._shutdown = False
-
     @abstractmethod
     def _translate_data(
         self,
@@ -388,6 +418,8 @@
         deadline_sec = time() + self._timeout
         for retry_num in range(_MAX_RETRYS):
             try:
+                if self._client is None:
+                    return self._result.FAILURE
                 self._client.Export(
                     request=self._translate_data(data),
                     metadata=self._headers,
@@ -407,6 +439,26 @@
                         retry_info.retry_delay.seconds
                         + retry_info.retry_delay.nanos / 1.0e9
                     )
+
+                # For UNAVAILABLE errors, reinitialize the channel to force 
reconnection
+                if error.code() == StatusCode.UNAVAILABLE and retry_num == 0:  
# type: ignore
+                    logger.debug(
+                        "Reinitializing gRPC channel for %s exporter due to 
UNAVAILABLE error",
+                        self._exporting,
+                    )
+                    try:
+                        if self._channel:
+                            self._channel.close()
+                    except Exception as e:
+                        logger.debug(
+                            "Error closing channel for %s exporter to %s: %s",
+                            self._exporting,
+                            self._endpoint,
+                            str(e),
+                        )
+                    # Enable channel reconnection for subsequent calls
+                    self._initialize_channel_and_stub()
+
                 if (
                     error.code() not in _RETRYABLE_ERROR_CODES  # type: ignore 
[reportAttributeAccessIssue]
                     or retry_num + 1 == _MAX_RETRYS
@@ -436,12 +488,19 @@
         return self._result.FAILURE  # type: ignore [reportReturnType]
 
     def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None:
+        """
+        Shut down the exporter.
+
+        Args:
+            timeout_millis: Timeout in milliseconds for shutting down the 
exporter.
+        """
         if self._shutdown:
             logger.warning("Exporter already shutdown, ignoring call")
             return
         self._shutdown = True
         self._shutdown_in_progress.set()
-        self._channel.close()
+        if self._channel:
+            self._channel.close()
 
     @property
     @abstractmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/version/__init__.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/version/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/src/opentelemetry/exporter/otlp/proto/grpc/version/__init__.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/src/opentelemetry/exporter/otlp/proto/grpc/version/__init__.py
    2020-02-02 01:00:00.000000000 +0100
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "1.39.1"
+__version__ = "1.40.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/tests/test_otlp_exporter_mixin.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/tests/test_otlp_exporter_mixin.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.39.1/tests/test_otlp_exporter_mixin.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.40.0/tests/test_otlp_exporter_mixin.py
 2020-02-02 01:00:00.000000000 +0100
@@ -15,13 +15,16 @@
 import threading
 import time
 import unittest
-from concurrent.futures import ThreadPoolExecutor
+from concurrent.futures import (  # pylint: disable=no-name-in-module
+    ThreadPoolExecutor,
+)
 from logging import WARNING, getLogger
 from platform import system
 from typing import Any, Optional, Sequence
 from unittest import TestCase
 from unittest.mock import Mock, patch
 
+import grpc
 from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
     Duration,
 )
@@ -89,8 +92,8 @@
     def _exporting(self):
         return "traces"
 
-    def shutdown(self, timeout_millis=30_000):
-        return OTLPExporterMixin.shutdown(self, timeout_millis)
+    def shutdown(self, timeout_millis: float = 30_000, **kwargs):
+        return OTLPExporterMixin.shutdown(self, timeout_millis, **kwargs)
 
 
 class TraceServiceServicerWithExportParams(TraceServiceServicer):
@@ -511,6 +514,16 @@
             self.assertEqual(mock_trace_service.num_requests, 2)
             self.assertAlmostEqual(after - before, 1.4, 1)
 
+    def test_channel_options_set_correctly(self):
+        """Test that gRPC channel options are set correctly for keepalive and 
reconnection"""
+        # This test verifies that the channel is created with the right options
+        # We patch grpc.insecure_channel to ensure it is called without errors
+        with patch(
+            "opentelemetry.exporter.otlp.proto.grpc.exporter.insecure_channel"
+        ) as mock_channel:
+            OTLPSpanExporterForTesting(insecure=True)
+            self.assertTrue(mock_channel.called)
+
     def test_otlp_headers_from_env(self):
         # pylint: disable=protected-access
         # This ensures that there is no other header than standard user-agent.
@@ -534,3 +547,27 @@
                 warning.records[-1].message,
                 "Failed to export traces to localhost:4317, error code: 
StatusCode.ALREADY_EXISTS",
             )
+
+    def test_unavailable_reconnects(self):
+        """Test that the exporter reconnects on UNAVAILABLE error"""
+        add_TraceServiceServicer_to_server(
+            TraceServiceServicerWithExportParams(StatusCode.UNAVAILABLE),
+            self.server,
+        )
+
+        # Spy on grpc.insecure_channel to verify it's called for reconnection
+        with patch(
+            "opentelemetry.exporter.otlp.proto.grpc.exporter.insecure_channel",
+            side_effect=grpc.insecure_channel,
+        ) as mock_insecure_channel:
+            # Mock sleep to avoid waiting
+            with patch("time.sleep"):
+                # We expect FAILURE because the server keeps returning 
UNAVAILABLE
+                # but we want to verify reconnection attempts happened
+                self.exporter.export([self.span])
+
+        # Verify that we attempted to reinitialize the channel (called 
insecure_channel)
+        # Since the initial channel was created in setUp (unpatched), this call
+        # must be from the reconnection logic.
+        self.assertTrue(mock_insecure_channel.called)
+        # Verify that reconnection enabled flag is set

Reply via email to