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