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