From 8a9a6afcf02f089f932bc81431ab46a60af32134 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 20 Apr 2011 16:21:36 +0100 Subject: Fix crash when QSocketNotifier used with an invalid descriptor select code for open C file/socket descriptors was crashing in FD_SET if a QSocketNotifier was created with an invalid descriptor. Added two autotests to QSocketNotifier, one to check notifiers with bogus socket descriptors don't crash, the other to check that notifiers with posix socket descriptors do work. (symbian socket engine doesn't use them so they are not implicitly tested) Reviewed-by: mread Task-Number: QTBUG-18138 --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 6 ++ tests/auto/qsocketnotifier/qsocketnotifier.pro | 2 +- tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp | 109 +++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 79f2596..7166e7d 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1084,6 +1084,12 @@ bool QEventDispatcherSymbian::hasPendingEvents() void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier ) { + //check socket descriptor is usable + if (notifier->socket() >= FD_SETSIZE || notifier->socket() < 0) { + //same warning message as the unix event dispatcher for easy testing + qWarning("QSocketNotifier: Internal error"); + return; + } //note - this is only for "open C" file descriptors //for native sockets, an active object in the symbian socket engine handles this QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier); diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index c43c96a..27484c8 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -4,7 +4,7 @@ QT = core network requires(contains(QT_CONFIG,private_tests)) -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index 5594dc3..b31a6e6 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -53,6 +53,11 @@ #include #define NATIVESOCKETENGINE QNativeSocketEngine #endif +#ifdef Q_OS_UNIX +#include +#endif +#include +#include class tst_QSocketNotifier : public QObject { @@ -64,6 +69,8 @@ public: private slots: void unexpectedDisconnection(); void mixingWithTimers(); + void posixSockets(); + void bogusFds(); }; tst_QSocketNotifier::tst_QSocketNotifier() @@ -114,6 +121,9 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_SYMBIAN + QSKIP("Symbian socket engine psuedo descriptors can't be used for QSocketNotifier", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -163,10 +173,14 @@ void tst_QSocketNotifier::unexpectedDisconnection() UnexpectedDisconnectTester tester(&readEnd1, &readEnd2); + QTimer timer; + timer.setSingleShot(true); + timer.start(30000); do { // we have to wait until sequence value changes // as any event can make us jump out processing QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + QVERIFY(timer.isActive); //escape if test would hang } while(tester.sequence <= 0); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); @@ -179,6 +193,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif } class MixingWithTimersHelper : public QObject @@ -243,5 +258,99 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.socketActivated, true); } +void tst_QSocketNotifier::posixSockets() +{ +#ifndef Q_OS_UNIX + QSKIP("test only for posix", SkipAll); +#else + + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost, 0)); + + int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in addr; + addr.sin_addr.s_addr = htonl(0x7f000001); + addr.sin_family = AF_INET; + addr.sin_port = htons(server.serverPort()); + qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); + QVERIFY(server.waitForNewConnection(5000)); + QScopedPointer passive(server.nextPendingConnection()); + + ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); + + { + QSocketNotifier rn(posixSocket, QSocketNotifier::Read); + connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy readSpy(&rn, SIGNAL(activated(int))); + QSocketNotifier wn(posixSocket, QSocketNotifier::Write); + connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QSocketNotifier en(posixSocket, QSocketNotifier::Exception); + connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy errorSpy(&en, SIGNAL(activated(int))); + + passive->write("hello",6); + passive->waitForBytesWritten(5000); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 0); + QCOMPARE(errorSpy.count(), 0); + + char buffer[100]; + qt_safe_read(posixSocket, buffer, 100); + QCOMPARE(buffer, "hello"); + + qt_safe_write(posixSocket, "goodbye", 8); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 1); + QCOMPARE(errorSpy.count(), 0); + QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); + } + qt_safe_close(posixSocket); +#endif +} + +void tst_QSocketNotifier::bogusFds() +{ +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier max(std::numeric_limits::max(), QSocketNotifier::Read); + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Invalid socket specified"); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier min(std::numeric_limits::min(), QSocketNotifier::Write); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + //bogus magic number is the first pseudo socket descriptor from symbian socket engine. + QSocketNotifier bogus(0x40000000, QSocketNotifier::Exception); + QSocketNotifier largestlegal(FD_SETSIZE - 1, QSocketNotifier::Read); + + QSignalSpy maxspy(&max, SIGNAL(activated(int))); + QSignalSpy minspy(&min, SIGNAL(activated(int))); + QSignalSpy bogspy(&bogus, SIGNAL(activated(int))); + QSignalSpy llspy(&largestlegal, SIGNAL(activated(int))); + + //generate some unrelated socket activity + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost)); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTcpSocket client; + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(server.hasPendingConnections()); + + //check no activity on bogus notifiers + QCOMPARE(maxspy.count(), 0); + QCOMPARE(minspy.count(), 0); + QCOMPARE(bogspy.count(), 0); + QCOMPARE(llspy.count(), 0); +} + QTEST_MAIN(tst_QSocketNotifier) #include -- cgit v0.12 d='n144' href='#n144'>144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
c-api/arg,,:ref,"PyArg_ParseTuple(args, ""O|O:ref"", &object, &callback)"
c-api/list,,:high,list[low:high]
c-api/sequence,,:i2,del o[i1:i2]
c-api/sequence,,:i2,o[i1:i2]
c-api/unicode,,:end,str[start:end]
c-api/unicode,,:start,unicode[start:start+length]
distutils/examples,267,`,This is the description of the ``foobar`` package.
distutils/setupscript,,::,
extending/embedding,,:numargs,"if(!PyArg_ParseTuple(args, "":numargs""))"
extending/extending,,:myfunction,"PyArg_ParseTuple(args, ""D:myfunction"", &c);"
extending/extending,,:set,"if (PyArg_ParseTuple(args, ""O:set_callback"", &temp)) {"
extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {"
faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr("
faq/programming,,::,for x in sequence[::-1]:
faq/programming,,:reduce,"print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,"
faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,"
faq/windows,,:bd8afb90ebf2,"Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32"
howto/cporting,,:encode,"if (!PyArg_ParseTuple(args, ""O:encode_object"", &myobj))"
howto/cporting,,:say,"if (!PyArg_ParseTuple(args, ""U:say_hello"", &name))"
howto/curses,,:black,"colors when it activates color mode.  They are: 0:black, 1:red,"
howto/curses,,:red,"colors when it activates color mode.  They are: 0:black, 1:red,"
howto/curses,,:green,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/curses,,:yellow,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/curses,,:blue,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/curses,,:magenta,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/curses,,:cyan,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/curses,,:white,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white.  The"
howto/ipaddress,,:DB8,>>> ipaddress.ip_address('2001:DB8::1')
howto/ipaddress,,::,>>> ipaddress.ip_address('2001:DB8::1')
howto/ipaddress,,:db8,IPv6Address('2001:db8::1')
howto/ipaddress,,::,IPv6Address('2001:db8::1')
howto/ipaddress,,::,IPv6Address('::1')
howto/ipaddress,,:db8,>>> ipaddress.ip_network('2001:db8::0/96')
howto/ipaddress,,::,>>> ipaddress.ip_network('2001:db8::0/96')
howto/ipaddress,,:db8,IPv6Network('2001:db8::/96')
howto/ipaddress,,::,IPv6Network('2001:db8::/96')
howto/ipaddress,,:db8,IPv6Network('2001:db8::/128')
howto/ipaddress,,::,IPv6Network('2001:db8::/128')
howto/ipaddress,,:db8,IPv6Interface('2001:db8::1/96')
howto/ipaddress,,::,IPv6Interface('2001:db8::1/96')
howto/ipaddress,,:db8,>>> addr6 = ipaddress.ip_address('2001:db8::1')
howto/ipaddress,,::,>>> addr6 = ipaddress.ip_address('2001:db8::1')
howto/ipaddress,,:db8,>>> host6 = ipaddress.ip_interface('2001:db8::1/96')
howto/ipaddress,,::,>>> host6 = ipaddress.ip_interface('2001:db8::1/96')
howto/ipaddress,,:db8,>>> net6 = ipaddress.ip_network('2001:db8::0/96')
howto/ipaddress,,::,>>> net6 = ipaddress.ip_network('2001:db8::0/96')
howto/ipaddress,,:ffff,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
howto/ipaddress,,::,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
howto/ipaddress,,::,IPv6Address('::ffff:ffff')
howto/ipaddress,,:ffff,IPv6Address('::ffff:ffff')
howto/ipaddress,,:db8,'2001:db8::/96'
howto/ipaddress,,::,'2001:db8::/96'
howto/ipaddress,,:db8,>>> ipaddress.ip_interface('2001:db8::1/96')
howto/ipaddress,,::,>>> ipaddress.ip_interface('2001:db8::1/96')
howto/ipaddress,,:db8,'2001:db8::1'
howto/ipaddress,,::,'2001:db8::1'
howto/ipaddress,,:db8,IPv6Address('2001:db8::ffff:ffff')
howto/ipaddress,,::,IPv6Address('2001:db8::ffff:ffff')
howto/ipaddress,,:ffff,IPv6Address('2001:db8::ffff:ffff')
howto/logging,,:And,"WARNING:And this, too"
howto/logging,,:And,"WARNING:root:And this, too"
howto/logging,,:Doing,INFO:root:Doing something
howto/logging,,:Finished,INFO:root:Finished
howto/logging,,:logger,severity:logger name:message
howto/logging,,:Look,WARNING:root:Look before you leap!
howto/logging,,:message,severity:logger name:message
howto/logging,,:root,DEBUG:root:This message should go to the log file
howto/logging,,:root,INFO:root:Doing something
howto/logging,,:root,INFO:root:Finished
howto/logging,,:root,INFO:root:So should this
howto/logging,,:root,INFO:root:Started
howto/logging,,:root,"WARNING:root:And this, too"
howto/logging,,:root,WARNING:root:Look before you leap!
howto/logging,,:root,WARNING:root:Watch out!
howto/logging,,:So,INFO:root:So should this
howto/logging,,:So,INFO:So should this
howto/logging,,:Started,INFO:root:Started
howto/logging,,:This,DEBUG:root:This message should go to the log file
howto/logging,,:This,DEBUG:This message should appear on the console
howto/logging,,:Watch,WARNING:root:Watch out!
howto/pyporting,,::,Programming Language :: Python :: 2
howto/pyporting,,::,Programming Language :: Python :: 3
howto/regex,,::,
howto/regex,,:foo,(?:foo)
howto/urllib2,,:password,"for example ""joe:password@example.com"""
library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],"
library/bisect,32,:hi,all(val >= x for val in a[i:hi])
library/bisect,42,:hi,all(val > x for val in a[i:hi])
library/configparser,,:home,my_dir: ${Common:home_dir}/twosheds
library/configparser,,:option,${section:option}
library/configparser,,:path,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
library/configparser,,:Python,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
library/configparser,,:system,path: ${Common:system_dir}/Library/Frameworks/
library/datetime,,:MM,
library/datetime,,:SS,
library/decimal,,:optional,"trailneg:optional trailing minus indicator"
library/difflib,,:ahi,a[alo:ahi]
library/difflib,,:bhi,b[blo:bhi]
library/difflib,,:i1,
library/difflib,,:i2,
library/difflib,,:j2,
library/doctest,,`,``factorial`` from the ``example`` module:
library/doctest,,`,The ``example`` module
library/doctest,,`,Using ``factorial``
library/exceptions,,:err,err.object[err.start:err.end]
library/functions,,:step,a[start:stop:step]
library/functions,,:stop,"a[start:stop, i]"
library/functions,,:stop,a[start:stop:step]
library/hashlib-blake2,,:vatrogasac,>>> cookie = b'user:vatrogasac'
library/hashlib-blake2,,:vatrogasac,"user:vatrogasac,349cf904533767ed2d755279a8df84d0"
library/hashlib-blake2,,:policajac,">>> compare_digest(b'user:policajac', sig)"
library/hashlib-blake2,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH,"
library/http.client,,:port,host:port
library/http.cookies,,`,!#$%&'*+-.^_`|~:
library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS"
library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS"
library/inspect,,:int,">>> def foo(a, *, b:int, **kwargs):"
library/inspect,,:int,"'(a, *, b:int, **kwargs)'"
library/inspect,,:int,'b:int'
library/ipaddress,,:db8,>>> ipaddress.ip_address('2001:db8::')
library/ipaddress,,::,>>> ipaddress.ip_address('2001:db8::')
library/ipaddress,,:db8,IPv6Address('2001:db8::')
library/ipaddress,,::,IPv6Address('2001:db8::')
library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000')
library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000')
library/ipaddress,,:db8,IPv6Address('2001:db8::1000')
library/ipaddress,,::,IPv6Address('2001:db8::1000')
library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer"
library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer"
library/ipaddress,,::,"""::abc:7:def"""
library/ipaddress,,:def,"""::abc:7:def"""
library/ipaddress,,::,::FFFF/96
library/ipaddress,,::,2002::/16
library/ipaddress,,::,2001::/32
library/ipaddress,,::,>>> str(ipaddress.IPv6Address('::1'))
library/ipaddress,,::,'::1'
library/ipaddress,,:ff00,ffff:ff00::
library/ipaddress,,:db00,2001:db00::0/24
library/ipaddress,,::,2001:db00::0/24
library/ipaddress,,:db00,2001:db00::0/ffff:ff00::
library/ipaddress,,::,2001:db00::0/ffff:ff00::
library/itertools,,:step,elements from seq[start:stop:step]
library/itertools,,:stop,elements from seq[start:stop:step]
library/logging.handlers,,:port,host:port
library/mmap,,:i2,obj[i1:i2]
library/multiprocessing,,`,# Add more tasks using `put()`
library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)"
library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy
library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy
library/multiprocessing,,`,# register the generator function baz; use `GeneratorProxy` to make proxies
library/nntplib,,:bytes,:bytes
library/nntplib,,:lines,:lines
library/optparse,,:len,"del parser.rargs[:len(value)]"
library/os.path,,:foo,c:foo
library/pathlib,,:bar,">>> PureWindowsPath('c:/Windows', 'd:bar')"
library/pathlib,,:bar,PureWindowsPath('d:bar')
library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').root
library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').anchor
library/pdb,,:lineno,filename:lineno
library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")"
library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS"""
library/pprint,,::,"'Programming Language :: Python :: 2 :: Only'],"
library/pprint,,::,"'Programming Language :: Python :: 2.6',"
library/pprint,,::,"'Programming Language :: Python :: 2.7',"
library/profile,,:lineno,filename:lineno(function)
library/pyexpat,,:elem1,<py:elem1 />
library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">"
library/smtplib,,:port,method must support that as well as a regular host:port
library/socket,,::,'5aef:2b::8'
library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])"
library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})"
library/sqlite3,,:memory,
library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})"
library/sqlite3,,:path,"db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)"
library/ssl,,:My,"Organizational Unit Name (eg, section) []:My Group"
library/ssl,,:My,"Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc."
library/ssl,,:myserver,"Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com"
library/ssl,,:MyState,State or Province Name (full name) [Some-State]:MyState
library/ssl,,:ops,Email Address []:ops@myserver.mygroup.myorganization.com
library/ssl,,:Some,"Locality Name (eg, city) []:Some City"
library/ssl,,:US,Country Name (2 letter code) [AU]:US
library/stdtypes,,:end,s[start:end]
library/stdtypes,,::,>>> hash(v[::-2]) == hash(b'abcefg'[::-2])
library/stdtypes,,:len,s[len(s):len(s)]
library/stdtypes,,::,>>> y = m[::2]
library/stdtypes,,::,>>> z = y[::-2]
library/subprocess,,`,"output=`dmesg | grep hda`"
library/subprocess,,`,"output=`mycmd myarg`"
library/tarfile,,:bz2,
library/tarfile,,:compression,filemode[:compression]
library/tarfile,,:gz,
library/tarfile,,:xz,'a:xz'
library/tarfile,,:xz,'r:xz'
library/tarfile,,:xz,'w:xz'
library/time,,:mm,
library/time,,:ss,
library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):"
library/turtle,,::,Example::
library/unittest,,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message',"
library/unittest,,:first,"self.assertEqual(cm.output, ['INFO:foo:first message',"
library/unittest,,:foo,'ERROR:foo.bar:second message'])
library/unittest,,:second,'ERROR:foo.bar:second message'])
library/urllib.request,,:close,Connection:close
library/urllib.request,,:port,:port
library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n"
library/urllib.request,,:password,"""joe:password@python.org"""
library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678
library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the"
library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the"
library/venv,,:param,":param nopip: If True, pip is not installed into the created"
library/venv,,:param,:param context: The information for the virtual environment
library/xmlrpc.client,,:pass,http://user:pass@host:port/path
library/xmlrpc.client,,:pass,user:pass
library/xmlrpc.client,,:port,http://user:pass@host:port/path
license,,`,"``Software''), to deal in the Software without restriction, including"
license,,`,"THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,"
license,,`,* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
license,,`,THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
license,,`,* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
license,,`,THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
license,,:zooko,mailto:zooko@zooko.com
reference/expressions,,:index,x[index:index]
reference/lexical_analysis,,`,$       ?       `
reference/lexical_analysis,,:fileencoding,# vim:fileencoding=<encoding-name>
tutorial/datastructures,,:value,It is also possible to delete a key:value
tutorial/datastructures,,:value,key:value pairs within the braces adds initial key:value pairs
tutorial/stdlib2,,:config,"logging.warning('Warning:config file %s not found', 'server.conf')"
tutorial/stdlib2,,:config,WARNING:root:Warning:config file server.conf not found
tutorial/stdlib2,,:Critical,CRITICAL:root:Critical error -- shutting down
tutorial/stdlib2,,:Error,ERROR:root:Error occurred
tutorial/stdlib2,,:root,CRITICAL:root:Critical error -- shutting down
tutorial/stdlib2,,:root,ERROR:root:Error occurred
tutorial/stdlib2,,:root,WARNING:root:Warning:config file server.conf not found
tutorial/stdlib2,,:start,extra = data[start:start+extra_size]
tutorial/stdlib2,,:start,"fields = struct.unpack('<IIIHH', data[start:start+16])"
tutorial/stdlib2,,:start,filename = data[start:start+filenamesize]
tutorial/stdlib2,,:Warning,WARNING:root:Warning:config file server.conf not found
using/cmdline,,:category,action:message:category:module:line
using/cmdline,,:errorhandler,:errorhandler
using/cmdline,,:line,action:message:category:module:line
using/cmdline,,:line,file:line: category: message
using/cmdline,,:message,action:message:category:module:line
using/cmdline,,:module,action:message:category:module:line
using/unix,,:Packaging,https://en.opensuse.org/Portal:Packaging
whatsnew/2.0,,:len,
whatsnew/2.3,,::,
whatsnew/2.3,,:config,
whatsnew/2.3,,:Critical,
whatsnew/2.3,,:Error,
whatsnew/2.3,,:Problem,
whatsnew/2.3,,:root,
whatsnew/2.3,,:Warning,
whatsnew/2.4,,::,
whatsnew/2.4,,:System,
whatsnew/2.5,,:memory,:memory:
whatsnew/2.5,,:step,[start:stop:step]
whatsnew/2.5,,:stop,[start:stop:step]
whatsnew/2.7,,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',"
whatsnew/2.7,,::,>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
whatsnew/2.7,,:Sunday,'2009:4:Sunday'
whatsnew/2.7,,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0"
whatsnew/2.7,,::,"export PYTHONWARNINGS=all,error:::Cookie:0"
whatsnew/3.2,,:affe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',"
whatsnew/3.2,,:affe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
whatsnew/3.2,,:beef,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',"
whatsnew/3.2,,:beef,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
whatsnew/3.2,,:cafe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',"
whatsnew/3.2,,:cafe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
whatsnew/3.2,,:deaf,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',"
whatsnew/3.2,,:deaf,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
whatsnew/3.2,,:directory,${buildout:directory}/downloads/dist
whatsnew/3.2,,::,"$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'"
whatsnew/3.2,,:feed,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',"
whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:"
whatsnew/3.2,,:location,zope9-location = ${zope9:location}
whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf
library/tarfile,,:xz,'x:xz'
library/xml.etree.elementtree,,:sometag,prefix:sometag
library/xml.etree.elementtree,,:fictional,"<actors xmlns:fictional=""http://characters.example.com"""
library/xml.etree.elementtree,,:character,<fictional:character>Lancelot</fictional:character>
library/xml.etree.elementtree,,:character,<fictional:character>Archie Leach</fictional:character>
library/xml.etree.elementtree,,:character,<fictional:character>Sir Robin</fictional:character>
library/xml.etree.elementtree,,:character,<fictional:character>Gunther</fictional:character>
library/xml.etree.elementtree,,:character,<fictional:character>Commander Clement</fictional:character>
library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:actor', ns):"
library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)"
library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):"
library/zipapp,,:main,"$ python -m zipapp myapp -m ""myapp:main"""
library/zipapp,,:fn,"argument should have the form ""pkg.mod:fn"", where ""pkg.mod"" is a"
library/zipapp,,:callable,"""pkg.module:callable"" and the archive will be run by importing"
library/stdtypes,,::,>>> m[::2].tolist()
library/sys,,`,# ``wrapper`` creates a ``wrap(coro)`` coroutine:
whatsnew/3.5,,:root,'WARNING:root:warning\n'
whatsnew/3.5,,:warning,'WARNING:root:warning\n'
whatsnew/3.5,,::,>>> addr6 = ipaddress.IPv6Address('::1')
whatsnew/3.5,,:root,ERROR:root:exception
whatsnew/3.5,,:exception,ERROR:root:exception
whatsnew/changelog,,:version,import sys; I = version[:version.index(' ')]
whatsnew/changelog,,:gz,": TarFile opened with external fileobj and ""w:gz"" mode didn't"
whatsnew/changelog,,::,": Use ""127.0.0.1"" or ""::1"" instead of ""localhost"" as much as"