1{ lib
2, stdenv
3, buildPythonPackage
4, pythonAtLeast
5, pythonOlder
6, fetchPypi
7, fetchpatch
8, python
9, appdirs
10, attrs
11, automat
12, bcrypt
13, constantly
14, cryptography
15, git
16, glibcLocales
17, h2
18, hyperlink
19, hypothesis
20, idna
21, incremental
22, priority
23, pyasn1
24, pyhamcrest
25, pynacl
26, pyopenssl
27, pyserial
28, service-identity
29, setuptools
30, typing-extensions
31, zope_interface
32
33 # for passthru.tests
34, cassandra-driver
35, klein
36, magic-wormhole
37, scrapy
38, treq
39, txaio
40, txamqp
41, txrequests
42, txtorcon
43, thrift
44, nixosTests
45}:
46
47buildPythonPackage rec {
48 pname = "twisted";
49 version = "22.10.0";
50 format = "setuptools";
51
52 disabled = pythonOlder "3.6";
53
54 src = fetchPypi {
55 pname = "Twisted";
56 inherit version;
57 extension = "tar.gz";
58 hash = "sha256-Mqy9QKlPX0bntCwQm/riswIlCUVWF4Oot6BZBI8tTTE=";
59 };
60
61 patches = [
62 (fetchpatch {
63 url = "https://github.com/twisted/twisted/pull/11787.diff";
64 hash = "sha256-bQgUmbvDa61Vg8p/o/ivfkOAHyj1lTgHkrRVEGLM9aU=";
65 })
66 (fetchpatch {
67 # Conditionally skip tests that require METHOD_CRYPT
68 # https://github.com/twisted/twisted/pull/11827
69 url = "https://github.com/mweinelt/twisted/commit/e69e652de671aac0abf5c7e6c662fc5172758c5a.patch";
70 hash = "sha256-LmvKUTViZoY/TPBmSlx4S9FbJNZfB5cxzn/YcciDmoI=";
71 })
72 # remove half broken pyasn1 integration that blow up with pyasn 0.5.0
73 # https://github.com/twisted/twisted/pull/11843
74 (fetchpatch {
75 url = "https://github.com/twisted/twisted/commit/bdee0eb835a76b2982beaf10c85269ff25ea09fa.patch";
76 excludes = [ "pyproject.toml" "tox.ini" ];
77 hash = "sha256-oGAHmZMpMWfK+2zEDjHD115sW7exCYqfORVOLw+Wa6M=";
78 })
79 ] ++ lib.optionals (pythonAtLeast "3.11") [
80 (fetchpatch {
81 url = "https://github.com/twisted/twisted/pull/11734.diff";
82 excludes = [ ".github/workflows/*" ];
83 hash = "sha256-Td08pDxHwl7fPLCA6rUySuXpy8YmZfvXPHGsBpdcmSo=";
84 })
85 (fetchpatch {
86 url = "https://github.com/twisted/twisted/commit/00bf5be704bee022ba4d9b24eb6c2c768b4a1921.patch";
87 hash = "sha256-fnBzczm3OlhbjRcePIQ7dSX6uldlCZ9DJTS+UFO2nAQ=";
88 })
89 ];
90
91 __darwinAllowLocalNetworking = true;
92
93 propagatedBuildInputs = [
94 attrs
95 automat
96 constantly
97 hyperlink
98 incremental
99 setuptools
100 typing-extensions
101 zope_interface
102 ];
103
104 postPatch = ''
105 substituteInPlace pyproject.toml \
106 --replace '"pyasn1 >= 0.4",' ""
107
108 echo 'ListingTests.test_localeIndependent.skip = "Timezone issue"'>> src/twisted/conch/test/test_cftp.py
109 echo 'ListingTests.test_newFile.skip = "Timezone issue"'>> src/twisted/conch/test/test_cftp.py
110 echo 'ListingTests.test_newSingleDigitDayOfMonth.skip = "Timezone issue"'>> src/twisted/conch/test/test_cftp.py
111 echo 'ListingTests.test_oldFile.skip = "Timezone issue"'>> src/twisted/conch/test/test_cftp.py
112 echo 'ListingTests.test_oldSingleDigitDayOfMonth.skip = "Timezone issue"'>> src/twisted/conch/test/test_cftp.py
113
114 echo 'UNIXTestsBuilder_AsyncioSelectorReactorTests.test_sendFileDescriptorTriggersPauseProducing.skip = "sendFileDescriptor producer was not paused"'>> src/twisted/internet/test/test_unix.py
115 echo 'UNIXTestsBuilder_SelectReactorTests.test_sendFileDescriptorTriggersPauseProducing.skip = "sendFileDescriptor producer was not paused"'>> src/twisted/internet/test/test_unix.py
116
117 echo 'FileObserverTests.test_getTimezoneOffsetEastOfUTC.skip = "mktime argument out of range"'>> src/twisted/test/test_log.py
118 echo 'FileObserverTests.test_getTimezoneOffsetWestOfUTC.skip = "mktime argument out of range"'>> src/twisted/test/test_log.py
119 echo 'FileObserverTests.test_getTimezoneOffsetWithoutDaylightSavingTime.skip = "tuple differs, values not"'>> src/twisted/test/test_log.py
120
121 echo 'MulticastTests.test_joinLeave.skip = "No such device"'>> src/twisted/test/test_udp.py
122 echo 'MulticastTests.test_loopback.skip = "No such device"'>> src/twisted/test/test_udp.py
123 echo 'MulticastTests.test_multicast.skip = "Reactor was unclean"'>> src/twisted/test/test_udp.py
124 echo 'MulticastTests.test_multiListen.skip = "No such device"'>> src/twisted/test/test_udp.py
125
126 # fails since migrating to libxcrypt
127 echo 'HelperTests.test_refuteCryptedPassword.skip = "OSError: Invalid argument"' >> src/twisted/conch/test/test_checkers.py
128
129 # not packaged
130 substituteInPlace src/twisted/test/test_failure.py \
131 --replace "from cython_test_exception_raiser import raiser # type: ignore[import]" "raiser = None"
132 '' + lib.optionalString stdenv.isLinux ''
133 echo 'PTYProcessTestsBuilder_EPollReactorTests.test_openFileDescriptors.skip = "invalid syntax"'>> src/twisted/internet/test/test_process.py
134 echo 'PTYProcessTestsBuilder_PollReactorTests.test_openFileDescriptors.skip = "invalid syntax"'>> src/twisted/internet/test/test_process.py
135 echo 'UNIXTestsBuilder_EPollReactorTests.test_sendFileDescriptorTriggersPauseProducing.skip = "sendFileDescriptor producer was not paused"'>> src/twisted/internet/test/test_unix.py
136 echo 'UNIXTestsBuilder_PollReactorTests.test_sendFileDescriptorTriggersPauseProducing.skip = "sendFileDescriptor producer was not paused"'>> src/twisted/internet/test/test_unix.py
137
138 # Patch t.p._inotify to point to libc. Without this,
139 # twisted.python.runtime.platform.supportsINotify() == False
140 substituteInPlace src/twisted/python/_inotify.py --replace \
141 "ctypes.util.find_library(\"c\")" "'${stdenv.cc.libc}/lib/libc.so.6'"
142 '' + lib.optionalString (stdenv.isAarch64 && stdenv.isDarwin) ''
143 echo 'AbortConnectionTests_AsyncioSelectorReactorTests.test_fullWriteBufferAfterByteExchange.skip = "Timeout after 120 seconds"' >> src/twisted/internet/test/test_tcp.py
144 echo 'AbortConnectionTests_AsyncioSelectorReactorTests.test_resumeProducingAbort.skip = "Timeout after 120 seconds"' >> src/twisted/internet/test/test_tcp.py
145
146 echo 'PosixReactorBaseTests.test_removeAllSkipsInternalReaders.skip = "Fails due to unclosed event loop"' >> src/twisted/internet/test/test_posixbase.py
147 echo 'PosixReactorBaseTests.test_wakerIsInternalReader.skip = "Fails due to unclosed event loop"' >> src/twisted/internet/test/test_posixbase.py
148
149 echo 'TCPPortTests.test_connectionLostFailed.skip = "Fails due to unclosed event loop"' >> src/twisted/internet/test/test_posixbase.py
150 '';
151
152 # Generate Twisted's plug-in cache. Twisted users must do it as well. See
153 # http://twistedmatrix.com/documents/current/core/howto/plugin.html#auto3
154 # and http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=477103 for details.
155 postFixup = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
156 $out/bin/twistd --help > /dev/null
157 '';
158
159 nativeCheckInputs = [
160 git
161 glibcLocales
162 # "hypothesis" indirectly depends on twisted to build its documentation.
163 (hypothesis.override { enableDocumentation = false; })
164 pyhamcrest
165 ]
166 ++ passthru.optional-dependencies.conch
167 # not supported on aarch64-darwin: https://github.com/pyca/pyopenssl/issues/873
168 ++ lib.optionals (!(stdenv.isDarwin && stdenv.isAarch64)) passthru.optional-dependencies.tls;
169
170 checkPhase = ''
171 export SOURCE_DATE_EPOCH=315532800
172 export PATH=$out/bin:$PATH
173 # race conditions when running in paralell
174 ${python.interpreter} -m twisted.trial twisted
175 '';
176
177 passthru = {
178 optional-dependencies = rec {
179 conch = [ appdirs bcrypt cryptography pyasn1 ];
180 conch_nacl = conch ++ [ pynacl ];
181 http2 = [ h2 priority ];
182 serial = [ pyserial ];
183 tls = [ idna pyopenssl service-identity ];
184 };
185
186 tests = {
187 inherit
188 cassandra-driver
189 klein
190 magic-wormhole
191 scrapy
192 treq
193 txaio
194 txamqp
195 txrequests
196 txtorcon
197 thrift;
198 inherit (nixosTests) buildbot matrix-synapse;
199 };
200 };
201
202 meta = with lib; {
203 homepage = "https://github.com/twisted/twisted";
204 description = "Asynchronous networking framework written in Python";
205 license = licenses.mit;
206 maintainers = with maintainers; [ SuperSandro2000 ];
207 };
208}