1{ 2 lib, 3 stdenv, 4 buildPythonPackage, 5 fetchFromGitHub, 6 fetchurl, 7 replaceVars, 8 9 # build 10 libpq, 11 setuptools, 12 13 # propagates 14 typing-extensions, 15 16 # psycopg-c 17 cython, 18 tomli, 19 20 # docs 21 furo, 22 shapely, 23 sphinxHook, 24 sphinx-autodoc-typehints, 25 26 # tests 27 anyio, 28 pproxy, 29 pytest-randomly, 30 pytestCheckHook, 31 postgresql, 32 postgresqlTestHook, 33}: 34 35let 36 pname = "psycopg"; 37 version = "3.2.9"; 38 39 src = fetchFromGitHub { 40 owner = "psycopg"; 41 repo = "psycopg"; 42 tag = version; 43 hash = "sha256-mMhfULdvqphwdEqynLNq+7XCNmqmf+zi1SGumC/6qAc="; 44 }; 45 46 patches = [ 47 (replaceVars ./ctypes.patch { 48 libpq = "${libpq}/lib/libpq${stdenv.hostPlatform.extensions.sharedLibrary}"; 49 libc = "${stdenv.cc.libc}/lib/libc.so.6"; 50 }) 51 ]; 52 53 baseMeta = { 54 changelog = "https://github.com/psycopg/psycopg/blob/${version}/docs/news.rst#current-release"; 55 homepage = "https://github.com/psycopg/psycopg"; 56 license = lib.licenses.lgpl3Plus; 57 maintainers = with lib.maintainers; [ hexa ]; 58 }; 59 60 psycopg-c = buildPythonPackage { 61 pname = "${pname}-c"; 62 inherit version src; 63 format = "pyproject"; 64 65 # apply patches to base repo 66 inherit patches; 67 68 # move into source root after patching 69 postPatch = '' 70 cd psycopg_c 71 72 substituteInPlace pyproject.toml \ 73 --replace-fail "Cython >= 3.0.0, < 3.1.0" "Cython" 74 ''; 75 76 nativeBuildInputs = [ 77 cython 78 libpq.pg_config 79 setuptools 80 tomli 81 ]; 82 83 buildInputs = [ 84 libpq 85 ]; 86 87 # tested in psycopg 88 doCheck = false; 89 90 meta = baseMeta // { 91 description = "C optimisation distribution for Psycopg"; 92 }; 93 }; 94 95 psycopg-pool = buildPythonPackage { 96 pname = "${pname}-pool"; 97 inherit version src; 98 format = "setuptools"; 99 100 # apply patches to base repo 101 inherit patches; 102 103 # move into source root after patching 104 postPatch = '' 105 cd psycopg_pool 106 ''; 107 108 propagatedBuildInputs = [ typing-extensions ]; 109 110 # tested in psycopg 111 doCheck = false; 112 113 meta = baseMeta // { 114 description = "Connection Pool for Psycopg"; 115 }; 116 }; 117in 118 119buildPythonPackage rec { 120 inherit pname version src; 121 pyproject = true; 122 123 outputs = [ 124 "out" 125 ] 126 ++ lib.optionals (stdenv.hostPlatform == stdenv.buildPlatform) [ 127 "doc" 128 ]; 129 130 sphinxRoot = "../docs"; 131 132 # Introduce this file necessary for the docs build via environment var 133 LIBPQ_DOCS_FILE = fetchurl { 134 url = "https://raw.githubusercontent.com/postgres/postgres/496a1dc44bf1261053da9b3f7e430769754298b4/doc/src/sgml/libpq.sgml"; 135 hash = "sha256-JwtCngkoi9pb0pqIdNgukY8GbG5pUDZvrGAHZqjFOw4"; 136 }; 137 138 inherit patches; 139 140 # only move to sourceRoot after patching, makes patching easier 141 postPatch = '' 142 cd psycopg 143 ''; 144 145 nativeBuildInputs = [ 146 setuptools 147 ] 148 # building the docs fails with the following error when cross compiling 149 # AttributeError: module 'psycopg_c.pq' has no attribute '__impl__' 150 ++ lib.optionals (stdenv.hostPlatform == stdenv.buildPlatform) [ 151 furo 152 sphinx-autodoc-typehints 153 sphinxHook 154 shapely 155 ]; 156 157 propagatedBuildInputs = [ 158 psycopg-c 159 typing-extensions 160 ]; 161 162 pythonImportsCheck = [ 163 "psycopg" 164 "psycopg_c" 165 "psycopg_pool" 166 ]; 167 168 optional-dependencies = { 169 c = [ psycopg-c ]; 170 pool = [ psycopg-pool ]; 171 }; 172 173 nativeCheckInputs = [ 174 anyio 175 pproxy 176 pytest-randomly 177 pytestCheckHook 178 postgresql 179 ] 180 ++ lib.optional stdenv.hostPlatform.isLinux postgresqlTestHook 181 ++ optional-dependencies.c 182 ++ optional-dependencies.pool; 183 184 env = { 185 postgresqlEnableTCP = 1; 186 PGUSER = "psycopg"; 187 PGDATABASE = "psycopg"; 188 }; 189 190 preCheck = '' 191 cd .. 192 '' 193 + lib.optionalString stdenv.hostPlatform.isLinux '' 194 export PSYCOPG_TEST_DSN="host=/build/run/postgresql user=$PGUSER" 195 ''; 196 197 disabledTests = [ 198 # don't depend on mypy for tests 199 "test_version" 200 "test_package_version" 201 # expects timeout, but we have no route in the sandbox 202 "test_connect_error_multi_hosts_each_message_preserved" 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 pytestFlags = [ 215 "-ocache_dir=.cache" 216 ]; 217 218 disabledTestMarks = [ 219 "refcount" 220 "timing" 221 "flakey" 222 ]; 223 224 postCheck = '' 225 cd psycopg 226 ''; 227 228 passthru = { 229 c = psycopg-c; 230 pool = psycopg-pool; 231 }; 232 233 meta = baseMeta // { 234 description = "PostgreSQL database adapter for Python"; 235 }; 236}