diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 4ae18fac608..7244e7ba996 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -49,6 +49,8 @@ The module defines the following functions: This function is identical to the :func:`fcntl` function, except that the argument handling is even more complicated. + The op parameter is limited to values that can fit in 32-bits. + The parameter *arg* can be one of an integer, absent (treated identically to the integer ``0``), an object supporting the read-only buffer interface (most likely a plain Python string) or an object supporting the read-write buffer interface. diff --git a/Doc/library/urllib2.rst b/Doc/library/urllib2.rst index d77712ff735..d6a5fbd2432 100644 --- a/Doc/library/urllib2.rst +++ b/Doc/library/urllib2.rst @@ -179,6 +179,7 @@ The following classes are provided: Cause requests to go through a proxy. If *proxies* is given, it must be a dictionary mapping protocol names to URLs of proxies. The default is to read the list of proxies from the environment variables :envvar:`_proxy`. + To disable autodetected proxy pass an empty dictionary. .. class:: HTTPPasswordMgr() diff --git a/Lib/bsddb/test/test_1413192.py b/Lib/bsddb/test/test_1413192.py index 1d4bd5624b1..3a663e6e034 100644 --- a/Lib/bsddb/test/test_1413192.py +++ b/Lib/bsddb/test/test_1413192.py @@ -5,7 +5,9 @@ import shutil import tempfile +from test.test_support import catch_warning import warnings + try: # For Pythons w/distutils and add-on pybsddb from bsddb3 import db @@ -33,12 +35,11 @@ def __init__(self): del self.the_txn -warnings.filterwarnings('ignore', 'DBTxn aborted in destructor') -try: +with catch_warning(): + warnings.filterwarnings('ignore', 'DBTxn aborted in destructor') context = Context() del context -finally: - warnings.resetwarnings() + # try not to leave a turd try: diff --git a/Lib/gzip.py b/Lib/gzip.py index 917c3f5279f..aa8386e5fe8 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -321,7 +321,8 @@ def _read_eof(self): crc32 = read32(self.fileobj) isize = U32(read32(self.fileobj)) # may exceed 2GB if U32(crc32) != U32(self.crc): - raise IOError("CRC check failed") + raise IOError("CRC check failed %s != %s" % (hex(U32(crc32)), + hex(U32(self.crc)))) elif isize != LOWU32(self.size): raise IOError("Incorrect length of data produced") diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 9a83559f877..63732c844f5 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -174,6 +174,7 @@ def readline(self): chr = None while chr != b"\n": chr = self.sslobj.read(1) + if not chr: break str += chr return str diff --git a/Lib/stat.py b/Lib/stat.py index c054fb8e0a9..d29c63c1f7c 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -3,12 +3,7 @@ Suggested usage: from stat import * """ -# XXX Strictly spoken, this module may have to be adapted for each POSIX -# implementation; in practice, however, the numeric constants used by -# stat() are almost universal (even for stat() emulations on non-UNIX -# systems like MS-DOS). - -# Indices for stat struct members in tuple returned by os.stat() +# Indices for stat struct members in the tuple returned by os.stat() ST_MODE = 0 ST_INO = 1 diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 665f5b3bc1d..136961237a5 100755 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -3,14 +3,14 @@ OS/2+EMX doesn't support the file locking operations. """ -import struct import fcntl -import os, sys +import os +import struct +import sys import unittest from test.test_support import verbose, TESTFN, unlink, run_unittest -# TODO - Write tests for ioctl(), flock() and lockf(). - +# TODO - Write tests for flock() and lockf(). def get_lockdata(): if sys.platform.startswith('atheos'): diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py index d8c03db4af2..537f29854a9 100644 --- a/Lib/test/test_hmac.py +++ b/Lib/test/test_hmac.py @@ -211,8 +211,8 @@ def update(self, v): def digest(self): return self._x.digest() - warnings.simplefilter('error', RuntimeWarning) - try: + with test_support.catch_warning(): + warnings.simplefilter('error', RuntimeWarning) try: hmac.HMAC(b'a', b'b', digestmod=MockCrazyHash) except RuntimeWarning: @@ -227,8 +227,6 @@ def digest(self): pass else: self.fail('Expected warning about small block_size') - finally: - warnings.resetwarnings() diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py index 2b127e2b4a9..feea5bf4f69 100644 --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -14,6 +14,11 @@ except IOError: raise TestSkipped("Unable to open /dev/tty") +try: + import pty +except ImportError: + pty = None + class IoctlTests(unittest.TestCase): def test_ioctl(self): # If this process has been put into the background, TIOCGPGRP returns @@ -34,6 +39,30 @@ def test_ioctl_mutate(self): self.assertEquals(r, 0) self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids)) + def test_ioctl_signed_unsigned_code_param(self): + if not pty: + raise TestSkipped('pty module required') + mfd, sfd = pty.openpty() + try: + if termios.TIOCSWINSZ < 0: + set_winsz_opcode_maybe_neg = termios.TIOCSWINSZ + set_winsz_opcode_pos = termios.TIOCSWINSZ & 0xffffffff + else: + set_winsz_opcode_pos = termios.TIOCSWINSZ + set_winsz_opcode_maybe_neg, = struct.unpack("i", + struct.pack("I", termios.TIOCSWINSZ)) + + # We're just testing that these calls do not raise exceptions. + saved_winsz = fcntl.ioctl(mfd, termios.TIOCGWINSZ, "\0"*8) + our_winsz = struct.pack("HHHH",80,25,0,0) + # test both with a positive and potentially negative ioctl code + new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_pos, our_winsz) + new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_maybe_neg, our_winsz) + fcntl.ioctl(mfd, set_winsz_opcode_maybe_neg, saved_winsz) + finally: + os.close(mfd) + os.close(sfd) + def test_main(): run_unittest(IoctlTests) diff --git a/Lib/test/test_unicode_file.py b/Lib/test/test_unicode_file.py index ede1b17bc46..5f0681e4797 100644 --- a/Lib/test/test_unicode_file.py +++ b/Lib/test/test_unicode_file.py @@ -49,6 +49,22 @@ def _do_single(self, filename): self.failUnless(base in file_list) + # Do as many "equivalancy' tests as we can - ie, check that although we + # have different types for the filename, they refer to the same file. + def _do_equivalent(self, filename1, filename2): + # Note we only check "filename1 against filename2" - we don't bother + # checking "filename2 against 1", as we assume we are called again with + # the args reversed. + self.failUnless(type(filename1)!=type(filename2), + "No point checking equivalent filenames of the same type") + # stat and lstat should return the same results. + self.failUnlessEqual(os.stat(filename1), + os.stat(filename2)) + self.failUnlessEqual(os.lstat(filename1), + os.lstat(filename2)) + # Copy/rename etc tests using equivalent filename + self._do_copyish(filename1, filename2) + # Tests that copy, move, etc one file to another. def _do_copyish(self, filename1, filename2): # Should be able to rename the file using either name. @@ -58,31 +74,20 @@ def _do_copyish(self, filename1, filename2): os.rename(filename1 + ".new", filename2) self.failUnless(os.path.isfile(filename2)) - # Try using shutil on the filenames. - try: - filename1==filename2 - except UnicodeDecodeError: - # these filenames can't be compared - shutil.copy tries to do - # just that. This is really a bug in 'shutil' - if one of shutil's - # 2 params are Unicode and the other isn't, it should coerce the - # string to Unicode with the filesystem encoding before comparison. - pass - else: - # filenames can be compared. - shutil.copy(filename1, filename2 + ".new") - os.unlink(filename1 + ".new") # remove using equiv name. - # And a couple of moves, one using each name. - shutil.move(filename1, filename2 + ".new") - self.failUnless(not os.path.exists(filename2)) - shutil.move(filename1 + ".new", filename2) - self.failUnless(os.path.exists(filename1)) - # Note - due to the implementation of shutil.move, - # it tries a rename first. This only fails on Windows when on - # different file systems - and this test can't ensure that. - # So we test the shutil.copy2 function, which is the thing most - # likely to fail. - shutil.copy2(filename1, filename2 + ".new") - os.unlink(filename1 + ".new") + shutil.copy(filename1, filename2 + ".new") + os.unlink(filename1 + ".new") # remove using equiv name. + # And a couple of moves, one using each name. + shutil.move(filename1, filename2 + ".new") + self.failUnless(not os.path.exists(filename2)) + shutil.move(filename1 + ".new", filename2) + self.failUnless(os.path.exists(filename1)) + # Note - due to the implementation of shutil.move, + # it tries a rename first. This only fails on Windows when on + # different file systems - and this test can't ensure that. + # So we test the shutil.copy2 function, which is the thing most + # likely to fail. + shutil.copy2(filename1, filename2 + ".new") + os.unlink(filename1 + ".new") def _do_directory(self, make_name, chdir_name, encoded): cwd = os.getcwd() @@ -127,6 +132,16 @@ def _test_single(self, filename): finally: os.unlink(filename) + def _test_equivalent(self, filename1, filename2): + remove_if_exists(filename1) + self.failUnless(not os.path.exists(filename2)) + f = file(filename1, "w") + f.close() + try: + self._do_equivalent(filename1, filename2) + finally: + os.unlink(filename1) + # The 'test' functions are unittest entry points, and simply call our # _test functions with each of the filename combinations we wish to test def test_single_files(self): @@ -135,6 +150,9 @@ def test_single_files(self): self._test_single(TESTFN_UNICODE_UNENCODEABLE) def test_directories(self): + # For all 'equivalent' combinations: + # Make dir with encoded, chdir with unicode, checkdir with encoded + # (or unicode/encoded/unicode, etc ext = ".dir" self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext, False) # Our directory name that can't use a non-unicode name. diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 1539f21ff8b..6447e5686ba 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -97,11 +97,20 @@ fcntl_ioctl(PyObject *self, PyObject *args) { #define IOCTL_BUFSZ 1024 int fd; - /* In PyArg_ParseTuple below, use the unsigned int 'I' format for - the signed int 'code' variable, because Python turns 0x8000000 - into a large positive number (PyLong, or PyInt on 64-bit - platforms,) whereas C expects it to be a negative int */ - int code; + /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I' + format for the 'code' parameter because Python turns 0x8000000 + into either a large positive number (PyLong or PyInt on 64-bit + platforms) or a negative number on others (32-bit PyInt) + whereas the system expects it to be a 32bit bit field value + regardless of it being passed as an int or unsigned long on + various platforms. See the termios.TIOCSWINSZ constant across + platforms for an example of thise. + + If any of the 64bit platforms ever decide to use more than 32bits + in their unsigned long ioctl codes this will break and need + special casing based on the platform being built on. + */ + unsigned int code; int arg; int ret; char *str; diff --git a/Objects/abstract.c b/Objects/abstract.c index dd05fe116dd..dac80d92fa0 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2598,22 +2598,20 @@ int PyObject_IsInstance(PyObject *inst, PyObject *cls) { static PyObject *name = NULL; - PyObject *t, *v, *tb; PyObject *checker; /* Quick test for an exact match */ if (Py_TYPE(inst) == (PyTypeObject *)cls) return 1; - PyErr_Fetch(&t, &v, &tb); - if (name == NULL) { name = PyUnicode_InternFromString("__instancecheck__"); if (name == NULL) return -1; } checker = PyObject_GetAttr(cls, name); - PyErr_Restore(t, v, tb); + if (checker == NULL && PyErr_Occurred()) + PyErr_Clear(); if (checker != NULL) { PyObject *res; int ok = -1;