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