1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 pythonAtLeast,
6 pythonOlder,
7 fetchPypi,
8 python,
9
10 # build-system
11 hatchling,
12 hatch-fancy-pypi-readme,
13
14 # dependencies
15 attrs,
16 automat,
17 constantly,
18 hyperlink,
19 incremental,
20 typing-extensions,
21 zope-interface,
22
23 # optional-dependencies
24 appdirs,
25 bcrypt,
26 cryptography,
27 h2,
28 idna,
29 priority,
30 pyopenssl,
31 pyserial,
32 service-identity,
33
34 # tests
35 cython-test-exception-raiser,
36 gitMinimal,
37 glibcLocales,
38 pyhamcrest,
39 hypothesis,
40
41 # for passthru.tests
42 cassandra-driver,
43 httpx,
44 klein,
45 magic-wormhole,
46 scrapy,
47 treq,
48 txaio,
49 txamqp,
50 txrequests,
51 txtorcon,
52 thrift,
53 nixosTests,
54}:
55
56buildPythonPackage rec {
57 pname = "twisted";
58 version = "25.5.0";
59 format = "pyproject";
60
61 disabled = pythonOlder "3.6";
62
63 src = fetchPypi {
64 inherit pname version;
65 extension = "tar.gz";
66 hash = "sha256-HesnI1jLa+Hj6PxvnIs2946w+nwiM9Lb4R7G/uBOoxY=";
67 };
68
69 __darwinAllowLocalNetworking = true;
70
71 nativeBuildInputs = [
72 hatchling
73 hatch-fancy-pypi-readme
74 incremental
75 ];
76
77 propagatedBuildInputs = [
78 attrs
79 automat
80 constantly
81 hyperlink
82 incremental
83 typing-extensions
84 zope-interface
85 ];
86
87 postPatch =
88 let
89 skippedTests = {
90 "src/twisted/conch/test/test_cftp.py" = [
91 # timezone issues
92 "ListingTests.test_localeIndependent"
93 "ListingTests.test_newSingleDigitDayOfMonth"
94 "ListingTests.test_oldFile"
95 "ListingTests.test_oldSingleDigitDayOfMonth"
96 "ListingTests.test_newFile"
97 ];
98 "src/twisted/test/test_log.py" = [
99 # wrong timezone offset calculation
100 "FileObserverTests.test_getTimezoneOffsetEastOfUTC"
101 "FileObserverTests.test_getTimezoneOffsetWestOfUTC"
102 "FileObserverTests.test_getTimezoneOffsetWithoutDaylightSavingTime"
103 ];
104 "src/twisted/test/test_udp.py" = [
105 # "No such device" (No multicast support in the build sandbox)
106 "MulticastTests.test_joinLeave"
107 "MulticastTests.test_loopback"
108 "MulticastTests.test_multicast"
109 "MulticastTests.test_multiListen"
110 ];
111 "src/twisted/trial/test/test_script.py" = [
112 # Fails in LXC containers with less than all cores available (limits.cpu)
113 "AutoJobsTests.test_cpuCount"
114 ];
115 "src/twisted/internet/test/test_unix.py" = [
116 # flaky?
117 "UNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing"
118 ];
119 }
120 // lib.optionalAttrs (pythonAtLeast "3.12") {
121 "src/twisted/trial/_dist/test/test_workerreporter.py" = [
122 "WorkerReporterTests.test_addSkipPyunit"
123 ];
124 "src/twisted/trial/_dist/test/test_worker.py" = [
125 "LocalWorkerAMPTests.test_runSkip"
126 ];
127 }
128 // lib.optionalAttrs (pythonOlder "3.13") {
129 # missing ciphers in the crypt module due to libxcrypt
130 "src/twisted/web/test/test_tap.py" = [
131 "ServiceTests.test_HTTPSFailureOnMissingSSL"
132 "ServiceTests.test_HTTPSFailureOnMissingSSL"
133 ];
134 "src/twisted/conch/test/test_checkers.py" = [
135 "HelperTests.test_refuteCryptedPassword"
136 "HelperTests.test_verifyCryptedPassword"
137 "HelperTests.test_verifyCryptedPasswordMD5"
138 "UNIXPasswordDatabaseTests.test_defaultCheckers"
139 "UNIXPasswordDatabaseTests.test_passInCheckers"
140 ];
141 "src/twisted/cred/test/test_strcred.py" = [
142 "UnixCheckerTests.test_isChecker"
143 "UnixCheckerTests.test_unixCheckerFailsPassword"
144 "UnixCheckerTests.test_unixCheckerFailsPasswordBytes"
145 "UnixCheckerTests.test_unixCheckerFailsUsername"
146 "UnixCheckerTests.test_unixCheckerFailsUsernameBytes"
147 "UnixCheckerTests.test_unixCheckerSucceeds"
148 "UnixCheckerTests.test_unixCheckerSucceedsBytes"
149 "CryptTests.test_verifyCryptedPassword"
150 "CryptTests.test_verifyCryptedPasswordOSError"
151 ];
152 # dependant on UnixCheckerTests.test_isChecker
153 "src/twisted/cred/test/test_cred.py" = [
154 "HashedPasswordOnDiskDatabaseTests.testBadCredentials"
155 "HashedPasswordOnDiskDatabaseTests.testGoodCredentials"
156 "HashedPasswordOnDiskDatabaseTests.testGoodCredentials_login"
157 "HashedPasswordOnDiskDatabaseTests.testHashedCredentials"
158 ];
159 }
160 // lib.optionalAttrs (pythonAtLeast "3.13") {
161 "src/twisted/web/test/test_flatten.py" = [
162 "FlattenerErrorTests.test_asynchronousFlattenError"
163 "FlattenerErrorTests.test_cancel"
164 ];
165 }
166 // lib.optionalAttrs stdenv.hostPlatform.isDarwin {
167 "src/twisted/internet/test/test_process.py" = [
168 # invalid syntaax
169 "ProcessTestsBuilder_AsyncioSelectorReactorTests.test_openFileDescriptors"
170 "ProcessTestsBuilder_SelectReactorTests.test_openFileDescriptors"
171 # exit code 120
172 "ProcessTestsBuilder_AsyncioSelectorReactorTests.test_processEnded"
173 "ProcessTestsBuilder_SelectReactorTests.test_processEnded"
174 ];
175 };
176 in
177 lib.concatStringsSep "\n" (
178 lib.mapAttrsToList (
179 file: tests: lib.concatMapStringsSep "\n" (test: ''echo '${test}.skip = ""' >> "${file}"'') tests
180 ) skippedTests
181 )
182 + lib.optionalString stdenv.hostPlatform.isLinux ''
183 # Patch t.p._inotify to point to libc. Without this,
184 # twisted.python.runtime.platform.supportsINotify() == False
185 substituteInPlace src/twisted/python/_inotify.py --replace-fail \
186 "ctypes.util.find_library(\"c\")" "'${stdenv.cc.libc}/lib/libc.so.6'"
187 '';
188
189 # Generate Twisted's plug-in cache. Twisted users must do it as well. See
190 # http://twistedmatrix.com/documents/current/core/howto/plugin.html#auto3
191 # and http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=477103 for details.
192 postFixup = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
193 $out/bin/twistd --help > /dev/null
194 '';
195
196 nativeCheckInputs = [
197 gitMinimal
198 glibcLocales
199 ]
200 ++ optional-dependencies.test
201 ++ optional-dependencies.conch
202 ++ optional-dependencies.http2
203 ++ optional-dependencies.serial
204 ++ optional-dependencies.tls;
205
206 preCheck = ''
207 export SOURCE_DATE_EPOCH=315532800
208 export PATH=$out/bin:$PATH
209 '';
210
211 checkPhase = ''
212 runHook preCheck
213 # race conditions when running in paralell
214 ${python.interpreter} -m twisted.trial -j1 twisted
215 runHook postCheck
216 '';
217
218 optional-dependencies = {
219 conch = [
220 appdirs
221 bcrypt
222 cryptography
223 ];
224 http2 = [
225 h2
226 priority
227 ];
228 serial = [ pyserial ];
229 test = [
230 cython-test-exception-raiser
231 pyhamcrest
232 hypothesis
233 httpx
234 ]
235 ++ httpx.optional-dependencies.http2;
236 tls = [
237 idna
238 pyopenssl
239 service-identity
240 ];
241 };
242
243 passthru = {
244 tests = {
245 inherit
246 cassandra-driver
247 klein
248 magic-wormhole
249 scrapy
250 treq
251 txaio
252 txamqp
253 txrequests
254 txtorcon
255 thrift
256 ;
257 inherit (nixosTests) buildbot matrix-synapse;
258 };
259 };
260
261 meta = with lib; {
262 changelog = "https://github.com/twisted/twisted/blob/twisted-${version}/NEWS.rst";
263 homepage = "https://github.com/twisted/twisted";
264 description = "Asynchronous networking framework written in Python";
265 license = licenses.mit;
266 maintainers = [ ];
267 };
268}