Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-mcp for openSUSE:Factory 
checked in at 2026-05-30 22:57:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mcp (Old)
 and      /work/SRC/openSUSE:Factory/.python-mcp.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-mcp"

Sat May 30 22:57:25 2026 rev:3 rq:1355963 version:1.27.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-mcp/python-mcp.changes    2026-04-17 
20:54:15.173050151 +0200
+++ /work/SRC/openSUSE:Factory/.python-mcp.new.1937/python-mcp.changes  
2026-05-30 23:00:00.452883361 +0200
@@ -1,0 +2,11 @@
+Fri May 29 16:58:45 UTC 2026 - Matej Cepl <[email protected]>
+
+- Update to 1.27.1:
+  - fix: catch PydanticUserError when generating output schema
+    (pydantic 2.13 compat)
+  - fix(auth): coerce empty-string optional URL fields to None in
+    OAuthClientMetadata
+  - build: restrict httpx to <1.0.0
+  - refactor: import SSEError from httpx_sse public API
+
+-------------------------------------------------------------------

Old:
----
  mcp-1.27.0.tar.gz

New:
----
  mcp-1.27.1.tar.gz

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

Other differences:
------------------
++++++ python-mcp.spec ++++++
--- /var/tmp/diff_new_pack.6fW0lo/_old  2026-05-30 23:00:01.332919537 +0200
+++ /var/tmp/diff_new_pack.6fW0lo/_new  2026-05-30 23:00:01.332919537 +0200
@@ -26,7 +26,7 @@
 %bcond_without libalternatives
 %{?sle15_python_module_pythons}
 Name:           python-mcp%{psuffix}
-Version:        1.27.0
+Version:        1.27.1
 Release:        0
 Summary:        Python implementation of the Model Context Protocol
 License:        MIT

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.6fW0lo/_old  2026-05-30 23:00:01.384921675 +0200
+++ /var/tmp/diff_new_pack.6fW0lo/_new  2026-05-30 23:00:01.388921839 +0200
@@ -1,5 +1,5 @@
-mtime: 1776178632
-commit: 6c52a8ad445a1d4865134bf7705797bd4ed8b0c4b0b229847f357e906a96e39a
-url: https://src.opensuse.org/AI_MCP/python-mcp
+mtime: 1780075977
+commit: b88951a85a4cfa4ebde098ef887234aa6a0fd8965abdb1d3090c2e73630d2903
+url: https://src.opensuse.org/AI/python-mcp
 revision: main
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-05-29 19:32:57.000000000 +0200
@@ -0,0 +1,6 @@
+_build.*
+*.obscpio
+*.osc
+.pbuild
+_service:*
+python-mcp-*-build/

++++++ mcp-1.27.0.tar.gz -> mcp-1.27.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/PKG-INFO new/mcp-1.27.1/PKG-INFO
--- old/mcp-1.27.0/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
+++ new/mcp-1.27.1/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: mcp
-Version: 1.27.0
+Version: 1.27.1
 Summary: Model Context Protocol SDK
 Project-URL: Homepage, https://modelcontextprotocol.io
 Project-URL: Repository, https://github.com/modelcontextprotocol/python-sdk
@@ -21,7 +21,7 @@
 Requires-Python: >=3.10
 Requires-Dist: anyio>=4.5
 Requires-Dist: httpx-sse>=0.4
-Requires-Dist: httpx>=0.27.1
+Requires-Dist: httpx<1.0.0,>=0.27.1
 Requires-Dist: jsonschema>=4.20.0
 Requires-Dist: pydantic-settings>=2.5.2
 Requires-Dist: pydantic<3.0.0,>=2.11.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/pyproject.toml 
