CodeSampleX

샘플

protobuf 6.33.6: Know which protobuf backend actually loaded: upb ships inside the binary wheel, so a musl/Alpine image with no prebuilt wheel silently gets the pure-Python fallback with different descriptor types and no warning

검증된 샘플 — pypi protobuf 6.33.6: Know which protobuf backend actually loaded: upb ships inside the binary wheel, so a musl/Alpine image with no prebuilt wheel…

sha256:d7bea0b572b3364fc334f71559dbe438cfebc689607a583f66c1d6e1e9e2cc91

이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다. 통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다. MIT-0

실행 증거

선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.

증거 기준
서명된 컨트랙트 통과
검증 영수증
3
빌드한 서명 키
3
선언된 환경 python linux x64 python python pip

검증 실행 환경

환경 컨트랙트 단계 실행일
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-15
python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-18
python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104…
2026-09-08

케이스

HOW
목표
Know which protobuf backend actually loaded: upb ships inside the binary wheel, so a musl/Alpine image with no prebuilt wheel silently gets the pure-Python fallback with different descriptor types and no warning
패키지
심벌
  • google.protobuf.internal.api_implementation.Type
  • google.protobuf.descriptor.Descriptor
환경
python
생성일
2026-08-15T11:26:57Z

컨트랙트

  1. assert the default backend is whatever the platform's wheel provided: upb when the C extension is importable, python when it is not, with no warning either way
  2. assert the pure-Python fallback carries different descriptor classes (google.protobuf.descriptor rather than google._upb._message), so isinstance and __module__ checks written against upb stop matching
  3. assert PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python forces the pure-Python backend
  4. assert PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp keeps Type()=='cpp' with no _c_module and then fails loudly on import, rather than falling back
  5. assert an unsupported backend name raises ValueError naming the supported ones
  6. assert backend selection is cached at first import, so mutating the environment afterwards changes nothing

파일

  • NOTES.md
  • csx.json
  • requirements.lock
  • requirements.txt
  • test/contract.py

소스 아티팩트 내려받기 (tar.gz)

소스

NOTES.md
A model would set `PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION="cpp"` expecting fast C++ acceleration (legacy behavior from protobuf <= 3.x) or a graceful fallback to pure Python if C++ extensions are unavailable.

