1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6 fetchurl,
7 pythonOlder,
8 substituteAll,
9
10 # build
11 postgresql,
12 setuptools,
13
14 # propagates
15 backports-zoneinfo,
16 typing-extensions,
17
18 # psycopg-c
19 cython,
20 tomli,
21
22 # docs
23 furo,
24 shapely,
25 sphinxHook,
26 sphinx-autodoc-typehints,
27
28 # tests
29 anyio,
30 pproxy,
31 pytest-randomly,
32 pytestCheckHook,
33 postgresqlTestHook,
34}:
35
36let
37 pname = "psycopg";
38 version = "3.1.19";
39
40 src = fetchFromGitHub {
41 owner = "psycopg";
42 repo = pname;
43 rev = "refs/tags/${version}";
44 hash = "sha256-Fvg67sGWSNwChZTO5QdLSOKrbGfxzQZJqCjI5Jidcqo=";
45 };
46
47 patches = [
48 (substituteAll {
49 src = ./ctypes.patch;
50 libpq = "${postgresql.lib}/lib/libpq${stdenv.hostPlatform.extensions.sharedLibrary}";
51 libc = "${stdenv.cc.libc}/lib/libc.so.6";
52 })
53 ];
54
55 baseMeta = {
56 changelog = "https://github.com/psycopg/psycopg/blob/${version}/docs/news.rst#current-release";
57 homepage = "https://github.com/psycopg/psycopg";
58 license = lib.licenses.lgpl3Plus;
59 maintainers = with lib.maintainers; [ hexa ];
60 };
61
62 psycopg-c = buildPythonPackage {
63 pname = "${pname}-c";
64 inherit version src;
65 format = "pyproject";
66
67 # apply patches to base repo
68 inherit patches;
69
70 # move into source root after patching
71 postPatch = ''
72 cd psycopg_c
73 '';
74
75 nativeBuildInputs = [
76 cython
77 postgresql
78 setuptools
79 tomli
80 ];
81
82 # tested in psycopg
83 doCheck = false;
84
85 meta = baseMeta // {
86 description = "C optimisation distribution for Psycopg";
87 };
88 };
89
90 psycopg-pool = buildPythonPackage {
91 pname = "${pname}-pool";
92 inherit version src;
93 format = "setuptools";
94
95 # apply patches to base repo
96 inherit patches;
97
98 # move into source root after patching
99 postPatch = ''
100 cd psycopg_pool
101 '';
102
103 propagatedBuildInputs = [ typing-extensions ];
104
105 # tested in psycopg
106 doCheck = false;
107
108 meta = baseMeta // {
109 description = "Connection Pool for Psycopg";
110 };
111 };
112in
113
114buildPythonPackage rec {
115 inherit pname version src;
116 format = "pyproject";
117
118 disabled = pythonOlder "3.7";
119
120 outputs = [
121 "out"
122 "doc"
123 ];
124
125 sphinxRoot = "../docs";
126
127 # Introduce this file necessary for the docs build via environment var
128 LIBPQ_DOCS_FILE = fetchurl {
129 url = "https://raw.githubusercontent.com/postgres/postgres/496a1dc44bf1261053da9b3f7e430769754298b4/doc/src/sgml/libpq.sgml";
130 hash = "sha256-JwtCngkoi9pb0pqIdNgukY8GbG5pUDZvrGAHZqjFOw4";
131 };
132
133 inherit patches;
134
135 # only move to sourceRoot after patching, makes patching easier
136 postPatch = ''
137 cd psycopg
138 '';
139
140 nativeBuildInputs = [
141 furo
142 setuptools
143 shapely
144 sphinx-autodoc-typehints
145 sphinxHook
146 ];
147
148 propagatedBuildInputs = [
149 psycopg-c
150 typing-extensions
151 ] ++ lib.optionals (pythonOlder "3.9") [ backports-zoneinfo ];
152
153 pythonImportsCheck = [
154 "psycopg"
155 "psycopg_c"
156 "psycopg_pool"
157 ];
158
159 passthru.optional-dependencies = {
160 c = [ psycopg-c ];
161 pool = [ psycopg-pool ];
162 };
163
164 nativeCheckInputs =
165 [
166 anyio
167 pproxy
168 pytest-randomly
169 pytestCheckHook
170 postgresql
171 ]
172 ++ lib.optional (stdenv.isLinux) postgresqlTestHook
173 ++ passthru.optional-dependencies.c
174 ++ passthru.optional-dependencies.pool;
175
176 env = {
177 postgresqlEnableTCP = 1;
178 PGUSER = "psycopg";
179 PGDATABASE = "psycopg";
180 };
181
182 preCheck =
183 ''
184 cd ..
185 ''
186 + lib.optionalString (stdenv.isLinux) ''
187 export PSYCOPG_TEST_DSN="host=/build/run/postgresql user=$PGUSER"
188 '';
189
190 disabledTests = [
191 # don't depend on mypy for tests
192 "test_version"
193 "test_package_version"
194 ];
195
196 disabledTestPaths = [
197 # Network access
198 "tests/test_dns.py"
199 "tests/test_dns_srv.py"
200 # Mypy typing test
201 "tests/test_typing.py"
202 "tests/crdb/test_typing.py"
203 ];
204
205 pytestFlagsArray = [
206 "-o"
207 "cache_dir=$TMPDIR"
208 "-m"
209 "'not refcount and not timing'"
210 # pytest.PytestRemovedIn9Warning: Marks applied to fixtures have no effect
211 "-W"
212 "ignore::pytest.PytestRemovedIn9Warning"
213 ];
214
215 postCheck = ''
216 cd ${pname}
217 '';
218
219 passthru = {
220 c = psycopg-c;
221 pool = psycopg-pool;
222 };
223
224 meta = baseMeta // {
225 description = "PostgreSQL database adapter for Python";
226 };
227}