new/mcp-1.27.1/pyproject.toml
--- old/mcp-1.27.0/pyproject.toml       2020-02-02 01:00:00.000000000 +0100
+++ new/mcp-1.27.1/pyproject.toml       2020-02-02 01:00:00.000000000 +0100
@@ -23,7 +23,7 @@
 ]
 dependencies = [
     "anyio>=4.5",
-    "httpx>=0.27.1",
+    "httpx>=0.27.1,<1.0.0",
     "httpx-sse>=0.4",
     "pydantic>=2.11.0,<3.0.0",
     "starlette>=0.27",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/src/mcp/client/sse.py 
new/mcp-1.27.1/src/mcp/client/sse.py
--- old/mcp-1.27.0/src/mcp/client/sse.py        2020-02-02 01:00:00.000000000 
+0100
+++ new/mcp-1.27.1/src/mcp/client/sse.py        2020-02-02 01:00:00.000000000 
+0100
@@ -8,8 +8,7 @@
 import httpx
 from anyio.abc import TaskStatus
 from anyio.streams.memory import MemoryObjectReceiveStream, 
MemoryObjectSendStream
-from httpx_sse import aconnect_sse
-from httpx_sse._exceptions import SSEError
+from httpx_sse import SSEError, aconnect_sse
 
 import mcp.types as types
 from mcp.shared._httpx_utils import McpHttpClientFactory, 
create_mcp_http_client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mcp-1.27.0/src/mcp/server/fastmcp/utilities/func_metadata.py 
new/mcp-1.27.1/src/mcp/server/fastmcp/utilities/func_metadata.py
--- old/mcp-1.27.0/src/mcp/server/fastmcp/utilities/func_metadata.py    
2020-02-02 01:00:00.000000000 +0100
+++ new/mcp-1.27.1/src/mcp/server/fastmcp/utilities/func_metadata.py    
2020-02-02 01:00:00.000000000 +0100
@@ -10,6 +10,7 @@
     BaseModel,
     ConfigDict,
     Field,
+    PydanticUserError,
     RootModel,
     WithJsonSchema,
     create_model,
@@ -411,9 +412,16 @@
         # Use StrictJsonSchema to raise exceptions instead of warnings
         try:
             schema = model.model_json_schema(schema_generator=StrictJsonSchema)
-        except (TypeError, ValueError, pydantic_core.SchemaError, 
pydantic_core.ValidationError) as e:
+        except (
+            PydanticUserError,
+            TypeError,
+            ValueError,
+            pydantic_core.SchemaError,
+            pydantic_core.ValidationError,
+        ) as e:
             # These are expected errors when a type can't be converted to a 
Pydantic schema
-            # TypeError: When Pydantic can't handle the type
+            # PydanticUserError: When Pydantic can't handle the type (e.g. 
PydanticInvalidForJsonSchema);
+            #   subclasses TypeError on pydantic <2.13 and RuntimeError on 
pydantic >=2.13
             # ValueError: When there are issues with the type definition 
(including our custom warnings)
             # SchemaError: When Pydantic can't build a schema
             # ValidationError: When validation fails
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/src/mcp/shared/auth.py 
new/mcp-1.27.1/src/mcp/shared/auth.py
--- old/mcp-1.27.0/src/mcp/shared/auth.py       2020-02-02 01:00:00.000000000 
+0100
+++ new/mcp-1.27.1/src/mcp/shared/auth.py       2020-02-02 01:00:00.000000000 
+0100
@@ -71,6 +71,24 @@
     software_id: str | None = None
     software_version: str | None = None
 
+    @field_validator(
+        "client_uri",
+        "logo_uri",
+        "tos_uri",
+        "policy_uri",
+        "jwks_uri",
+        mode="before",
+    )
+    @classmethod
+    def _empty_string_optional_url_to_none(cls, v: object) -> object:
+        # RFC 7591 §2 marks these URL fields OPTIONAL. Some authorization 
servers
+        # echo omitted metadata back as "" instead of dropping the keys, which
+        # AnyHttpUrl would otherwise reject — throwing away an otherwise valid
+        # registration response. Treat "" as absent.
+        if v == "":
+            return None
+        return v
+
     def validate_scope(self, requested_scope: str | None) -> list[str] | None:
         if requested_scope is None:
             return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/tests/shared/test_auth.py 
new/mcp-1.27.1/tests/shared/test_auth.py
--- old/mcp-1.27.0/tests/shared/test_auth.py    2020-02-02 01:00:00.000000000 
+0100
+++ new/mcp-1.27.1/tests/shared/test_auth.py    2020-02-02 01:00:00.000000000 
+0100
@@ -1,6 +1,9 @@
 """Tests for OAuth 2.0 shared code."""
 
