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