summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/distutils/introduction.rst2
-rw-r--r--Doc/documenting/style.rst104
-rw-r--r--Doc/library/configparser.rst4
-rw-r--r--Doc/library/functions.rst13
-rw-r--r--Doc/library/modulefinder.rst3
-rw-r--r--Doc/library/socket.rst4
-rw-r--r--Doc/library/ssl.rst3
-rw-r--r--Doc/library/stdtypes.rst9
-rw-r--r--Doc/library/subprocess.rst4
-rw-r--r--Doc/library/wsgiref.rst12
-rw-r--r--Doc/library/xml.dom.minidom.rst8
-rw-r--r--Doc/library/xml.dom.rst7
-rw-r--r--Lib/compileall.py10
-rw-r--r--Lib/distutils/command/build_scripts.py45
-rw-r--r--Lib/idlelib/IOBinding.py44
-rw-r--r--Lib/idlelib/NEWS.txt13
-rw-r--r--Lib/idlelib/ScriptBinding.py16
-rw-r--r--Lib/modulefinder.py7
-rw-r--r--Lib/ssl.py25
-rw-r--r--Lib/subprocess.py4
-rw-r--r--Lib/test/json_tests/test_recursion.py21
-rw-r--r--Lib/test/support.py17
-rw-r--r--Lib/test/test_compileall.py2
-rw-r--r--Lib/test/test_heapq.py68
-rw-r--r--Lib/test/test_io.py26
-rw-r--r--Lib/test/test_minidom.py20
-rw-r--r--Lib/test/test_sax.py45
-rw-r--r--Lib/test/test_socket.py25
-rw-r--r--Lib/test/test_ssl.py56
-rw-r--r--Lib/test/test_subprocess.py3
-rw-r--r--Lib/xml/__init__.py21
-rw-r--r--Makefile.pre.in3
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS38
-rw-r--r--Modules/_io/bufferedio.c2
-rw-r--r--Modules/_json.c17
-rw-r--r--Modules/_ssl.c8
-rw-r--r--Modules/_tkinter.c14
-rw-r--r--Modules/socketmodule.c11
-rw-r--r--Parser/myreadline.c1
-rwxr-xr-xconfigure125
-rw-r--r--configure.in12
42 files changed, 560 insertions, 313 deletions
diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst
index b772b01..8dc604d 100644
--- a/Doc/distutils/introduction.rst
+++ b/Doc/distutils/introduction.rst
@@ -187,7 +187,7 @@ modules using the Distutils:
module distribution
a collection of Python modules distributed together as a single downloadable
resource and meant to be installed *en masse*. Examples of some well-known
- module distributions are Numeric Python, PyXML, PIL (the Python Imaging
+ module distributions are NumPy, SciPy, PIL (the Python Imaging
Library), or mxBase. (This would be called a *package*, except that term is
already taken in the Python context: a single module distribution may contain
zero, one, or many Python packages.)
diff --git a/Doc/documenting/style.rst b/Doc/documenting/style.rst
index d055711..ade845c 100644
--- a/Doc/documenting/style.rst
+++ b/Doc/documenting/style.rst
@@ -108,6 +108,110 @@ Unix
The name of the operating system developed at AT&T Bell Labs in the early
1970s.
+Affirmative Tone
+----------------
+
+The documentation focuses on affirmatively stating what the language does and
+how to use it effectively.
+
+Except for certain security risks or segfault risks, the docs should avoid
+wording along the lines of "feature x is dangerous" or "experts only". These
+kinds of value judgments belong in external blogs and wikis, not in the core
+documentation.
+
+Bad example (creating worry in the mind of a reader):
+
+ Warning: failing to explicitly close a file could result in lost data or
+ excessive resource consumption. Never rely on reference counting to
+ automatically close a file.
+
+Good example (establishing confident knowledge in the effective use of the language):
+
+ A best practice for using files is use a try/finally pair to explicitly
+ close a file after it is used. Alternatively, using a with-statement can
+ achieve the same effect. This assures that files are flushed and file
+ descriptor resources are released in a timely manner.
+
+Economy of Expression
+---------------------
+
+More documentation is not necessarily better documentation. Error on the side
+of being succinct.
+
+It is an unfortunate fact that making documentation longer can be an impediment
+to understanding and can result in even more ways to misread or misinterpret the
+text. Long descriptions full of corner cases and caveats can create the
+impression that a function is more complex or harder to use than it actually is.
+
+The documentation for :func:`super` is an example of where a good deal of
+information was condensed into a few short paragraphs. Discussion of
+:func:`super` could have filled a chapter in a book, but it is often easier to
+grasp a terse description than a lengthy narrative.
+
+
+Code Examples
+-------------
+
+Short code examples can be a useful adjunct to understanding. Readers can often
+grasp a simple example more quickly than they can digest a formal description in
+prose.
+
+People learn faster with concrete, motivating examples that match the context of
+a typical use case. For instance, the :func:`str.rpartition` method is better
+demonstrated with an example splitting the domain from a URL than it would be
+with an example of removing the last word from a line of Monty Python dialog.
+
+The ellipsis for the :attr:`sys.ps2` secondary interpreter prompt should only be
+used sparingly, where it is necessary to clearly differentiate between input
+lines and output lines. Besides contributing visual clutter, it makes it
+difficult for readers to cut-and-paste examples so they can experiment with
+variations.
+
+Code Equivalents
+----------------
+
+Giving pure Python code equivalents (or approximate equivalents) can be a useful
+adjunct to a prose description. A documenter should carefully weigh whether the
+code equivalent adds value.
+
+A good example is the code equivalent for :func:`all`. The short 4-line code
+equivalent is easily digested; it re-emphasizes the early-out behavior; and it
+clarifies the handling of the corner-case where the iterable is empty. In
+addition, it serves as a model for people wanting to implement a commonly
+requested alternative where :func:`all` would return the specific object
+evaluating to False whenever the function terminates early.
+
+A more questionable example is the code for :func:`itertools.groupby`. Its code
+equivalent borders on being too complex to be a quick aid to understanding.
+Despite its complexity, the code equivalent was kept because it serves as a
+model to alternative implementations and because the operation of the "grouper"
+is more easily shown in code than in English prose.
+
+An example of when not to use a code equivalent is for the :func:`oct` function.
+The exact steps in converting a number to octal doesn't add value for a user
+trying to learn what the function does.
+
+Audience
+--------
+
+The tone of the tutorial (and all the docs) needs to be respectful of the
+reader's intelligence. Don't presume that the readers are stupid. Lay out the
+relevant information, show motivating use cases, provide glossary links, and do
+our best to connect-the-dots, but don't talk down to them or waste their time.
+
+The tutorial is meant for newcomers, many of whom will be using the tutorial to
+evaluate the language as a whole. The experience needs to be positive and not
+leave the reader with worries that something bad will happen if they make a
+misstep. The tutorial serves as guide for intelligent and curious readers,
+saving details for the how-to guides and other sources.
+
+Be careful accepting requests for documentation changes from the rare but vocal
+category of reader who is looking for vindication for one of their programming
+errors ("I made a mistake, therefore the docs must be wrong ..."). Typically,
+the documentation wasn't consulted until after the error was made. It is
+unfortunate, but typically no documentation edit would have saved the user from
+making false assumptions about the language ("I was surprised by ...").
+
.. _Apple Publications Style Guide: http://developer.apple.com/mac/library/documentation/UserExperience/Conceptual/APStyleGuide/APSG_2009.pdf
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index 1a88bbd..c84e423 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -1064,6 +1064,10 @@ ConfigParser Objects
given *section*. Optional arguments have the same meaning as for the
:meth:`get` method.
+ .. versionchanged:: 3.2
+ Items present in *vars* no longer appear in the result. The previous
+ behaviour mixed actual parser options with variables provided for
+ interpolation.
.. method:: set(section, option, value)
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 3020128..8b7eef5 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -498,11 +498,14 @@ are always available. They are listed here in alphabetical order.
of the *value* argument, however there is a standard formatting syntax that
is used by most built-in types: :ref:`formatspec`.
- .. note::
-
- ``format(value, format_spec)`` merely calls
- ``value.__format__(format_spec)``.
-
+ The default *format_spec* is an empty string which usually gives the same
+ effect as calling ``str(value)``.
+
+ A call to ``format(value, format_spec)`` is translated to
+ ``type(value).__format__(format_spec)`` which bypasses the instance
+ dictionary when searching for the value's :meth:`__format__` method. A
+ :exc:`TypeError` exception is raised if the method is not found or if either
+ the *format_spec* or the return value are not strings.
.. function:: frozenset([iterable])
:noindex:
diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst
index d42c6ab..97ace60 100644
--- a/Doc/library/modulefinder.rst
+++ b/Doc/library/modulefinder.rst
@@ -25,8 +25,7 @@ report of the imported modules will be printed.
.. function:: ReplacePackage(oldname, newname)
Allows specifying that the module named *oldname* is in fact the package named
- *newname*. The most common usage would be to handle how the :mod:`_xmlplus`
- package replaces the :mod:`xml` package.
+ *newname*.
.. class:: ModuleFinder(path=None, debug=0, excludes=[], replace_paths=[])
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index bfb8ae9..14cd4ff 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -652,8 +652,8 @@ correspond to Unix system calls applicable to sockets.
.. method:: socket.listen(backlog)
Listen for connections made to the socket. The *backlog* argument specifies the
- maximum number of queued connections and should be at least 1; the maximum value
- is system-dependent (usually 5).
+ maximum number of queued connections and should be at least 0; the maximum value
+ is system-dependent (usually 5), the minimum value is forced to 0.
.. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 011d378..09a2961 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -289,6 +289,9 @@ Constants
Selects SSL version 2 as the channel encryption protocol.
+ This protocol is not available if OpenSSL is compiled with OPENSSL_NO_SSL2
+ flag.
+
.. warning::
SSL version 2 is insecure. Its use is highly discouraged.
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index e3c8b15..e24c450 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1047,6 +1047,15 @@ functions based on regular expressions.
*start* and *end* are interpreted as in slice notation. Return ``-1`` if
*sub* is not found.
+ .. note::
+
+ The :meth:`~str.find` method should be used only if you need to know the
+ position of *sub*. To check if *sub* is a substring or not, use the
+ :keyword:`in` operator::
+
+ >>> 'Py' in 'Python'
+ True
+
.. method:: str.format(*args, **kwargs)
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index e09994c..4c0edb3 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -217,8 +217,8 @@ This module defines one class called :class:`Popen`:
*creationflags*, if given, can be :data:`CREATE_NEW_CONSOLE` or
:data:`CREATE_NEW_PROCESS_GROUP`. (Windows only)
- Popen objects are supported as context managers via the :keyword:`with` statement,
- closing any open file descriptors on exit.
+ Popen objects are supported as context managers via the :keyword:`with` statement:
+ on exit, standard file descriptors are closed, and the process is waited for.
::
with Popen(["ifconfig"], stdout=PIPE) as proc:
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index 3969ea4..1fd3451 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -122,8 +122,8 @@ parameter expect a WSGI-compliant dictionary to be supplied; please see
def simple_app(environ, start_response):
setup_testing_defaults(environ)
- status = b'200 OK'
- headers = [(b'Content-type', b'text/plain; charset=utf-8')]
+ status = '200 OK'
+ headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
@@ -414,8 +414,8 @@ Paste" library.
# Our callable object which is intentionally not compliant to the
# standard, so the validator is going to break
def simple_app(environ, start_response):
- status = b'200 OK' # HTTP Status
- headers = [(b'Content-type', b'text/plain')] # HTTP Headers
+ status = '200 OK' # HTTP Status
+ headers = [('Content-type', 'text/plain')] # HTTP Headers
start_response(status, headers)
# This is going to break because we need to return a list, and
@@ -754,8 +754,8 @@ This is a working "Hello World" WSGI application::
# is a dictionary containing CGI-style envrironment variables and the
# second variable is the callable object (see PEP 333).
def hello_world_app(environ, start_response):
- status = b'200 OK' # HTTP Status
- headers = [(b'Content-type', b'text/plain; charset=utf-8')] # HTTP Headers
+ status = '200 OK' # HTTP Status
+ headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst
index 070967b..ab5476d 100644
--- a/Doc/library/xml.dom.minidom.rst
+++ b/Doc/library/xml.dom.minidom.rst
@@ -60,12 +60,8 @@ functions do not provide a parser implementation themselves.
You can also create a :class:`Document` by calling a method on a "DOM
Implementation" object. You can get this object either by calling the
:func:`getDOMImplementation` function in the :mod:`xml.dom` package or the
-:mod:`xml.dom.minidom` module. Using the implementation from the
-:mod:`xml.dom.minidom` module will always return a :class:`Document` instance
-from the minidom implementation, while the version from :mod:`xml.dom` may
-provide an alternate implementation (this is likely if you have the `PyXML
-package <http://pyxml.sourceforge.net/>`_ installed). Once you have a
-:class:`Document`, you can add child nodes to it to populate the DOM::
+:mod:`xml.dom.minidom` module. Once you have a :class:`Document`, you
+can add child nodes to it to populate the DOM::
from xml.dom.minidom import getDOMImplementation
diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst
index c1786a6..297fc0c 100644
--- a/Doc/library/xml.dom.rst
+++ b/Doc/library/xml.dom.rst
@@ -30,13 +30,6 @@ The Document Object Model is being defined by the W3C in stages, or "levels" in
their terminology. The Python mapping of the API is substantially based on the
DOM Level 2 recommendation.
-.. XXX PyXML is dead...
-.. The mapping of the Level 3 specification, currently
- only available in draft form, is being developed by the `Python XML Special
- Interest Group <http://www.python.org/sigs/xml-sig/>`_ as part of the `PyXML
- package <http://pyxml.sourceforge.net/>`_. Refer to the documentation bundled
- with that package for information on the current state of DOM Level 3 support.
-
.. What if your needs are somewhere between SAX and the DOM? Perhaps
you cannot afford to load the entire tree in memory but you find the
SAX model somewhat cumbersome and low-level. There is also a module
diff --git a/Lib/compileall.py b/Lib/compileall.py
index d79a1bb..743be27 100644
--- a/Lib/compileall.py
+++ b/Lib/compileall.py
@@ -35,11 +35,11 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
optimize: optimization level or -1 for level of the interpreter
"""
if not quiet:
- print('Listing', dir, '...')
+ print('Listing {!r}...'.format(dir))
try:
names = os.listdir(dir)
except os.error:
- print("Can't list", dir)
+ print("Can't list {!r}".format(dir))
names = []
names.sort()
success = 1
@@ -109,13 +109,13 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
except IOError:
pass
if not quiet:
- print('Compiling', fullname, '...')
+ print('Compiling {!r}...'.format(fullname))
try:
ok = py_compile.compile(fullname, cfile, dfile, True,
optimize=optimize)
except py_compile.PyCompileError as err:
if quiet:
- print('*** Error compiling', fullname, '...')
+ print('*** Error compiling {!r}...'.format(fullname))
else:
print('*** ', end='')
# escape non-printable characters in msg
@@ -126,7 +126,7 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
success = 0
except (SyntaxError, UnicodeError, IOError) as e:
if quiet:
- print('*** Error compiling', fullname, '...')
+ print('*** Error compiling {!r}...'.format(fullname))
else:
print('*** ', end='')
print(e.__class__.__name__ + ':', e)
diff --git a/Lib/distutils/command/build_scripts.py b/Lib/distutils/command/build_scripts.py
index 8b08bfe..a43a7c3 100644
--- a/Lib/distutils/command/build_scripts.py
+++ b/Lib/distutils/command/build_scripts.py
@@ -11,9 +11,10 @@ from distutils.core import Command
from distutils.dep_util import newer
from distutils.util import convert_path, Mixin2to3
from distutils import log
+import tokenize
# check if Python is called on the first line with this expression
-first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
+first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
class build_scripts(Command):
@@ -74,12 +75,14 @@ class build_scripts(Command):
# that way, we'll get accurate feedback if we can read the
# script.
try:
- f = open(script, "r")
+ f = open(script, "rb")
except IOError:
if not self.dry_run:
raise
f = None
else:
+ encoding, lines = tokenize.detect_encoding(f.readline)
+ f.seek(0)
first_line = f.readline()
if not first_line:
self.warn("%s is an empty file (skipping)" % script)
@@ -88,25 +91,45 @@ class build_scripts(Command):
match = first_line_re.match(first_line)
if match:
adjust = True
- post_interp = match.group(1) or ''
+ post_interp = match.group(1) or b''
if adjust:
log.info("copying and adjusting %s -> %s", script,
self.build_dir)
updated_files.append(outfile)
if not self.dry_run:
- outf = open(outfile, "w")
if not sysconfig.python_build:
- outf.write("#!%s%s\n" %
- (self.executable,
- post_interp))
+ executable = self.executable
else:
- outf.write("#!%s%s\n" %
- (os.path.join(
+ executable = os.path.join(
sysconfig.get_config_var("BINDIR"),
"python%s%s" % (sysconfig.get_config_var("VERSION"),
- sysconfig.get_config_var("EXE"))),
- post_interp))
+ sysconfig.get_config_var("EXE")))
+ executable = os.fsencode(executable)
+ shebang = b"#!" + executable + post_interp + b"\n"
+ # Python parser starts to read a script using UTF-8 until
+ # it gets a #coding:xxx cookie. The shebang has to be the
+ # first line of a file, the #coding:xxx cookie cannot be
+ # written before. So the shebang has to be decodable from
+ # UTF-8.
+ try:
+ shebang.decode('utf-8')
+ except UnicodeDecodeError:
+ raise ValueError(
+ "The shebang ({!r}) is not decodable "
+ "from utf-8".format(shebang))
+ # If the script is encoded to a custom encoding (use a
+ # #coding:xxx cookie), the shebang has to be decodable from
+ # the script encoding too.
+ try:
+ shebang.decode(encoding)
+ except UnicodeDecodeError:
+ raise ValueError(
+ "The shebang ({!r}) is not decodable "
+ "from the script encoding ({})"
+ .format(shebang, encoding))
+ outf = open(outfile, "wb")
+ outf.write(shebang)
outf.writelines(f.readlines())
outf.close()
if f:
diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py
index 381bb00..3f5d556 100644
--- a/Lib/idlelib/IOBinding.py
+++ b/Lib/idlelib/IOBinding.py
@@ -309,17 +309,20 @@ class IOBinding:
return "yes"
message = "Do you want to save %s before closing?" % (
self.filename or "this untitled document")
- m = tkMessageBox.Message(
- title="Save On Close",
- message=message,
- icon=tkMessageBox.QUESTION,
- type=tkMessageBox.YESNOCANCEL,
- master=self.text)
- reply = m.show()
- if reply == "yes":
+ confirm = tkMessageBox.askyesnocancel(
+ title="Save On Close",
+ message=message,
+ default=tkMessageBox.YES,
+ master=self.text)
+ if confirm:
+ reply = "yes"
self.save(None)
if not self.get_saved():
reply = "cancel"
+ elif confirm is None:
+ reply = "cancel"
+ else:
+ reply = "no"
self.text.focus_set()
return reply
@@ -328,7 +331,7 @@ class IOBinding:
self.save_as(event)
else:
if self.writefile(self.filename):
- self.set_saved(1)
+ self.set_saved(True)
try:
self.editwin.store_file_breaks()
except AttributeError: # may be a PyShell
@@ -420,15 +423,12 @@ class IOBinding:
self.text.insert("end-1c", "\n")
def print_window(self, event):
- m = tkMessageBox.Message(
- title="Print",
- message="Print to Default Printer",
- icon=tkMessageBox.QUESTION,
- type=tkMessageBox.OKCANCEL,
- default=tkMessageBox.OK,
- master=self.text)
- reply = m.show()
- if reply != tkMessageBox.OK:
+ confirm = tkMessageBox.askokcancel(
+ title="Print",
+ message="Print to Default Printer",
+ default=tkMessageBox.OK,
+ master=self.text)
+ if not confirm:
self.text.focus_set()
return "break"
tempfilename = None
@@ -443,8 +443,8 @@ class IOBinding:
if not self.writefile(tempfilename):
os.unlink(tempfilename)
return "break"
- platform=os.name
- printPlatform=1
+ platform = os.name
+ printPlatform = True
if platform == 'posix': #posix platform
command = idleConf.GetOption('main','General',
'print-command-posix')
@@ -452,7 +452,7 @@ class IOBinding:
elif platform == 'nt': #win32 platform
command = idleConf.GetOption('main','General','print-command-win')
else: #no printing for this platform
- printPlatform=0
+ printPlatform = False
if printPlatform: #we can try to print for this platform
command = command % filename
pipe = os.popen(command, "r")
@@ -466,7 +466,7 @@ class IOBinding:
output = "Printing command: %s\n" % repr(command) + output
tkMessageBox.showerror("Print status", output, master=self.text)
else: #no printing for this platform
- message="Printing is not enabled for this platform: %s" % platform
+ message = "Printing is not enabled for this platform: %s" % platform
tkMessageBox.showinfo("Print status", message, master=self.text)
if tempfilename:
os.unlink(tempfilename)
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index deeb4a6..18a2b82 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -1,18 +1,23 @@
-What's New in IDLE 3.1.4?
+What's New in IDLE 3.2.1?
=========================
-*Release date: XX-XXX-XX*
+*Release date: 15-May-11*
+
+- Issue #11896: Save on Close failed despite selecting "Yes" in dialog.
+
+- Issue #1028: Ctrl-space binding to show completions was causing IDLE to exit.
+ Tk < 8.5 was sending invalid Unicode null; replaced with valid null.
- <Home> toggle failing on Tk 8.5, causing IDLE exits and strange selection
behavior. Issue 4676. Improve selection extension behaviour.
-- <Home> toggle non-functional when NumLock set on Windows. Issue 3851.
+- <Home> toggle non-functional when NumLock set on Windows. Issue 3851.
What's New in IDLE 3.1b1?
=========================
-*Release date: 27-Jun-09*
+*Release date: 06-May-09*
- Use of 'filter' in keybindingDialog.py was causing custom key assignment to
fail. Patch 5707 amaury.forgeotdarc.
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
index c42b29d..41e6a59 100644
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -174,9 +174,9 @@ class ScriptBinding:
if autosave and filename:
self.editwin.io.save(None)
else:
- reply = self.ask_save_dialog()
+ confirm = self.ask_save_dialog()
self.editwin.text.focus_set()
- if reply == "ok":
+ if confirm:
self.editwin.io.save(None)
filename = self.editwin.io.filename
else:
@@ -185,13 +185,11 @@ class ScriptBinding:
def ask_save_dialog(self):
msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?"
- mb = tkMessageBox.Message(title="Save Before Run or Check",
- message=msg,
- icon=tkMessageBox.QUESTION,
- type=tkMessageBox.OKCANCEL,
- default=tkMessageBox.OK,
- master=self.editwin.text)
- return mb.show()
+ confirm = tkMessageBox.askokcancel(title="Save Before Run or Check",
+ message=msg,
+ default=tkMessageBox.OK,
+ master=self.editwin.text)
+ return confirm
def errorbox(self, title, message):
# XXX This should really be a function of EditorWindow...
diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py
index 646a785..f033ba9 100644
--- a/Lib/modulefinder.py
+++ b/Lib/modulefinder.py
@@ -35,9 +35,10 @@ def AddPackagePath(packagename, path):
replacePackageMap = {}
-# This ReplacePackage mechanism allows modulefinder to work around the
-# way the _xmlplus package injects itself under the name "xml" into
-# sys.modules at runtime by calling ReplacePackage("_xmlplus", "xml")
+# This ReplacePackage mechanism allows modulefinder to work around
+# situations in which a package injects itself under the name
+# of another package into sys.modules at runtime by calling
+# ReplacePackage("real_package_name", "faked_package_name")
# before running ModuleFinder.
def ReplacePackage(oldname, newname):
diff --git a/Lib/ssl.py b/Lib/ssl.py
index e7c175f..b12b9fd 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -62,8 +62,6 @@ import _ssl # if we can't import it, let the error propagate
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
from _ssl import _SSLContext, SSLError
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
-from _ssl import (PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23,
- PROTOCOL_TLSv1)
from _ssl import OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1
from _ssl import RAND_status, RAND_egd, RAND_add
from _ssl import (
@@ -78,6 +76,18 @@ from _ssl import (
SSL_ERROR_INVALID_ERROR_CODE,
)
from _ssl import HAS_SNI
+from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
+_PROTOCOL_NAMES = {
+ PROTOCOL_TLSv1: "TLSv1",
+ PROTOCOL_SSLv23: "SSLv23",
+ PROTOCOL_SSLv3: "SSLv3",
+}
+try:
+ from _ssl import PROTOCOL_SSLv2
+except ImportError:
+ pass
+else:
+ _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
from socket import getnameinfo as _getnameinfo
from socket import error as socket_error
@@ -552,13 +562,4 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
return DER_cert_to_PEM_cert(dercert)
def get_protocol_name(protocol_code):
- if protocol_code == PROTOCOL_TLSv1:
- return "TLSv1"
- elif protocol_code == PROTOCOL_SSLv23:
- return "SSLv23"
- elif protocol_code == PROTOCOL_SSLv2:
- return "SSLv2"
- elif protocol_code == PROTOCOL_SSLv3:
- return "SSLv3"
- else:
- return "<unknown>"
+ return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 9856e6a..28dd691 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -419,7 +419,7 @@ if mswindows:
STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
STD_ERROR_HANDLE, SW_HIDE,
STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW)
-
+
__all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP",
"STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE",
"STD_ERROR_HANDLE", "SW_HIDE",
@@ -764,6 +764,8 @@ class Popen(object):
self.stderr.close()
if self.stdin:
self.stdin.close()
+ # Wait for the process to terminate, to avoid zombies.
+ self.wait()
def __del__(self, _maxsize=sys.maxsize, _active=_active):
if not self._child_created:
diff --git a/Lib/test/json_tests/test_recursion.py b/Lib/test/json_tests/test_recursion.py
index 6d5db50..ab5f213 100644
--- a/Lib/test/json_tests/test_recursion.py
+++ b/Lib/test/json_tests/test_recursion.py
@@ -16,6 +16,11 @@ class RecursiveJSONEncoder(json.JSONEncoder):
return 'JSONTestObject'
return json.JSONEncoder.default(o)
+class EndlessJSONEncoder(json.JSONEncoder):
+ def default(self, o):
+ """If check_circular is False, this will keep adding another list."""
+ return [o]
+
class TestRecursion(TestCase):
def test_listrecursion(self):
@@ -67,7 +72,7 @@ class TestRecursion(TestCase):
self.fail("didn't raise ValueError on default recursion")
- def test_highly_nested_objects(self):
+ def test_highly_nested_objects_decoding(self):
# test that loading highly-nested objects doesn't segfault when C
# accelerations are used. See #12017
with self.assertRaises(RuntimeError):
@@ -77,3 +82,17 @@ class TestRecursion(TestCase):
with self.assertRaises(RuntimeError):
json.loads('[' * 100000 + '1' + ']' * 100000)
+ def test_highly_nested_objects_encoding(self):
+ # See #12051
+ l, d = [], {}
+ for x in range(100000):
+ l, d = [l], {'k':d}
+ with self.assertRaises(RuntimeError):
+ json.dumps(l)
+ with self.assertRaises(RuntimeError):
+ json.dumps(d)
+
+ def test_endless_recursion(self):
+ # See #12051
+ with self.assertRaises(RuntimeError):
+ EndlessJSONEncoder(check_circular=False).encode(5j)
diff --git a/Lib/test/support.py b/Lib/test/support.py
index a9e1b77..cab366b 100644
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -43,8 +43,9 @@ __all__ = [
"run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
"reap_children", "cpython_only", "check_impl_detail", "get_attribute",
"swap_item", "swap_attr", "requires_IEEE_754",
- "TestHandler", "Matcher", "can_symlink", "skip_unless_symlink"]
-
+ "TestHandler", "Matcher", "can_symlink", "skip_unless_symlink",
+ "import_fresh_module"
+ ]
class Error(Exception):
"""Base class for regression test exceptions."""
@@ -91,12 +92,14 @@ def import_module(name, deprecated=False):
def _save_and_remove_module(name, orig_modules):
"""Helper function to save and remove a module from sys.modules
- Return value is True if the module was in sys.modules and
- False otherwise."""
+ Return True if the module was in sys.modules, False otherwise.
+ Raise ImportError if the module can't be imported."""
saved = True
try:
orig_modules[name] = sys.modules[name]
except KeyError:
+ # try to import the module and raise an error if it can't be imported
+ __import__(name)
saved = False
else:
del sys.modules[name]
@@ -106,8 +109,7 @@ def _save_and_remove_module(name, orig_modules):
def _save_and_block_module(name, orig_modules):
"""Helper function to save and block a module in sys.modules
- Return value is True if the module was in sys.modules and
- False otherwise."""
+ Return True if the module was in sys.modules, False otherwise."""
saved = True
try:
orig_modules[name] = sys.modules[name]
@@ -123,6 +125,7 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False):
the sys.modules cache is restored to its original state.
Modules named in fresh are also imported anew if needed by the import.
+ If one of these modules can't be imported, None is returned.
Importing of modules named in blocked is prevented while the fresh import
takes place.
@@ -144,6 +147,8 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False):
if not _save_and_block_module(blocked_name, orig_modules):
names_to_remove.append(blocked_name)
fresh_module = importlib.import_module(name)
+ except ImportError:
+ fresh_module = None
finally:
for orig_name, module in orig_modules.items():
sys.modules[orig_name] = module
diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
index c1dfdb3..d1c9ee5 100644
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -345,7 +345,7 @@ class CommandLineTests(unittest.TestCase):
def test_invalid_arg_produces_message(self):
out = self.assertRunOK('badfilename')
- self.assertRegex(out, b"Can't list badfilename")
+ self.assertRegex(out, b"Can't list 'badfilename'")
def test_main():
diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py
index b41458b..e0c49c1 100644
--- a/Lib/test/test_heapq.py
+++ b/Lib/test/test_heapq.py
@@ -1,16 +1,31 @@
"""Unittests for heapq."""
+import sys
import random
-import unittest
+
from test import support
-import sys
+from unittest import TestCase, skipUnless
-# We do a bit of trickery here to be able to test both the C implementation
-# and the Python implementation of the module.
-import heapq as c_heapq
py_heapq = support.import_fresh_module('heapq', blocked=['_heapq'])
+c_heapq = support.import_fresh_module('heapq', fresh=['_heapq'])
+
+# _heapq.nlargest/nsmallest are saved in heapq._nlargest/_smallest when
+# _heapq is imported, so check them there
+func_names = ['heapify', 'heappop', 'heappush', 'heappushpop',
+ 'heapreplace', '_nlargest', '_nsmallest']
-class TestHeap(unittest.TestCase):
+class TestModules(TestCase):
+ def test_py_functions(self):
+ for fname in func_names:
+ self.assertEqual(getattr(py_heapq, fname).__module__, 'heapq')
+
+ @skipUnless(c_heapq, 'requires _heapq')
+ def test_c_functions(self):
+ for fname in func_names:
+ self.assertEqual(getattr(c_heapq, fname).__module__, '_heapq')
+
+
+class TestHeap(TestCase):
module = None
def test_push_pop(self):
@@ -176,21 +191,8 @@ class TestHeap(unittest.TestCase):
self.assertEqual(list(self.module.nlargest(n, data, key=f)),
sorted(data, key=f, reverse=True)[:n])
-class TestHeapPython(TestHeap):
- module = py_heapq
-
- # As an early adopter, we sanity check the
- # test.support.import_fresh_module utility function
- def test_pure_python(self):
- self.assertFalse(sys.modules['heapq'] is self.module)
- self.assertTrue(hasattr(self.module.heapify, '__code__'))
-
-
-class TestHeapC(TestHeap):
- module = c_heapq
-
def test_comparison_operator(self):
- # Issue 3501: Make sure heapq works with both __lt__
+ # Issue 3051: Make sure heapq works with both __lt__
# For python 3.0, __le__ alone is not enough
def hsort(data, comp):
data = [comp(x) for x in data]
@@ -212,6 +214,15 @@ class TestHeapC(TestHeap):
self.assertRaises(TypeError, data, LE)
+class TestHeapPython(TestHeap):
+ module = py_heapq
+
+
+@skipUnless(c_heapq, 'requires _heapq')
+class TestHeapC(TestHeap):
+ module = c_heapq
+
+
#==============================================================================
class LenOnly:
@@ -307,9 +318,9 @@ def L(seqn):
'Test multiple tiers of iterators'
return chain(map(lambda x:x, R(Ig(G(seqn)))))
-class TestErrorHandling(unittest.TestCase):
- # only for C implementation
- module = c_heapq
+
+class TestErrorHandling(TestCase):
+ module = None
def test_non_sequence(self):
for f in (self.module.heapify, self.module.heappop):
@@ -360,11 +371,20 @@ class TestErrorHandling(unittest.TestCase):
self.assertRaises(ZeroDivisionError, f, 2, E(s))
+class TestErrorHandlingPython(TestErrorHandling):
+ module = py_heapq
+
+@skipUnless(c_heapq, 'requires _heapq')
+class TestErrorHandlingC(TestErrorHandling):
+ module = c_heapq
+
+
#==============================================================================
def test_main(verbose=None):
- test_classes = [TestHeapPython, TestHeapC, TestErrorHandling]
+ test_classes = [TestModules, TestHeapPython, TestHeapC,
+ TestErrorHandlingPython, TestErrorHandlingC]
support.run_unittest(*test_classes)
# verify reference counting
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index b665a6c..dac30cb 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -1490,6 +1490,32 @@ class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest):
self.assertEqual(s,
b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size))
+ def test_write_rewind_write(self):
+ # Various combinations of reading / writing / seeking backwards / writing again
+ def mutate(bufio, pos1, pos2):
+ assert pos2 >= pos1
+ # Fill the buffer
+ bufio.seek(pos1)
+ bufio.read(pos2 - pos1)
+ bufio.write(b'\x02')
+ # This writes earlier than the previous write, but still inside
+ # the buffer.
+ bufio.seek(pos1)
+ bufio.write(b'\x01')
+
+ b = b"\x80\x81\x82\x83\x84"
+ for i in range(0, len(b)):
+ for j in range(i, len(b)):
+ raw = self.BytesIO(b)
+ bufio = self.tp(raw, 100)
+ mutate(bufio, i, j)
+ bufio.flush()
+ expected = bytearray(b)
+ expected[j] = 2
+ expected[i] = 1
+ self.assertEqual(raw.getvalue(), expected,
+ "failed result for i=%d, j=%d" % (i, j))
+
def test_truncate_after_read_or_write(self):
raw = self.BytesIO(b"A" * 10)
bufio = self.tp(raw, 100)
diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py
index 4c2b34a..200b95d 100644
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -45,26 +45,6 @@ def create_doc_with_doctype():
return doc
class MinidomTest(unittest.TestCase):
- def tearDown(self):
- try:
- Node.allnodes
- except AttributeError:
- # We don't actually have the minidom from the standard library,
- # but are picking up the PyXML version from site-packages.
- pass
- else:
- self.confirm(len(Node.allnodes) == 0,
- "assertion: len(Node.allnodes) == 0")
- if len(Node.allnodes):
- print("Garbage left over:")
- if verbose:
- print(list(Node.allnodes.items())[0:10])
- else:
- # Don't print specific nodes if repeatable results
- # are needed
- print(len(Node.allnodes))
- Node.allnodes = {}
-
def confirm(self, test, testname = "Test"):
self.assertTrue(test, testname)
diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py
index 0f6a1ca..1225d6e 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -794,51 +794,6 @@ class XmlReaderTest(XmlTestBase):
self.assertEqual(attrs.getQNameByName((ns_uri, "attr")), "ns:attr")
- # During the development of Python 2.5, an attempt to move the "xml"
- # package implementation to a new package ("xmlcore") proved painful.
- # The goal of this change was to allow applications to be able to
- # obtain and rely on behavior in the standard library implementation
- # of the XML support without needing to be concerned about the
- # availability of the PyXML implementation.
- #
- # While the existing import hackery in Lib/xml/__init__.py can cause
- # PyXML's _xmlpus package to supplant the "xml" package, that only
- # works because either implementation uses the "xml" package name for
- # imports.
- #
- # The move resulted in a number of problems related to the fact that
- # the import machinery's "package context" is based on the name that's
- # being imported rather than the __name__ of the actual package
- # containment; it wasn't possible for the "xml" package to be replaced
- # by a simple module that indirected imports to the "xmlcore" package.
- #
- # The following two tests exercised bugs that were introduced in that
- # attempt. Keeping these tests around will help detect problems with
- # other attempts to provide reliable access to the standard library's
- # implementation of the XML support.
-
- def test_sf_1511497(self):
- # Bug report: http://www.python.org/sf/1511497
- import sys
- old_modules = sys.modules.copy()
- for modname in list(sys.modules.keys()):
- if modname.startswith("xml."):
- del sys.modules[modname]
- try:
- import xml.sax.expatreader
- module = xml.sax.expatreader
- self.assertEqual(module.__name__, "xml.sax.expatreader")
- finally:
- sys.modules.update(old_modules)
-
- def test_sf_1513611(self):
- # Bug report: http://www.python.org/sf/1513611
- sio = StringIO("invalid")
- parser = make_parser()
- from xml.sax import SAXParseException
- self.assertRaises(SAXParseException, parser.parse, sio)
-
-
def test_main():
run_unittest(MakeParserTest,
SaxutilsTest,
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index a948541..baca4c1 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -564,23 +564,9 @@ class GeneralModuleTests(unittest.TestCase):
# XXX The following don't test module-level functionality...
- def _get_unused_port(self, bind_address='0.0.0.0'):
- """Use a temporary socket to elicit an unused ephemeral port.
-
- Args:
- bind_address: Hostname or IP address to search for a port on.
-
- Returns: A most likely to be unused port.
- """
- tempsock = socket.socket()
- tempsock.bind((bind_address, 0))
- host, port = tempsock.getsockname()
- tempsock.close()
- return port
-
def testSockName(self):
# Testing getsockname()
- port = self._get_unused_port()
+ port = support.find_unused_port()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.addCleanup(sock.close)
sock.bind(("0.0.0.0", port))
@@ -629,7 +615,7 @@ class GeneralModuleTests(unittest.TestCase):
def test_getsockaddrarg(self):
host = '0.0.0.0'
- port = self._get_unused_port(bind_address=host)
+ port = support.find_unused_port()
big_port = port + 65536
neg_port = port - 65536
sock = socket.socket()
@@ -788,6 +774,13 @@ class GeneralModuleTests(unittest.TestCase):
fp.close()
self.assertEqual(repr(fp), "<_io.BufferedReader name=-1>")
+ def testListenBacklog0(self):
+ srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ srv.bind((HOST, 0))
+ # backlog = 0
+ srv.listen(0)
+ srv.close()
+
@unittest.skipUnless(thread, 'Threading required for this test.')
class BasicTCPTest(SocketConnectedTest):
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index ba788e4..f65aceb 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -21,9 +21,11 @@ import functools
ssl = support.import_module("ssl")
PROTOCOLS = [
- ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3,
+ ssl.PROTOCOL_SSLv3,
ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
]
+if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ PROTOCOLS.append(ssl.PROTOCOL_SSLv2)
HOST = support.HOST
@@ -67,22 +69,25 @@ def no_sslv2_implies_sslv3_hello():
# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
def skip_if_broken_ubuntu_ssl(func):
- @functools.wraps(func)
- def f(*args, **kwargs):
- try:
- ssl.SSLContext(ssl.PROTOCOL_SSLv2)
- except ssl.SSLError:
- if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
- platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
- raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
- return func(*args, **kwargs)
- return f
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ @functools.wraps(func)
+ def f(*args, **kwargs):
+ try:
+ ssl.SSLContext(ssl.PROTOCOL_SSLv2)
+ except ssl.SSLError:
+ if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
+ platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
+ raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
+ return func(*args, **kwargs)
+ return f
+ else:
+ return func
class BasicSocketTests(unittest.TestCase):
def test_constants(self):
- ssl.PROTOCOL_SSLv2
+ #ssl.PROTOCOL_SSLv2
ssl.PROTOCOL_SSLv23
ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLSv1
@@ -310,7 +315,8 @@ class ContextTests(unittest.TestCase):
@skip_if_broken_ubuntu_ssl
def test_constructor(self):
- ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
@@ -1199,6 +1205,7 @@ else:
t.join()
@skip_if_broken_ubuntu_ssl
+ @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), "need SSLv2")
def test_protocol_sslv2(self):
"""Connecting to an SSLv2 server with various client options"""
if support.verbose:
@@ -1224,14 +1231,15 @@ else:
"""Connecting to an SSLv23 server with various client options"""
if support.verbose:
sys.stdout.write("\n")
- try:
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
- except (ssl.SSLError, socket.error) as x:
- # this fails on some older versions of OpenSSL (0.9.7l, for instance)
- if support.verbose:
- sys.stdout.write(
- " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
- % str(x))
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try:
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
+ except (ssl.SSLError, socket.error) as x:
+ # this fails on some older versions of OpenSSL (0.9.7l, for instance)
+ if support.verbose:
+ sys.stdout.write(
+ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
+ % str(x))
try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
@@ -1262,7 +1270,8 @@ else:
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
if no_sslv2_implies_sslv3_hello():
@@ -1278,7 +1287,8 @@ else:
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 4ec754c..176ff10 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -1491,7 +1491,8 @@ class ContextManagerTests(ProcessTestCase):
def test_returncode(self):
with subprocess.Popen([sys.executable, "-c",
"import sys; sys.exit(100)"]) as proc:
- proc.wait()
+ pass
+ # __exit__ calls wait(), so the returncode should be set
self.assertEqual(proc.returncode, 100)
def test_communicate_stdin(self):
diff --git a/Lib/xml/__init__.py b/Lib/xml/__init__.py
index deed983..bf6d8dd 100644
--- a/Lib/xml/__init__.py
+++ b/Lib/xml/__init__.py
@@ -18,24 +18,3 @@ etree -- The ElementTree XML library. This is a subset of the full
__all__ = ["dom", "parsers", "sax", "etree"]
-
-_MINIMUM_XMLPLUS_VERSION = (0, 8, 4)
-
-
-try:
- import _xmlplus
-except ImportError:
- pass
-else:
- try:
- v = _xmlplus.version_info
- except AttributeError:
- # _xmlplus is too old; ignore it
- pass
- else:
- if v >= _MINIMUM_XMLPLUS_VERSION:
- import sys
- _xmlplus.__path__.extend(__path__)
- sys.modules[__name__] = _xmlplus
- else:
- del v
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 460c7c7..db870a4 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -76,6 +76,7 @@ PY_CFLAGS= $(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS)
# environment variables
PY_CPPFLAGS= -I. -IInclude -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS)
PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS)
+NO_AS_NEEDED= @NO_AS_NEEDED@
LDLAST= @LDLAST@
SGI_ABI= @SGI_ABI@
CCSHARED= @CCSHARED@
@@ -459,7 +460,7 @@ libpython$(LDVERSION).so: $(LIBRARY_OBJS)
fi
libpython3.so: libpython$(LDVERSION).so
- $(BLDSHARED) -o $@ -Wl,-hl$@ $^
+ $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^
libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
$(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
diff --git a/Misc/ACKS b/Misc/ACKS
index 5c33b2e..399de8c 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -268,6 +268,7 @@ Carey Evans
Tim Everett
Paul Everitt
David Everly
+Daniel Evers
Greg Ewing
Martijn Faassen
Clovis Fabricio
diff --git a/Misc/NEWS b/Misc/NEWS
index 4b20d44..dfde0b2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,13 @@ What's New in Python 3.2.1 beta 1?
Core and Builtins
-----------------
+- Issue #12044: Fixed subprocess.Popen when used as a context manager to
+ wait for the process to end when exiting the context to avoid unintentionally
+ leaving zombie processes around.
+
+- Issue #1195: Fix input() if it is interrupted by CTRL+d and then CTRL+c,
+ clear the end-of-file indicator after CTRL+d.
+
- Issue #1856: Avoid crashes and lockups when daemon threads run while the
interpreter is shutting down; instead, these threads are now killed when they
try to take the GIL.
@@ -83,6 +90,28 @@ Core and Builtins
Library
-------
+- Issue #12062: Fix a flushing bug when doing a certain type of I/O sequence
+ on a file opened in read+write mode (namely: reading, seeking a bit forward,
+ writing, then seeking before the previous write but still within buffered
+ data, and writing again).
+
+- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError.
+ With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused
+ IDLE to exit. Converted to valid Unicode null in PythonCmd().
+
+- Issue #11169: compileall module uses repr() to format filenames and paths to
+ escape surrogate characters and show spaces.
+
+- Issue #10419, #6011: build_scripts command of distutils handles correctly
+ non-ASCII path (path to the Python executable). Open and write the script in
+ binary mode, but ensure that the shebang is decodable from UTF-8 and from the
+ encoding of the script.
+
+- Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in
+ order to accept exactly one connection. Patch by Daniel Evers.
+
+- Issue #11164: Stop trying to use _xmlplus in the xml module.
+
- Issue #11927: SMTP_SSL now uses port 465 by default as documented. Patch by
Kasun Herath.
@@ -314,6 +343,8 @@ Library
Build
-----
+- Issue #11347: Use --no-as-needed when linking libpython3.so.
+
- Issue #11411: Fix 'make DESTDIR=' with a relative destination.
- Issue #11268: Prevent Mac OS X Installer failure if Documentation package had
@@ -333,6 +364,9 @@ Tools/Demos
Extension Modules
-----------------
+- Issue #12051: Fix segfault in json.dumps() while encoding highly-nested
+ objects using the C accelerations.
+
- Issue #12017: Fix segfault in json.loads() while decoding highly-nested
objects using the C accelerations.
@@ -613,6 +647,8 @@ Core and Builtins
Library
-------
+- Issue #12012: ssl.PROTOCOL_SSLv2 becomes optional.
+
- Issue #10916: mmap should not segfault when a file is mapped using 0 as length
and a non-zero offset, and an attempt to read past the end of file is made
(IndexError is raised instead). Patch by Ross Lagerwall.
@@ -828,6 +864,8 @@ Tools/Demos
Tests
-----
+- Issue #11910: Fix test_heapq to skip the C tests when _heapq is missing.
+
- Fix test_startfile to wait for child process to terminate before finishing.
- Issue #10822: Fix test_posix:test_getgroups failure under Solaris. Patch
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 386a880..26ebde0 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1838,7 +1838,7 @@ bufferedwriter_write(buffered *self, PyObject *args)
avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
if (buf.len <= avail) {
memcpy(self->buffer + self->pos, buf.buf, buf.len);
- if (!VALID_WRITE_BUFFER(self)) {
+ if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
self->write_pos = self->pos;
}
ADJUST_POSITION(self, self->pos + buf.len);
diff --git a/Modules/_json.c b/Modules/_json.c
index dd71003..0924873 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -1338,10 +1338,18 @@ encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssi
return _steal_list_append(rval, encoded);
}
else if (PyList_Check(obj) || PyTuple_Check(obj)) {
- return encoder_listencode_list(s, rval, obj, indent_level);
+ if (Py_EnterRecursiveCall(" while encoding a JSON object"))
+ return -1;
+ rv = encoder_listencode_list(s, rval, obj, indent_level);
+ Py_LeaveRecursiveCall();
+ return rv;
}
else if (PyDict_Check(obj)) {
- return encoder_listencode_dict(s, rval, obj, indent_level);
+ if (Py_EnterRecursiveCall(" while encoding a JSON object"))
+ return -1;
+ rv = encoder_listencode_dict(s, rval, obj, indent_level);
+ Py_LeaveRecursiveCall();
+ return rv;
}
else {
PyObject *ident = NULL;
@@ -1367,7 +1375,12 @@ encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssi
Py_XDECREF(ident);
return -1;
}
+
+ if (Py_EnterRecursiveCall(" while encoding a JSON object"))
+ return -1;
rv = encoder_listencode_obj(s, rval, newobj, indent_level);
+ Py_LeaveRecursiveCall();
+
Py_DECREF(newobj);
if (rv) {
Py_XDECREF(ident);
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index e494264..a813d5f 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -63,8 +63,10 @@ enum py_ssl_cert_requirements {
};
enum py_ssl_version {
+#ifndef OPENSSL_NO_SSL2
PY_SSL_VERSION_SSL2,
- PY_SSL_VERSION_SSL3,
+#endif
+ PY_SSL_VERSION_SSL3=1,
PY_SSL_VERSION_SSL23,
PY_SSL_VERSION_TLS1
};
@@ -1450,8 +1452,10 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
ctx = SSL_CTX_new(TLSv1_method());
else if (proto_version == PY_SSL_VERSION_SSL3)
ctx = SSL_CTX_new(SSLv3_method());
+#ifndef OPENSSL_NO_SSL2
else if (proto_version == PY_SSL_VERSION_SSL2)
ctx = SSL_CTX_new(SSLv2_method());
+#endif
else if (proto_version == PY_SSL_VERSION_SSL23)
ctx = SSL_CTX_new(SSLv23_method());
else
@@ -2110,8 +2114,10 @@ PyInit__ssl(void)
PY_SSL_CERT_REQUIRED);
/* protocol versions */
+#ifndef OPENSSL_NO_SSL2
PyModule_AddIntConstant(m, "PROTOCOL_SSLv2",
PY_SSL_VERSION_SSL2);
+#endif
PyModule_AddIntConstant(m, "PROTOCOL_SSLv3",
PY_SSL_VERSION_SSL3);
PyModule_AddIntConstant(m, "PROTOCOL_SSLv23",
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index c7c1530..cb2795f 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -2023,7 +2023,19 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
for (i = 0; i < (argc - 1); i++) {
PyObject *s = PyUnicode_FromString(argv[i + 1]);
- if (!s || PyTuple_SetItem(arg, i, s)) {
+ if (!s) {
+ /* Is Tk leaking 0xC080 in %A - a "modified" utf-8 null? */
+ if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) &&
+ !strcmp(argv[i + 1], "\xC0\x80")) {
+ PyErr_Clear();
+ /* Convert to "strict" utf-8 null */
+ s = PyUnicode_FromString("\0");
+ } else {
+ Py_DECREF(arg);
+ return PythonCmd_Error(interp);
+ }
+ }
+ if (PyTuple_SetItem(arg, i, s)) {
Py_DECREF(arg);
return PythonCmd_Error(interp);
}
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index e2fdb5e..bc11b23 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -2220,8 +2220,10 @@ sock_listen(PySocketSockObject *s, PyObject *arg)
if (backlog == -1 && PyErr_Occurred())
return NULL;
Py_BEGIN_ALLOW_THREADS
- if (backlog < 1)
- backlog = 1;
+ /* To avoid problems on systems that don't allow a negative backlog
+ * (which doesn't make sense anyway) we force a minimum value of 0. */
+ if (backlog < 0)
+ backlog = 0;
res = listen(s->sock_fd, backlog);
Py_END_ALLOW_THREADS
if (res < 0)
@@ -2234,8 +2236,9 @@ PyDoc_STRVAR(listen_doc,
"listen(backlog)\n\
\n\
Enable a server to accept connections. The backlog argument must be at\n\
-least 1; it specifies the number of unaccepted connection that the system\n\
-will allow before refusing new connections.");
+least 0 (if it is lower, it is set to 0); it specifies the number of\n\
+unaccepted connections that the system will allow before refusing new\n\
+connections.");
/*
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
index 50802c3..b12d052 100644
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -73,6 +73,7 @@ my_fgets(char *buf, int len, FILE *fp)
}
#endif /* MS_WINDOWS */
if (feof(fp)) {
+ clearerr(fp);
return -1; /* EOF */
}
#ifdef EINTR
diff --git a/configure b/configure
index 98ae6e6..a0c8ca0 100755
--- a/configure
+++ b/configure
@@ -668,6 +668,7 @@ BUILDEXEEXT
EGREP
GREP
CPP
+NO_AS_NEEDED
MAINCC
CXX
OBJEXT
@@ -1572,6 +1573,52 @@ fi
} # ac_fn_c_try_compile
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1773,52 +1820,6 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_header_compile
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -4168,8 +4169,38 @@ $as_echo "$as_me: WARNING:
fi
-# checks for UNIX variants that set C preprocessor variables
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5
+$as_echo_n "checking for -Wl,--no-as-needed... " >&6; }
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,--no-as-needed"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ NO_AS_NEEDED="-Wl,--no-as-needed"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ NO_AS_NEEDED=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LDFLAGS="$save_LDFLAGS"
+
+
+
+# checks for UNIX variants that set C preprocessor variables
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
diff --git a/configure.in b/configure.in
index aaeb9bc..8dc56a3 100644
--- a/configure.in
+++ b/configure.in
@@ -525,6 +525,18 @@ then
fi
+AC_MSG_CHECKING([for -Wl,--no-as-needed])
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,--no-as-needed"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [NO_AS_NEEDED="-Wl,--no-as-needed"
+ AC_MSG_RESULT([yes])],
+ [NO_AS_NEEDED=""
+ AC_MSG_RESULT([no])])
+LDFLAGS="$save_LDFLAGS"
+AC_SUBST(NO_AS_NEEDED)
+
+
# checks for UNIX variants that set C preprocessor variables
AC_USE_SYSTEM_EXTENSIONS