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