From b175a3cce4eb69ca30a6461c8cd0cf130f28c6b1 Mon Sep 17 00:00:00 2001 From: Lazizbek Ergashev Date: Fri, 28 Aug 2026 16:57:49 +0500 Subject: [PATCH 1/2] fix(embeddings): check for numpy once per response --- src/openai/lib/_parsing/_embeddings.py | 4 +++- tests/lib/test_embeddings.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/openai/lib/_parsing/_embeddings.py b/src/openai/lib/_parsing/_embeddings.py index acb890fa52..13a9279730 100644 --- a/src/openai/lib/_parsing/_embeddings.py +++ b/src/openai/lib/_parsing/_embeddings.py @@ -20,11 +20,13 @@ def parse_embedding_response( if not obj.data: raise ValueError("No embedding data received") + use_numpy = has_numpy() + for embedding in obj.data: data = cast(object, embedding.embedding) if not isinstance(data, str): continue - if not has_numpy(): + if not use_numpy: # use array for base64 optimisation embedding.embedding = array.array("f", base64.b64decode(data)).tolist() else: diff --git a/tests/lib/test_embeddings.py b/tests/lib/test_embeddings.py index 787d580716..a3ff5b4fc0 100644 --- a/tests/lib/test_embeddings.py +++ b/tests/lib/test_embeddings.py @@ -63,6 +63,24 @@ def test_decode_preserves_response_and_non_string_vectors(encoding_format: Omit assert parsed.model == "text-embedding-3-small" +@pytest.mark.parametrize("encoding_format", [omit, not_given], ids=["omit", "not-given"]) +def test_decoder_is_inspected_once(encoding_format: Omit | NotGiven, monkeypatch: pytest.MonkeyPatch) -> None: + calls = 0 + + def counting_decoder() -> bool: + nonlocal calls + calls += 1 + return False + + monkeypatch.setattr(embeddings_parser, "has_numpy", counting_decoder) + response = make_response(ENCODED, ENCODED, ENCODED) + + parsed = embeddings_parser.parse_embedding_response(response, encoding_format=encoding_format) + + assert calls == 1 + assert [cast(object, item.embedding) for item in parsed.data] == [VALUES, VALUES, VALUES] + + @pytest.mark.parametrize("encoding_format", ["float", "base64", None]) @pytest.mark.parametrize("vectors", [(ENCODED,), ("abc",), ()], ids=["encoded", "invalid", "empty"]) def test_explicit_format_is_untouched( From c519bd1a76689da81e96da0547030de586662b4f Mon Sep 17 00:00:00 2001 From: Lazizbek Ergashev Date: Fri, 28 Aug 2026 17:19:53 +0500 Subject: [PATCH 2/2] fix(embeddings): only check for numpy when a vector needs decoding --- src/openai/lib/_parsing/_embeddings.py | 4 +++- tests/lib/test_embeddings.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/openai/lib/_parsing/_embeddings.py b/src/openai/lib/_parsing/_embeddings.py index 13a9279730..5fd8aea2c3 100644 --- a/src/openai/lib/_parsing/_embeddings.py +++ b/src/openai/lib/_parsing/_embeddings.py @@ -20,12 +20,14 @@ def parse_embedding_response( if not obj.data: raise ValueError("No embedding data received") - use_numpy = has_numpy() + use_numpy: bool | None = None for embedding in obj.data: data = cast(object, embedding.embedding) if not isinstance(data, str): continue + if use_numpy is None: + use_numpy = has_numpy() if not use_numpy: # use array for base64 optimisation embedding.embedding = array.array("f", base64.b64decode(data)).tolist() diff --git a/tests/lib/test_embeddings.py b/tests/lib/test_embeddings.py index a3ff5b4fc0..fab3a96e65 100644 --- a/tests/lib/test_embeddings.py +++ b/tests/lib/test_embeddings.py @@ -81,6 +81,19 @@ def counting_decoder() -> bool: assert [cast(object, item.embedding) for item in parsed.data] == [VALUES, VALUES, VALUES] +@pytest.mark.parametrize("encoding_format", [omit, not_given], ids=["omit", "not-given"]) +def test_float_vectors_skip_the_decoder(encoding_format: Omit | NotGiven, monkeypatch: pytest.MonkeyPatch) -> None: + def unexpected_decoder() -> bool: + raise AssertionError("a response without string vectors must not inspect the decoder") + + monkeypatch.setattr(embeddings_parser, "has_numpy", unexpected_decoder) + response = make_response(VALUES, [4.0, 5.0]) + + parsed = embeddings_parser.parse_embedding_response(response, encoding_format=encoding_format) + + assert [cast(object, item.embedding) for item in parsed.data] == [VALUES, [4.0, 5.0]] + + @pytest.mark.parametrize("encoding_format", ["float", "base64", None]) @pytest.mark.parametrize("vectors", [(ENCODED,), ("abc",), ()], ids=["encoded", "invalid", "empty"]) def test_explicit_format_is_untouched(