From 62ec61fb6ad5f1745597017297a455d63a2f97e4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 7 Jun 2011 12:17:15 +0200 Subject: test.support: can_symlink() removes the temporary symbolic link --- Lib/test/support.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/support.py b/Lib/test/support.py index 2aedf24..b19c698 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1487,11 +1487,14 @@ def can_symlink(): global _can_symlink if _can_symlink is not None: return _can_symlink + symlink_path = TESTFN + "can_symlink" try: - os.symlink(TESTFN, TESTFN + "can_symlink") + os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError): can = False + else: + os.remove(symlink_path) _can_symlink = can return can -- cgit v0.12 From 41c1910bb3229874a02c19ecd9189715b3ce501b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 7 Jun 2011 15:19:44 +0200 Subject: #12274: use proper escaping for % in IDLE config. --- Lib/idlelib/config-main.def | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index 5ddd098..9546e2b 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -46,8 +46,8 @@ [General] editor-on-startup= 0 autosave= 0 -print-command-posix=lpr %s -print-command-win=start /min notepad /p %s +print-command-posix=lpr %%s +print-command-win=start /min notepad /p %%s delete-exitfunc= 1 [EditorWindow] -- cgit v0.12 From b8f2ad03805048f43723019aecbcf181fbf01549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 8 Jun 2011 00:47:49 +0200 Subject: Remove outdated bit of advice (584f9c213a6d follow-up) --- Doc/documenting/markup.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst index 57d9eeb..c005d0c 100644 --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ following example shows all of the features of this directive type:: Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: -- cgit v0.12 From b805c47138d23c2d6cbaffde81a4b7d9afe44e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 8 Jun 2011 01:11:36 +0200 Subject: Add examples that work on Windows to distutils docs (#1626300) --- Doc/distutils/introduction.rst | 10 ++++++++-- Doc/install/index.rst | 15 +++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst index 8dc604d..57d34a4 100644 --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ Some observations: for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 31c1d7f..f8d6305 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ in the name of the downloaded archive, e.g. :file:`foo-1.0.tar.gz` or directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ Standard Build and Install ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: -- cgit v0.12 From 96deb7550effe961b2847a340ff05b1ab899d379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 8 Jun 2011 04:53:20 +0200 Subject: Add links from builtins module docs to built-in functions and constants docs --- Doc/library/builtins.rst | 4 +++- Doc/library/constants.rst | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst index c495728..d4199d2 100644 --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,7 +7,9 @@ This module provides direct access to all 'built-in' identifiers of Python; for example, ``builtins.open`` is the full name for the built-in function -:func:`open`. +:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for +documentation. + This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 51a1c26..fa61f68 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -1,3 +1,5 @@ +.. _built-in-consts: + Built-in Constants ================== -- cgit v0.12 From d2f8cec88558993e10c1dae103a5bae6549e25ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 8 Jun 2011 05:29:39 +0200 Subject: Fix a few misuses of :option: I missed in r86521. Extract of the commit message: Fix usage of :option: in the docs (#9312). :option: is used to create a link to an option of python, not to mark up any instance of any arbitrary command-line option. These were changed to ````. --- Doc/c-api/intro.rst | 4 ++-- Doc/license.rst | 4 ++-- Doc/using/cmdline.rst | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 83b98f9..843707d 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -588,8 +588,8 @@ frequently-used builds will be described in the remainder of this section. Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/license.rst b/Doc/license.rst index a32b7ab..b471828 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -845,7 +845,7 @@ expat ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -874,7 +874,7 @@ libffi ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d1f47eb..16a753c 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -501,7 +501,7 @@ Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG -- cgit v0.12 From 9c669ccc77c85eac245d460bab510a38b20d9a08 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 8 Jun 2011 18:17:18 -0500 Subject: Fix #11583. Changed os.path.isdir to use GetFileAttributes instead of os.stat. By changing to the Windows GetFileAttributes API in nt._isdir we can figure out if the path is a directory without opening the file via os.stat. This has the minor benefit of speeding up os.path.isdir by at least 2x for regular files and 10-15x improvements were seen on symbolic links (which opened the file multiple times during os.stat). Since os.path.isdir is used in several places on interpreter startup, we get a minor speedup in startup time. --- Lib/ntpath.py | 13 +++++++++++++ Misc/NEWS | 3 +++ Modules/posixmodule.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index ec8a7ab..2483ced 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -672,3 +672,16 @@ except ImportError: def sameopenfile(f1, f2): """Test whether two file objects reference the same file""" return _getfileinformation(f1) == _getfileinformation(f2) + + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir +except ImportError: + from genericpath import isdir as _isdir + +def isdir(path): + return _isdir(path) diff --git a/Misc/NEWS b/Misc/NEWS index 16a0f29..15ed46f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Core and Builtins Library ------- +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Named tuples now work correctly with vars(). - Issue #12085: Fix an attribute error in subprocess.Popen destructor if the diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 89d3f2f..767ed61 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2819,6 +2819,42 @@ posix__getfileinformation(PyObject *self, PyObject *args) info.nFileIndexHigh, info.nFileIndexLow); } + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "O&:_isdir", + PyUnicode_FSConverter, &opath)) + return NULL; + + path = PyBytes_AsString(opath); + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ PyDoc_STRVAR(posix_mkdir__doc__, @@ -8055,6 +8091,7 @@ static PyMethodDef posix_methods[] = { {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, NULL}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- cgit v0.12 From 95d028fd18fc33ceac8b2727a1e9fe3d4a8256b8 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Thu, 9 Jun 2011 09:10:38 -0500 Subject: Correction to 88e318166eaf - Issue #11583 Rather than wrapping the C _isdir function in a Python function, just import the C _isdir function directly. Additionally, add in the docstring which was left out. --- Lib/ntpath.py | 8 +++----- Modules/posixmodule.c | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 2483ced..826be87 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -679,9 +679,7 @@ try: # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. - from nt import _isdir + from nt import _isdir as isdir except ImportError: - from genericpath import isdir as _isdir - -def isdir(path): - return _isdir(path) + # Use genericpath.isdir as imported above. + pass diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 767ed61..eb2e412 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2820,6 +2820,9 @@ posix__getfileinformation(PyObject *self, PyObject *args) info.nFileIndexLow); } +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -8091,7 +8094,7 @@ static PyMethodDef posix_methods[] = { {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, - {"_isdir", posix__isdir, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- cgit v0.12 From 8168d10ea683d939ae52a1ed3d7c697c92bfae3d Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Thu, 9 Jun 2011 16:50:49 +0100 Subject: Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. --- Lib/logging/handlers.py | 6 +++++- Misc/NEWS | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 306cf86..4a6b959 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -766,6 +766,8 @@ class SysLogHandler(logging.Handler): """ return self.priority_map.get(levelName, "warning") + append_nul = True # some old syslog daemons expect a NUL terminator + def emit(self, record): """ Emit a record. @@ -773,7 +775,9 @@ class SysLogHandler(logging.Handler): The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) + '\000' + msg = self.format(record) + if self.append_nul: + msg += '\000' """ We need to convert record level to lowercase, maybe this will change in the future. diff --git a/Misc/NEWS b/Misc/NEWS index 15ed46f..c5d2cec 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Core and Builtins Library ------- +- Issue #12168: SysLogHandler now allows NUL termination to be controlled using + a new 'append_nul' attribute on the handler. + - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes instead of os.stat. -- cgit v0.12 From 0f663d07e669c39ce9a7ddfa71ed1293379a358e Mon Sep 17 00:00:00 2001 From: R David Murray Date: Thu, 9 Jun 2011 15:05:57 -0400 Subject: #12283: Fixed regression in smtplib quoting of leading dots in DATA. I unfortunately introduced the regression when I refactored the code, and there were no tests of quoting so it wasn't caught. Now there is one. --- Lib/smtplib.py | 2 +- Lib/test/test_smtplib.py | 15 +++++++++++++++ Misc/NEWS | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py index dbccf48..ce71699 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -162,7 +162,7 @@ def quotedata(data): re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) def _quote_periods(bindata): - return re.sub(br'(?m)^\.', '..', bindata) + return re.sub(br'(?m)^\.', b'..', bindata) def _fix_eols(data): return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 884529f..dd92044 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -278,6 +278,21 @@ class DebuggingServerTests(unittest.TestCase): mexpect = '%s%s\n%s' % (MSG_BEGIN, m.decode('ascii'), MSG_END) self.assertEqual(self.output.getvalue(), mexpect) + def testSendNeedingDotQuote(self): + # Issue 12283 + m = '.A test\n.mes.sage.' + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) + smtp.sendmail('John', 'Sally', m) + # XXX (see comment in testSend) + time.sleep(0.01) + smtp.quit() + + self.client_evt.set() + self.serv_evt.wait() + self.output.flush() + mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END) + self.assertEqual(self.output.getvalue(), mexpect) + def testSendMessage(self): m = email.mime.text.MIMEText('A test message') smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) diff --git a/Misc/NEWS b/Misc/NEWS index c5d2cec..dab5355 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,8 @@ Core and Builtins Library ------- +- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. + - Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. -- cgit v0.12 From 4fbb9dbd3421fca6d4c289d996ef035da0cef330 Mon Sep 17 00:00:00 2001 From: R David Murray Date: Thu, 9 Jun 2011 15:50:51 -0400 Subject: #10694: zipfile now ignores garbage at the end of a zipfile. Original fix by 'rep', final patch (with tests) by Xuanji Li. --- Lib/test/test_zipfile.py | 18 ++++++++++++++++++ Lib/zipfile.py | 18 ++++++++---------- Misc/NEWS | 2 ++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 90aab86..782020c 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -351,6 +351,24 @@ class TestsWithSourceFile(unittest.TestCase): with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 50f4848..5cc7816 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -246,16 +246,14 @@ def _EndRecData(fpin): # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) - - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) + + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/NEWS b/Misc/NEWS index dab5355..2d00324 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,8 @@ Core and Builtins Library ------- +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. - Issue #12168: SysLogHandler now allows NUL termination to be controlled using -- cgit v0.12 From e6eafa2ade22dc687eee78374fa93d4b9ab7a2c1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 10 Jun 2011 16:32:54 +0200 Subject: Issue #10801: Fix test_unicode_filenames() of test_zipfile Just try to open files from the ZIP for reading, don't extract them to avoid UnicodeEncodeError if the filename is not encodable to the filesystem encoding (e.g. ASCII locale encoding). --- Lib/test/test_zipfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index a36b010..ee7524e 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -405,7 +405,8 @@ class TestsWithSourceFile(unittest.TestCase): zipfp = zipfile.ZipFile(fname) try: - zipfp.extractall() + for name in zipfp.namelist(): + zipfp.open(name).close() finally: zipfp.close() -- cgit v0.12 From 1df0f214a9fdb4dde7506576b144cf6a7fd01b65 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 10 Jun 2011 11:32:52 -0500 Subject: fix regression in netrc comment handling (closes #12009) --- Lib/netrc.py | 12 +++-- Lib/test/test_netrc.py | 131 ++++++++++++++++++++++++++++++++++--------------- Misc/ACKS | 1 + Misc/NEWS | 5 ++ 4 files changed, 105 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py index a60b8b7..c96db6f 100644 --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex +import io, os, shlex __all__ = ["netrc", "NetrcParseError"] @@ -37,12 +37,14 @@ class netrc: lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword + saved_lineno = lexer.lineno toplevel = tt = lexer.get_token() if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + if lexer.lineno == saved_lineno and len(tt) == 1: + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +70,8 @@ class netrc: self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py index da7ec05..ef70e37 100644 --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp(self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 + + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) def test_main(): support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS index c698d73..e74324f 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -564,6 +564,7 @@ Paul Moore Derek Morr James A Morrison Mher Movsisyan +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS index ed70507..6cf2867 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7,6 +7,11 @@ What's New in Python 3.1.4? *Release date: 2011-05-XX* +Library +------- + +- Issue #12009: Fixed regression in netrc file comment handling. + Extension Modules ----------------- -- cgit v0.12 From 645e4589b1df21594fe6b10c16615a091e52c344 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Fri, 10 Jun 2011 18:52:50 +0100 Subject: Documented change for Issue #12168. --- Doc/library/logging.handlers.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index eda9302..378c071 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -436,6 +436,21 @@ supports sending logging messages to a remote or local Unix syslog. The record is formatted, and then sent to the syslog server. If exception information is present, it is *not* sent to the server. + .. versionchanged:: 3.2.1 + (See: :issue:`12168`.) In earlier versions, the message sent to the + syslog daemons was always terminated with a NUL byte, because early + versions of these daemons expected a NUL terminated message - even + though it's not in the relevant specification (RF 5424). More recent + versions of these daemons don't expect the NUL byte but strip it off + if it's there, and even more recent daemons (which adhere more closely + to RFC 5424) pass the NUL byte on as part of the message. + + To enable easier handling of syslog messages in the face of all these + differing daemon behaviours, the appending of the NUL byte has been + made configurable, through the use of a class-level attribute, + ``append_nul``. This defaults to ``True`` (preserving the existing + behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance + in order for that instance to *not* append the NUL terminator. .. method:: encodePriority(facility, priority) -- cgit v0.12 From d858df20d0d82eeefbdbe9982cfd68207a0cd446 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Jun 2011 09:58:58 -0500 Subject: bump to 3.1.4 --- Include/patchlevel.h | 6 +++--- Lib/distutils/__init__.py | 2 +- Lib/idlelib/idlever.py | 2 +- Misc/NEWS | 2 +- Misc/RPM/python-3.1.spec | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index db58c5f..3b06447 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 4 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.1.4rc1" +#define PY_VERSION "3.1.4" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py index 5f8425f..a3e2993 100644 --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -15,5 +15,5 @@ __revision__ = "$Id$" # Updated automatically by the Python release process. # #--start constants-- -__version__ = "3.1.4rc1" +__version__ = "3.1.4" #--end constants-- diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py index fa89048..09f1b72 100644 --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1 +1 @@ -IDLE_VERSION = "3.1.4rc1" +IDLE_VERSION = "3.1.4" diff --git a/Misc/NEWS b/Misc/NEWS index 6cf2867..eab5cc9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -5,7 +5,7 @@ Python News What's New in Python 3.1.4? =========================== -*Release date: 2011-05-XX* +*Release date: 2011-06-11* Library ------- diff --git a/Misc/RPM/python-3.1.spec b/Misc/RPM/python-3.1.spec index d3c9bf2..4215cbb 100644 --- a/Misc/RPM/python-3.1.spec +++ b/Misc/RPM/python-3.1.spec @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 3.1.4rc1 +%define version 3.1.4 %define libvers 3.1 #--end constants-- %define release 1pydotorg -- cgit v0.12 From f2ff3054f979370c3cb577eae2f3aa1e935cd15f Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Jun 2011 09:59:17 -0500 Subject: Added tag v3.1.4 for changeset c918ec9f3a76 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 680baaf..8dd9975 100644 --- a/.hgtags +++ b/.hgtags @@ -76,3 +76,4 @@ a69a031ac1402dede8b1ef80096436bca6d371f3 v3.1 d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1 a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3 32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1 +c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4 -- cgit v0.12 From acde6a0a40bc749aed4bb5f30560d1c5a9e2be3c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Jun 2011 11:33:01 -0500 Subject: onto 3.1.5 --- Include/patchlevel.h | 2 +- Misc/NEWS | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 3b06447..d9652a5 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.1.4" +#define PY_VERSION "3.1.4+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Misc/NEWS b/Misc/NEWS index eab5cc9..e68a4e3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,18 @@ Python News +++++++++++ +What's New in Python 3.1.5? +=========================== + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 3.1.4? =========================== -- cgit v0.12 From 9fbfe15c86a079f03f54b20106cdefa402325330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 11 Jun 2011 10:34:19 +0200 Subject: Add missing reST target to one heading in the tutorial --- Doc/tutorial/interpreter.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 8d743de..29afc50 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -169,6 +169,8 @@ also be ``.pyw``, in that case, the console window that normally appears is suppressed. +.. _tut-source-encoding: + Source Code Encoding -------------------- -- cgit v0.12 From 9620cc04634e720d1d016cce4bf02e0c27607e64 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Jun 2011 15:53:11 -0500 Subject: allow "fake" filenames in findsource (closes #9284) This allows findsource() to work in doctests. A patch from Dirkjan Ochtman. --- Lib/inspect.py | 8 ++++++-- Lib/test/test_inspect.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 4899cbf..bb46ea6 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -518,9 +518,13 @@ def findsource(object): or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) - if not file: + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index f5dff1e..7666fe4 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -298,6 +298,23 @@ class TestRetrievingSourceCode(GetSourceBase): del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec(compile(source, fn, 'single'), ns) + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderModule = mod2 diff --git a/Misc/NEWS b/Misc/NEWS index d3496b0..de1c531 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Core and Builtins Library ------- +- Issue #9284: Allow inspect.findsource() to find the source of doctest + functions. + - Issue #12009: Fixed regression in netrc file comment handling. - Issue #10694: zipfile now ignores garbage at the end of a zipfile. -- cgit v0.12 From 0aaa9e1d7b16e92c0cbe9e40c037c38ba0427840 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Sat, 11 Jun 2011 23:03:37 +0100 Subject: Issue #12206: documentation for LogRecord constructor updated re. the level argument. --- Doc/library/logging.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 32f762d..76633db 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -544,6 +544,9 @@ wire). :param name: The name of the logger used to log the event represented by this LogRecord. :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) + Note that this is converted to *two* attributes of the LogRecord: + ``levelno`` for the numeric value and ``levelname`` for the + corresponding level name. :param pathname: The full pathname of the source file where the logging call was made. :param lineno: The line number in the source file where the logging call was -- cgit v0.12 From cdc751720ee7a13ac163da1eedf3a513386c98d4 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Sun, 12 Jun 2011 11:44:28 +0100 Subject: Updated Formatter.formatTime documentation. --- Doc/library/logging.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 76633db..20cd57c 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -453,6 +453,13 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on record. Otherwise, the ISO8601 format is used. The resulting string is returned. + This function uses a user-configurable function to convert the creation + time to a tuple. By default, :func:`time.localtime` is used; to change + this for a particular formatter instance, set the ``converter`` attribute + to a function with the same signature as :func:`time.localtime` or + :func:`time.gmtime`. To change it for all formatters, for example if you + want all logging times to be shown in GMT, set the ``converter`` + attribute in the ``Formatter`` class. .. method:: formatException(exc_info) -- cgit v0.12