1{ lib
2, stdenv
3, buildPythonPackage
4, fetchFromGitHub
5, fetchpatch
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_3
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.12";
39
40 src = fetchFromGitHub {
41 owner = "psycopg";
42 repo = pname;
43 rev = "refs/tags/${version}";
44 hash = "sha256-2fd21aSCjwSwk8G0uS3cPGzLZfPVoJl2V5dG+akfCrE=";
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 # https://github.com/psycopg/psycopg/pull/669
55 # mark some tests as timing remove on next version update
56 (fetchpatch {
57 name = "mark_tests_as_timing.patch";
58 url = "https://github.com/psycopg/psycopg/commit/00a3c640dd836328ba15931b400b012171f648c2.patch";
59 hash = "sha256-DoVZv1yy9gHOKl0AdVLir+C+UztJZVjboLhS5af2944=";
60 })
61 ];
62
63 baseMeta = {
64 changelog = "https://github.com/psycopg/psycopg/blob/${version}/docs/news.rst#current-release";
65 homepage = "https://github.com/psycopg/psycopg";
66 license = lib.licenses.lgpl3Plus;
67 maintainers = with lib.maintainers; [ hexa ];
68 };
69
70 psycopg-c = buildPythonPackage {
71 pname = "${pname}-c";
72 inherit version src;
73 format = "pyproject";
74
75 # apply patches to base repo
76 inherit patches;
77
78 # move into source root after patching
79 postPatch = ''
80 cd psycopg_c
81 '';
82
83 nativeBuildInputs = [
84 cython_3
85 postgresql
86 setuptools
87 tomli
88 ];
89
90 # tested in psycopg
91 doCheck = false;
92
93 meta = baseMeta // {
94 description = "C optimisation distribution for Psycopg";
95 };
96 };
97
98 psycopg-pool = buildPythonPackage {
99 pname = "${pname}-pool";
100 inherit version src;
101 format = "setuptools";
102
103 # apply patches to base repo
104 inherit patches;
105
106 # move into source root after patching
107 postPatch = ''
108 cd psycopg_pool
109 '';
110
111 propagatedBuildInputs = [
112 typing-extensions
113 ];
114
115 # tested in psycopg
116 doCheck = false;
117
118 meta = baseMeta // {
119 description = "Connection Pool for Psycopg";
120 };
121 };
122
123in
124
125buildPythonPackage rec {
126 inherit pname version src;
127 format = "pyproject";
128
129 disabled = pythonOlder "3.7";
130
131 outputs = [
132 "out"
133 "doc"
134 ];
135
136 sphinxRoot = "../docs";
137
138 # Introduce this file necessary for the docs build via environment var
139 LIBPQ_DOCS_FILE = fetchurl {
140 url = "https://raw.githubusercontent.com/postgres/postgres/REL_14_STABLE/doc/src/sgml/libpq.sgml";
141 hash = "sha256-yn09fR9+7zQni8SvTG7BUmYRD7MK7u2arVAznWz2oAw=";
142 };
143
144 inherit patches;
145
146 # only move to sourceRoot after patching, makes patching easier
147 postPatch = ''
148 cd psycopg
149 '';
150
151 nativeBuildInputs = [
152 furo
153 setuptools
154 shapely
155 sphinx-autodoc-typehints
156 sphinxHook
157 ];
158
159 propagatedBuildInputs = [
160 psycopg-c
161 typing-extensions
162 ] ++ lib.optionals (pythonOlder "3.9") [
163 backports-zoneinfo
164 ];
165
166 pythonImportsCheck = [
167 "psycopg"
168 "psycopg_c"
169 "psycopg_pool"
170 ];
171
172 passthru.optional-dependencies = {
173 c = [ psycopg-c ];
174 pool = [ psycopg-pool ];
175 };
176
177 nativeCheckInputs = [
178 anyio
179 pproxy
180 pytest-randomly
181 pytestCheckHook
182 postgresql
183 ]
184 ++ lib.optional (stdenv.isLinux) postgresqlTestHook
185 ++ passthru.optional-dependencies.c
186 ++ passthru.optional-dependencies.pool;
187
188 env = {
189 postgresqlEnableTCP = 1;
190 PGUSER = "psycopg";
191 };
192
193 preCheck = ''
194 cd ..
195 '' + lib.optionalString (stdenv.isLinux) ''
196 export PSYCOPG_TEST_DSN="host=127.0.0.1 user=$PGUSER"
197 '';
198
199 disabledTests = [
200 # don't depend on mypy for tests
201 "test_version"
202 "test_package_version"
203 ];
204
205 disabledTestPaths = [
206 # Network access
207 "tests/test_dns.py"
208 "tests/test_dns_srv.py"
209 # Mypy typing test
210 "tests/test_typing.py"
211 "tests/crdb/test_typing.py"
212 ];
213
214 pytestFlagsArray = [
215 "-o" "cache_dir=$TMPDIR"
216 "-m" "'not timing'"
217 ];
218
219 postCheck = ''
220 cd ${pname}
221 '';
222
223 passthru = {
224 c = psycopg-c;
225 pool = psycopg-pool;
226 };
227
228 meta = baseMeta // {
229 description = "PostgreSQL database adapter for Python";
230 };
231}