1{ 2 buildPackages, 3 buildPythonPackage, 4 fetchpatch, 5 isPyPy, 6 lib, 7 numpy, 8 protobuf, 9 pytestCheckHook, 10 pythonAtLeast, 11 substituteAll, 12 tzdata, 13}: 14 15assert lib.versionOlder protobuf.version "21" -> throw "Protobuf 21 or newer required"; 16 17let 18 protobufVersionMajor = lib.versions.major protobuf.version; 19 protobufVersionMinor = lib.versions.minor protobuf.version; 20in 21buildPythonPackage { 22 inherit (protobuf) pname src; 23 24 # protobuf 21 corresponds with its python library 4.21 25 version = "4.${protobufVersionMajor}.${protobufVersionMinor}"; 26 format = "setuptools"; 27 28 sourceRoot = "${protobuf.src.name}/python"; 29 30 patches = 31 lib.optionals (lib.versionAtLeast protobuf.version "22") [ 32 # Replace the vendored abseil-cpp with nixpkgs' 33 (substituteAll { 34 src = ./use-nixpkgs-abseil-cpp.patch; 35 abseil_cpp_include_path = "${lib.getDev protobuf.abseil-cpp}/include"; 36 }) 37 ] 38 ++ lib.optionals (pythonAtLeast "3.11" && lib.versionOlder protobuf.version "22") [ 39 (fetchpatch { 40 name = "support-python311.patch"; 41 url = "https://github.com/protocolbuffers/protobuf/commit/2206b63c4649cf2e8a06b66c9191c8ef862ca519.diff"; 42 stripLen = 1; # because sourceRoot above 43 hash = "sha256-3GaoEyZIhS3QONq8LEvJCH5TdO9PKnOgcQF0GlEiwFo="; 44 }) 45 ]; 46 47 prePatch = '' 48 if [[ "$(<../version.json)" != *'"python": "'"$version"'"'* ]]; then 49 echo "Python library version mismatch. Derivation version: $version, actual: $(<../version.json)" 50 exit 1 51 fi 52 ''; 53 54 # Remove the line in setup.py that forces compiling with C++14. Upstream's 55 # CMake build has been updated to support compiling with other versions of 56 # C++, but the Python build has not. Without this, we observe compile-time 57 # errors using GCC. 58 # 59 # Fedora appears to do the same, per this comment: 60 # 61 # https://github.com/protocolbuffers/protobuf/issues/12104#issuecomment-1542543967 62 # 63 postPatch = '' 64 sed -i "/extra_compile_args.append('-std=c++14')/d" setup.py 65 66 # The former function has been renamed into the latter in Python 3.12. 67 # Does not apply to all protobuf versions, hence --replace-warn. 68 substituteInPlace google/protobuf/internal/json_format_test.py \ 69 --replace-warn assertRaisesRegexp assertRaisesRegex 70 ''; 71 72 nativeBuildInputs = lib.optional isPyPy tzdata; 73 74 buildInputs = [ protobuf ]; 75 76 propagatedNativeBuildInputs = [ 77 # For protoc of the same version. 78 buildPackages."protobuf_${protobufVersionMajor}" 79 ]; 80 81 setupPyGlobalFlags = [ "--cpp_implementation" ]; 82 83 nativeCheckInputs = [ 84 pytestCheckHook 85 ] ++ lib.optionals (lib.versionAtLeast protobuf.version "22") [ numpy ]; 86 87 disabledTests = lib.optionals isPyPy [ 88 # error message differs 89 "testInvalidTimestamp" 90 # requires tracemalloc which pypy does not implement 91 # https://foss.heptapod.net/pypy/pypy/-/issues/3048 92 "testUnknownFieldsNoMemoryLeak" 93 # assertion is not raised for some reason 94 "testStrictUtf8Check" 95 ]; 96 97 disabledTestPaths = 98 lib.optionals (lib.versionAtLeast protobuf.version "23") [ 99 # The following commit (I think) added some internal test logic for Google 100 # that broke generator_test.py. There is a new proto file that setup.py is 101 # not generating into a .py file. However, adding this breaks a bunch of 102 # conflict detection in descriptor_test.py that I don't understand. So let's 103 # just disable generator_test.py for now. 104 # 105 # https://github.com/protocolbuffers/protobuf/commit/5abab0f47e81ac085f0b2d17ec3b3a3b252a11f1 106 # 107 "google/protobuf/internal/generator_test.py" 108 ] 109 ++ lib.optionals (lib.versionAtLeast protobuf.version "25") [ 110 "minimal_test.py" # ModuleNotFoundError: No module named 'google3' 111 ]; 112 113 pythonImportsCheck = [ 114 "google.protobuf" 115 "google.protobuf.internal._api_implementation" # Verify that --cpp_implementation worked 116 ]; 117 118 passthru = { 119 inherit protobuf; 120 }; 121 122 meta = with lib; { 123 description = "Protocol Buffers are Google's data interchange format"; 124 homepage = "https://developers.google.com/protocol-buffers/"; 125 license = licenses.bsd3; 126 maintainers = with maintainers; [ knedlsepp ]; 127 # Tests are currently failing because backend is unavailable and causes tests to fail 128 # Progress tracked in https://github.com/NixOS/nixpkgs/pull/264902 129 broken = lib.versionAtLeast protobuf.version "26"; 130 }; 131}