-from mcp.shared.auth import OAuthMetadata
+import pytest
+from pydantic import ValidationError
+
+from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, 
OAuthMetadata
 
 
 class TestOAuthMetadata:
@@ -59,3 +62,80 @@
                 "token_endpoint_auth_methods_supported": 
["client_secret_basic", "client_secret_post"],
             }
         )
+
+
+# RFC 7591 §2 marks client_uri/logo_uri/tos_uri/policy_uri/jwks_uri as 
OPTIONAL.
+# Some authorization servers echo the client's omitted metadata back as ""
+# instead of dropping the keys; without coercion, AnyHttpUrl rejects "" and
+# the whole registration response is thrown away even though the server
+# returned a valid client_id.
+
+
[email protected](
+    "empty_field",
+    ["client_uri", "logo_uri", "tos_uri", "policy_uri", "jwks_uri"],
+)
+def test_optional_url_empty_string_coerced_to_none(empty_field: str):
+    data = {
+        "redirect_uris": ["https://example.com/callback";],
+        empty_field: "",
+    }
+    metadata = OAuthClientMetadata.model_validate(data)
+    assert getattr(metadata, empty_field) is None
+
+
+def test_all_optional_urls_empty_together():
+    data = {
+        "redirect_uris": ["https://example.com/callback";],
+        "client_uri": "",
+        "logo_uri": "",
+        "tos_uri": "",
+        "policy_uri": "",
+        "jwks_uri": "",
+    }
+    metadata = OAuthClientMetadata.model_validate(data)
+    assert metadata.client_uri is None
+    assert metadata.logo_uri is None
+    assert metadata.tos_uri is None
+    assert metadata.policy_uri is None
+    assert metadata.jwks_uri is None
+
+
+def test_valid_url_passes_through_unchanged():
+    data = {
+        "redirect_uris": ["https://example.com/callback";],
+        "client_uri": "https://udemy.com/";,
+    }
+    metadata = OAuthClientMetadata.model_validate(data)
+    assert str(metadata.client_uri) == "https://udemy.com/";
+
+
+def test_information_full_inherits_coercion():
+    """OAuthClientInformationFull subclasses OAuthClientMetadata, so the
+    same coercion applies to DCR responses parsed via the full model."""
+    data = {
+        "client_id": "abc123",
+        "redirect_uris": ["https://example.com/callback";],
+        "client_uri": "",
+        "logo_uri": "",
+        "tos_uri": "",
+        "policy_uri": "",
+        "jwks_uri": "",
+    }
+    info = OAuthClientInformationFull.model_validate(data)
+    assert info.client_id == "abc123"
+    assert info.client_uri is None
+    assert info.logo_uri is None
+    assert info.tos_uri is None
+    assert info.policy_uri is None
+    assert info.jwks_uri is None
+
+
+def test_invalid_non_empty_url_still_rejected():
+    """Coercion must only touch empty strings — garbage URLs still raise."""
+    data = {
+        "redirect_uris": ["https://example.com/callback";],
+        "client_uri": "not a url",
+    }
+    with pytest.raises(ValidationError):
+        OAuthClientMetadata.model_validate(data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp-1.27.0/uv.lock new/mcp-1.27.1/uv.lock
--- old/mcp-1.27.0/uv.lock      2020-02-02 01:00:00.000000000 +0100
+++ new/mcp-1.27.1/uv.lock      2020-02-02 01:00:00.000000000 +0100
@@ -819,7 +819,7 @@
 [package.metadata]
 requires-dist = [
     { name = "anyio", specifier = ">=4.5" },
-    { name = "httpx", specifier = ">=0.27.1" },
+    { name = "httpx", specifier = ">=0.27.1,<1.0.0" },
     { name = "httpx-sse", specifier = ">=0.4" },
     { name = "jsonschema", specifier = ">=4.20.0" },
     { name = "pydantic", specifier = ">=2.11.0,<3.0.0" },

Reply via email to