Instead, requesting `"cpp"` on modern protobuf wheels emits a `UserWarning: Selected implementation cpp is not available.` but leaves `api_implementation.Type() == "cpp"` with `_c_module = None` (unlike `"upb"` which actively falls back to `"python"` on missing extension). When `google.protobuf.descriptor` or any generated proto class is imported, it unconditionally tries `from google.protobuf.pyext import _message` and fails loudly with `ImportError: cannot import name '_message' from 'google.protobuf.pyext'`.
csx.json
{"case":{"caseId":"case:sha256:6483191fa9a850cace107ffc29c4bf0f6e9b4efc052f5db1ffeb3a045c8bf212","constraints":{"runtime":"python"},"contract":["assert the default backend is whatever the platform's wheel provided: upb when the C extension is importable, python when it is not, with no warning either way","assert the pure-Python fallback carries different descriptor classes (google.protobuf.descriptor rather than google._upb._message), so isinstance and __module__ checks written against upb stop matching","assert PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python forces the pure-Python backend","assert PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp keeps Type()=='cpp' with no _c_module and then fails loudly on import, rather than falling back","assert an unsupported backend name raises ValueError naming the supported ones","assert backend selection is cached at first import, so mutating the environment afterwards changes nothing"],"goal":"Know which protobuf backend actually loaded: upb ships inside the binary wheel, so a musl/Alpine image with no prebuilt wheel silently gets the pure-Python fallback with different descriptor types and no warning","kind":"HOW","packages":["pkg:pypi/protobuf@6.33.6"],"schemaVersion":1,"symbols":["google.protobuf.internal.api_implementation.Type","google.protobuf.descriptor.Descriptor"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/protobuf@6.33.6"],"schemaVersion":1,"symbols":["google.protobuf.internal.api_implementation.Type","google.protobuf.descriptor.Descriptor"],"verifierAdapter":"python@1"}
requirements.lock
protobuf==6.33.6
requirements.txt
protobuf==6.33.6
test/contract.py
import os
import sys
import warnings


def reset_proto_env(backend=None):
    """Reset environment and clear all protobuf modules from sys.modules."""
    if backend is None:
        os.environ.pop("PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION", None)
    else:
        os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = backend

    to_delete = [
        k
        for k in sys.modules
        if k.startswith("google.protobuf")
        or k.startswith("google._upb")
        or k.startswith("google3")
    ]
    for k in to_delete:
        del sys.modules[k]


def test_default_backend_follows_the_wheel_the_platform_got():
    # Naive expectation: "modern protobuf defaults to the upb C extension",
    # which is what every answer about this says.
    #
    # Reality: that is a statement about the WHEEL, not about protobuf. upb
    # ships inside the binary wheel. On a platform with no prebuilt wheel --
    # musl/Alpine being the one people actually hit, since the manylinux
    # wheels are glibc -- pip installs the pure-Python fallback and
    # api_implementation.Type() is "python". Nothing warns. The code runs,
    # 10-50x slower, and the descriptor types are different classes, so
    # anything that compares __module__ or isinstance against the upb types
    # silently stops matching.
    #
    # This is a one-line-of-Dockerfile difference: python:3.13-alpine versus
    # python:3.13-slim decides it.
    reset_proto_env(None)
    from google.protobuf.internal import api_implementation
    from google.protobuf import descriptor_pb2
    from google.protobuf.descriptor import Descriptor

    impl = api_implementation.Type()
    assert impl in ("upb", "python"), impl
    descriptor_module = type(descriptor_pb2.FileDescriptorProto.DESCRIPTOR).__module__

    if impl == "upb":
        assert api_implementation._c_module is not None
        assert api_implementation._c_module.__name__ == "google._upb._message"
        assert descriptor_module == "google._upb._message"
    else:
        # The fallback is not an error state and says nothing about itself.
        assert api_implementation._c_module is None
        assert descriptor_module == "google.protobuf.descriptor"
        try:
            import google._upb._message  # noqa: F401
            raise AssertionError(
                "the pure-Python backend was selected while the upb extension is importable"
            )
        except ImportError:
            pass
    assert isinstance(descriptor_pb2.FileDescriptorProto.DESCRIPTOR, Descriptor)
    print("default backend on this platform:", impl)


def test_explicit_python_backend():
    # Setting PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python forces pure Python implementation.
    reset_proto_env("python")
    from google.protobuf.internal import api_implementation
    from google.protobuf import descriptor_pb2
    from google.protobuf.descriptor import Descriptor

    assert api_implementation.Type() == "python"
    assert api_implementation._c_module is None
    assert type(descriptor_pb2.FileDescriptorProto.DESCRIPTOR).__module__ == "google.protobuf.descriptor"
    assert isinstance(descriptor_pb2.FileDescriptorProto.DESCRIPTOR, Descriptor)


def test_cpp_backend_missing_in_wheel_raises_import_error():
    # Naive expectation: setting 'cpp' enables C++ extension or falls back gracefully to Python.
    # Reality: api_implementation warns but keeps Type() == 'cpp' and _c_module is None.
    # Subsequent import of google.protobuf.descriptor attempts `from google.protobuf.pyext import _message`
    # and raises ImportError loudly (no fallback occurs).
    reset_proto_env("cpp")

    with warnings.catch_warnings(record=True) as caught_warnings:
        warnings.simplefilter("always")
        from google.protobuf.internal import api_implementation
        assert api_implementation.Type() == "cpp"
        assert api_implementation._c_module is None

    assert any(
        "Selected implementation cpp is not available" in str(w.message)
        for w in caught_warnings
    )

    try:
        from google.protobuf import descriptor
        raise AssertionError("Expected ImportError because cpp pyext._message is not in prebuilt wheels")
    except ImportError as err:
        assert "_message" in str(err)


def test_invalid_backend_name_raises_value_error():
    # Naive expectation: unknown backend strings default to python or are ignored.
    # Reality: api_implementation immediately raises ValueError listing supported backends.
    reset_proto_env("invalid_backend")
    try:
        from google.protobuf.internal import api_implementation
        raise AssertionError("Expected ValueError for unsupported backend")
    except ValueError as err:
        assert "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION" in str(err)
        assert "python" in str(err) and "cpp" in str(err) and "upb" in str(err)


def test_runtime_env_mutation_after_import_is_cached():
    # Backend selection is performed once during initial module load and cached.
    # Mutating os.environ later in the process has no effect.
    reset_proto_env("python")
    from google.protobuf.internal import api_implementation

    assert api_implementation.Type() == "python"
    os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "upb"
    assert api_implementation.Type() == "python"


if __name__ == "__main__":
    test_default_backend_follows_the_wheel_the_platform_got()
    test_explicit_python_backend()
    test_cpp_backend_missing_in_wheel_raises_import_error()
    test_invalid_backend_name_raises_value_error()
    test_runtime_env_mutation_after_import_is_cached()
    print("Contract assertions passed.")

오리진 시더

anonymous