summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/collections.rst58
-rw-r--r--Doc/library/http.cookiejar.rst2
-rw-r--r--Doc/library/readline.rst2
-rw-r--r--Doc/library/sys.rst40
-rw-r--r--Doc/tutorial/interactive.rst5
-rw-r--r--Lib/ctypes/test/test_as_parameter.py12
-rw-r--r--Lib/idlelib/EditorWindow.py27
-rw-r--r--Lib/idlelib/NEWS.txt11
-rw-r--r--Lib/msilib/__init__.py26
-rw-r--r--Lib/multiprocessing/sharedctypes.py4
-rw-r--r--Lib/re.py3
-rw-r--r--Lib/test/test_mailbox.py18
-rw-r--r--Lib/test/test_msilib.py46
-rw-r--r--Lib/test/test_multiprocessing.py15
-rw-r--r--Lib/test/test_re.py78
-rw-r--r--Lib/test/test_subprocess.py1
-rw-r--r--Lib/test/test_xdrlib.py2
-rw-r--r--Lib/xdrlib.py4
-rw-r--r--Misc/ACKS3
-rw-r--r--Misc/NEWS17
-rw-r--r--Modules/_ctypes/_ctypes.c74
-rw-r--r--Modules/getbuildinfo.c6
22 files changed, 335 insertions, 119 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index b52868e..02415f7 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -907,10 +907,10 @@ attribute.
ABCs - abstract base classes
----------------------------
-The collections module offers the following ABCs:
+The collections module offers the following :term:`ABCs <abstract base class>`:
========================= ===================== ====================== ====================================================
-ABC Inherits Abstract Methods Mixin Methods
+ABC Inherits from Abstract Methods Mixin Methods
========================= ===================== ====================== ====================================================
:class:`Container` ``__contains__``
:class:`Hashable` ``__hash__``
@@ -923,15 +923,15 @@ ABC Inherits Abstract Methods Mixin
:class:`Iterable`, ``index``, and ``count``
:class:`Container`
-:class:`MutableSequence` :class:`Sequence` ``__setitem__`` Inherited Sequence methods and
+:class:`MutableSequence` :class:`Sequence` ``__setitem__``, Inherited :class:`Sequence` methods and
``__delitem__``, ``append``, ``reverse``, ``extend``, ``pop``,
- and ``insert`` ``remove``, and ``__iadd__``
+ ``insert`` ``remove``, and ``__iadd__``
:class:`Set` :class:`Sized`, ``__le__``, ``__lt__``, ``__eq__``, ``__ne__``,
:class:`Iterable`, ``__gt__``, ``__ge__``, ``__and__``, ``__or__``,
:class:`Container` ``__sub__``, ``__xor__``, and ``isdisjoint``
-:class:`MutableSet` :class:`Set` ``add`` and Inherited Set methods and
+:class:`MutableSet` :class:`Set` ``add``, Inherited :class:`Set` methods and
``discard`` ``clear``, ``pop``, ``remove``, ``__ior__``,
``__iand__``, ``__ixor__``, and ``__isub__``
@@ -939,19 +939,61 @@ ABC Inherits Abstract Methods Mixin
:class:`Iterable`, ``get``, ``__eq__``, and ``__ne__``
:class:`Container`
-:class:`MutableMapping` :class:`Mapping` ``__setitem__`` and Inherited Mapping methods and
+:class:`MutableMapping` :class:`Mapping` ``__setitem__``, Inherited :class:`Mapping` methods and
``__delitem__`` ``pop``, ``popitem``, ``clear``, ``update``,
and ``setdefault``
:class:`MappingView` :class:`Sized` ``__len__``
-:class:`KeysView` :class:`MappingView`, ``__contains__``,
- :class:`Set` ``__iter__``
:class:`ItemsView` :class:`MappingView`, ``__contains__``,
:class:`Set` ``__iter__``
+:class:`KeysView` :class:`MappingView`, ``__contains__``,
+ :class:`Set` ``__iter__``
:class:`ValuesView` :class:`MappingView` ``__contains__``, ``__iter__``
========================= ===================== ====================== ====================================================
+
+.. class:: Container
+ Hashable
+ Sized
+ Callable
+
+ ABCs for classes that provide respectively the methods :meth:`__contains__`,
+ :meth:`__hash__`, :meth:`__len__`, and :meth:`__call__`.
+
+.. class:: Iterable
+
+ ABC for classes that provide the :meth:`__iter__` method.
+ See also the definition of :term:`iterable`.
+
+.. class:: Iterator
+
+ ABC for classes that provide the :meth:`__iter__` and :meth:`next` methods.
+ See also the definition of :term:`iterator`.
+
+.. class:: Sequence
+ MutableSequence
+
+ ABCs for read-only and mutable :term:`sequences <sequence>`.
+
+.. class:: Set
+ MutableSet
+
+ ABCs for read-only and mutable sets.
+
+.. class:: Mapping
+ MutableMapping
+
+ ABCs for read-only and mutable :term:`mappings <mapping>`.
+
+.. class:: MappingView
+ ItemsView
+ KeysView
+ ValuesView
+
+ ABCs for mapping, items, keys, and values :term:`views <view>`.
+
+
These ABCs allow us to ask classes or instances if they provide
particular functionality, for example::
diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst
index 1aafec9..74d8d16 100644
--- a/Doc/library/http.cookiejar.rst
+++ b/Doc/library/http.cookiejar.rst
@@ -719,7 +719,7 @@ cookies (assumes Unix/Netscape convention for location of the cookies file)::
import os, http.cookiejar, urllib.request
cj = http.cookiejar.MozillaCookieJar()
- cj.load(os.path.join(os.environ["HOME"], ".netscape/cookies.txt"))
+ cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst
index 218f81e..ab7b4b6 100644
--- a/Doc/library/readline.rst
+++ b/Doc/library/readline.rst
@@ -197,7 +197,7 @@ normally be executed automatically during interactive sessions from the user's
import os
import readline
- histfile = os.path.join(os.environ["HOME"], ".pyhist")
+ histfile = os.path.join(os.path.expanduser("~"), ".pyhist")
try:
readline.read_history_file(histfile)
except IOError:
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index a9d24f3..e51e8ea 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -206,31 +206,21 @@ always available.
The struct sequence *flags* exposes the status of command line flags. The
attributes are read only.
- +------------------------------+------------------------------------------+
- | attribute | flag |
- +==============================+==========================================+
- | :const:`debug` | -d |
- +------------------------------+------------------------------------------+
- | :const:`division_warning` | -Q |
- +------------------------------+------------------------------------------+
- | :const:`inspect` | -i |
- +------------------------------+------------------------------------------+
- | :const:`interactive` | -i |
- +------------------------------+------------------------------------------+
- | :const:`optimize` | -O or -OO |
- +------------------------------+------------------------------------------+
- | :const:`dont_write_bytecode` | -B |
- +------------------------------+------------------------------------------+
- | :const:`no_user_site` | -s |
- +------------------------------+------------------------------------------+
- | :const:`no_site` | -S |
- +------------------------------+------------------------------------------+
- | :const:`ignore_environment` | -E |
- +------------------------------+------------------------------------------+
- | :const:`verbose` | -v |
- +------------------------------+------------------------------------------+
- | :const:`bytes_warning` | -b |
- +------------------------------+------------------------------------------+
+ ============================= =============================
+ attribute flag
+ ============================= =============================
+ :const:`debug` :option:`-d`
+ :const:`division_warning` :option:`-Q`
+ :const:`inspect` :option:`-i`
+ :const:`interactive` :option:`-i`
+ :const:`optimize` :option:`-O` or :option:`-OO`
+ :const:`dont_write_bytecode` :option:`-B`
+ :const:`no_user_site` :option:`-s`
+ :const:`no_site` :option:`-S`
+ :const:`ignore_environment` :option:`-E`
+ :const:`verbose` :option:`-v`
+ :const:`bytes_warning` :option:`-b`
+ ============================= =============================
.. data:: float_info
diff --git a/Doc/tutorial/interactive.rst b/Doc/tutorial/interactive.rst
index ca0cfaf..5faaf96 100644
--- a/Doc/tutorial/interactive.rst
+++ b/Doc/tutorial/interactive.rst
@@ -123,10 +123,7 @@ interpreter. ::
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
- # to it: "export PYTHONSTARTUP=/home/user/.pystartup" in bash.
- #
- # Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
- # full path to your home directory.
+ # to it: "export PYTHONSTARTUP=~/.pystartup" in bash.
import atexit
import os
diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py
index 835398f..475d595 100644
--- a/Lib/ctypes/test/test_as_parameter.py
+++ b/Lib/ctypes/test/test_as_parameter.py
@@ -187,6 +187,18 @@ class BasicWrapTestCase(unittest.TestCase):
self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+ def test_recursive_as_param(self):
+ from ctypes import c_int
+
+ class A(object):
+ pass
+
+ a = A()
+ a._as_parameter_ = a
+ with self.assertRaises(RuntimeError):
+ c_int.from_param(a)
+
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class AsParamWrapper(object):
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index 173fad9..98ec02b 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -304,13 +304,13 @@ class EditorWindow(object):
return "break"
def home_callback(self, event):
- if (event.state & 12) != 0 and event.keysym == "Home":
- # state&1==shift, state&4==control, state&8==alt
- return # <Modifier-Home>; fall back to class binding
-
+ if (event.state & 4) != 0 and event.keysym == "Home":
+ # state&4==Control. If <Control-Home>, use the Tk binding.
+ return
if self.text.index("iomark") and \
self.text.compare("iomark", "<=", "insert lineend") and \
self.text.compare("insert linestart", "<=", "iomark"):
+ # In Shell on input line, go to just after prompt
insertpt = int(self.text.index("iomark").split(".")[1])
else:
line = self.text.get("insert linestart", "insert lineend")
@@ -319,30 +319,27 @@ class EditorWindow(object):
break
else:
insertpt=len(line)
-
lineat = int(self.text.index("insert").split('.')[1])
-
if insertpt == lineat:
insertpt = 0
-
dest = "insert linestart+"+str(insertpt)+"c"
-
if (event.state&1) == 0:
- # shift not pressed
+ # shift was not pressed
self.text.tag_remove("sel", "1.0", "end")
else:
if not self.text.index("sel.first"):
- self.text.mark_set("anchor","insert")
-
+ self.text.mark_set("my_anchor", "insert") # there was no previous selection
+ else:
+ if self.text.compare(self.text.index("sel.first"), "<", self.text.index("insert")):
+ self.text.mark_set("my_anchor", "sel.first") # extend back
+ else:
+ self.text.mark_set("my_anchor", "sel.last") # extend forward
first = self.text.index(dest)
- last = self.text.index("anchor")
-
+ last = self.text.index("my_anchor")
if self.text.compare(first,">",last):
first,last = last,first
-
self.text.tag_remove("sel", "1.0", "end")
self.text.tag_add("sel", first, last)
-
self.text.mark_set("insert", dest)
self.text.see("insert")
return "break"
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 24629c1..6a031e1 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -1,3 +1,14 @@
+What's New in IDLE 3.1.4?
+=========================
+
+*Release date: XX-XXX-XX*
+
+- <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.
+
+
+
What's New in IDLE 3.1b1?
=========================
diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py
index 114a1c7..dbdb325 100644
--- a/Lib/msilib/__init__.py
+++ b/Lib/msilib/__init__.py
@@ -173,11 +173,10 @@ def add_tables(db, module):
add_data(db, table, getattr(module, table))
def make_id(str):
- #str = str.replace(".", "_") # colons are allowed
- str = str.replace(" ", "_")
- str = str.replace("-", "_")
- if str[0] in string.digits:
- str = "_"+str
+ identifier_chars = string.ascii_letters + string.digits + "._"
+ str = "".join([c if c in identifier_chars else "_" for c in str])
+ if str[0] in (string.digits + "."):
+ str = "_" + str
assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
return str
@@ -285,19 +284,28 @@ class Directory:
[(feature.id, component)])
def make_short(self, file):
+ oldfile = file
+ file = file.replace('+', '_')
+ file = ''.join(c for c in file if not c in ' "/\[]:;=,')
parts = file.split(".")
- if len(parts)>1:
+ if len(parts) > 1:
+ prefix = "".join(parts[:-1]).upper()
suffix = parts[-1].upper()
+ if not prefix:
+ prefix = suffix
+ suffix = None
else:
+ prefix = file.upper()
suffix = None
- prefix = parts[0].upper()
- if len(prefix) <= 8 and (not suffix or len(suffix)<=3):
+ if len(parts) < 3 and len(prefix) <= 8 and file == oldfile and (
+ not suffix or len(suffix) <= 3):
if suffix:
file = prefix+"."+suffix
else:
file = prefix
- assert file not in self.short_names
else:
+ file = None
+ if file is None or file in self.short_names:
prefix = prefix[:6]
if suffix:
suffix = suffix[:3]
diff --git a/Lib/multiprocessing/sharedctypes.py b/Lib/multiprocessing/sharedctypes.py
index e83ce58..1e694da 100644
--- a/Lib/multiprocessing/sharedctypes.py
+++ b/Lib/multiprocessing/sharedctypes.py
@@ -80,7 +80,9 @@ def RawArray(typecode_or_type, size_or_initializer):
type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
if isinstance(size_or_initializer, int):
type_ = type_ * size_or_initializer
- return _new_value(type_)
+ obj = _new_value(type_)
+ ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
+ return obj
else:
type_ = type_ * len(size_or_initializer)
result = _new_value(type_)
diff --git a/Lib/re.py b/Lib/re.py
index 9bd913a..309afef 100644
--- a/Lib/re.py
+++ b/Lib/re.py
@@ -223,8 +223,7 @@ def escape(pattern):
if isinstance(pattern, str):
alphanum = _alphanum_str
s = list(pattern)
- for i in range(len(pattern)):
- c = pattern[i]
+ for i, c in enumerate(pattern):
if c not in alphanum:
if c == "\000":
s[i] = "\\000"
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 9a43f88..dd13c72 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -741,8 +741,6 @@ class TestMaildir(TestMailbox):
self.assertFalse((perms & 0o111)) # Execute bits should all be off.
def test_reread(self):
- # Wait for 2 seconds
- time.sleep(2)
# Initially, the mailbox has not been read and the time is null.
assert getattr(self._box, '_last_read', None) is None
@@ -751,15 +749,21 @@ class TestMaildir(TestMailbox):
self._box._refresh()
assert getattr(self._box, '_last_read', None) is not None
- # Try calling _refresh() again; the modification times shouldn't have
- # changed, so the mailbox should not be re-reading. Re-reading causes
- # the ._toc attribute to be assigned a new dictionary object, so
- # we'll check that the ._toc attribute isn't a different object.
+ # Put the last modified times more than one second into the past
+ # (because mtime has a one second granularity, a refresh is done
+ # unconditionally if called for within the same second, just in case
+ # the mbox has changed).
+ for subdir in ('cur', 'new'):
+ os.utime(os.path.join(self._box._path, subdir),
+ (time.time()-5,)*2)
+
+ # Re-reading causes the ._toc attribute to be assigned a new dictionary
+ # object, so we'll check that the ._toc attribute isn't a different
+ # object.
orig_toc = self._box._toc
def refreshed():
return self._box._toc is not orig_toc
- time.sleep(1) # Wait 1sec to ensure time.time()'s value changes
self._box._refresh()
assert not refreshed()
diff --git a/Lib/test/test_msilib.py b/Lib/test/test_msilib.py
new file mode 100644
index 0000000..ccdaec7
--- /dev/null
+++ b/Lib/test/test_msilib.py
@@ -0,0 +1,46 @@
+""" Test suite for the code in msilib """
+import unittest
+import os
+from test.support import run_unittest, import_module
+msilib = import_module('msilib')
+
+class Test_make_id(unittest.TestCase):
+ #http://msdn.microsoft.com/en-us/library/aa369212(v=vs.85).aspx
+ """The Identifier data type is a text string. Identifiers may contain the
+ ASCII characters A-Z (a-z), digits, underscores (_), or periods (.).
+ However, every identifier must begin with either a letter or an
+ underscore.
+ """
+
+ def test_is_no_change_required(self):
+ self.assertEqual(
+ msilib.make_id("short"), "short")
+ self.assertEqual(
+ msilib.make_id("nochangerequired"), "nochangerequired")
+ self.assertEqual(
+ msilib.make_id("one.dot"), "one.dot")
+ self.assertEqual(
+ msilib.make_id("_"), "_")
+ self.assertEqual(
+ msilib.make_id("a"), "a")
+ #self.assertEqual(
+ # msilib.make_id(""), "")
+
+ def test_invalid_first_char(self):
+ self.assertEqual(
+ msilib.make_id("9.short"), "_9.short")
+ self.assertEqual(
+ msilib.make_id(".short"), "_.short")
+
+ def test_invalid_any_char(self):
+ self.assertEqual(
+ msilib.make_id(".s\x82ort"), "_.s_ort")
+ self.assertEqual (
+ msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt")
+
+
+def test_main():
+ run_unittest(__name__)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py
index f4031de..1136ab2 100644
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -914,6 +914,21 @@ class _TestArray(BaseTestCase):
self.assertEqual(list(arr[:]), seq)
@unittest.skipIf(c_int is None, "requires _ctypes")
+ def test_array_from_size(self):
+ size = 10
+ # Test for zeroing (see issue #11675).
+ # The repetition below strengthens the test by increasing the chances
+ # of previously allocated non-zero memory being used for the new array
+ # on the 2nd and 3rd loops.
+ for _ in range(3):
+ arr = self.Array('i', size)
+ self.assertEqual(len(arr), size)
+ self.assertEqual(list(arr), [0] * size)
+ arr[:] = range(10)
+ self.assertEqual(list(arr), list(range(10)))
+ del arr
+
+ @unittest.skipIf(c_int is None, "requires _ctypes")
def test_rawarray(self):
self.test_array(raw=True)
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 268d66d..5ad44dd 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -1,7 +1,10 @@
from test.support import verbose, run_unittest
import re
from re import Scanner
-import sys, os, traceback
+import os
+import sys
+import string
+import traceback
from weakref import proxy
# Misc tests from Tim Peters' re.doc
@@ -411,31 +414,62 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.search("\s(b)", " b").group(1), "b")
self.assertEqual(re.search("a\s", "a ").group(0), "a ")
+ def assertMatch(self, pattern, text, match=None, span=None,
+ matcher=re.match):
+ if match is None and span is None:
+ # the pattern matches the whole text
+ match = text
+ span = (0, len(text))
+ elif match is None or span is None:
+ raise ValueError('If match is not None, span should be specified '
+ '(and vice versa).')
+ m = matcher(pattern, text)
+ self.assertTrue(m)
+ self.assertEqual(m.group(), match)
+ self.assertEqual(m.span(), span)
+
def test_re_escape(self):
- p=""
- self.assertEqual(re.escape(p), p)
- for i in range(0, 256):
- p = p + chr(i)
- self.assertEqual(re.match(re.escape(chr(i)), chr(i)) is not None,
- True)
- self.assertEqual(re.match(re.escape(chr(i)), chr(i)).span(), (0,1))
-
- pat=re.compile(re.escape(p))
- self.assertEqual(pat.match(p) is not None, True)
- self.assertEqual(pat.match(p).span(), (0,256))
+ alnum_chars = string.ascii_letters + string.digits
+ p = ''.join(chr(i) for i in range(256))
+ for c in p:
+ if c in alnum_chars:
+ self.assertEqual(re.escape(c), c)
+ elif c == '\x00':
+ self.assertEqual(re.escape(c), '\\000')
+ else:
+ self.assertEqual(re.escape(c), '\\' + c)
+ self.assertMatch(re.escape(c), c)
+ self.assertMatch(re.escape(p), p)
def test_re_escape_byte(self):
- p=b""
- self.assertEqual(re.escape(p), p)
- for i in range(0, 256):
+ alnum_chars = (string.ascii_letters + string.digits).encode('ascii')
+ p = bytes(range(256))
+ for i in p:
b = bytes([i])
- p += b
- self.assertEqual(re.match(re.escape(b), b) is not None, True)
- self.assertEqual(re.match(re.escape(b), b).span(), (0,1))
-
- pat=re.compile(re.escape(p))
- self.assertEqual(pat.match(p) is not None, True)
- self.assertEqual(pat.match(p).span(), (0,256))
+ if b in alnum_chars:
+ self.assertEqual(re.escape(b), b)
+ elif i == 0:
+ self.assertEqual(re.escape(b), b'\\000')
+ else:
+ self.assertEqual(re.escape(b), b'\\' + b)
+ self.assertMatch(re.escape(b), b)
+ self.assertMatch(re.escape(p), p)
+
+ def test_re_escape_non_ascii(self):
+ s = 'xxx\u2620\u2620\u2620xxx'
+ s_escaped = re.escape(s)
+ self.assertEqual(s_escaped, 'xxx\\\u2620\\\u2620\\\u2620xxx')
+ self.assertMatch(s_escaped, s)
+ self.assertMatch('.%s+.' % re.escape('\u2620'), s,
+ 'x\u2620\u2620\u2620x', (2, 7), re.search)
+
+ def test_re_escape_non_ascii_bytes(self):
+ b = 'y\u2620y\u2620y'.encode('utf-8')
+ b_escaped = re.escape(b)
+ self.assertEqual(b_escaped, b'y\\\xe2\\\x98\\\xa0y\\\xe2\\\x98\\\xa0y')
+ self.assertMatch(b_escaped, b)
+ res = re.findall(re.escape('\u2620'.encode('utf-8')), b)
+ self.assertEqual(len(res), 2)
def pickle_test(self, pickle):
oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)')
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 410849f..837bdb5 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -874,6 +874,7 @@ class ProcessTestCase(BaseTestCase):
stdout=subprocess.PIPE,
bufsize=0)
f = p.stdout
+ self.addCleanup(f.close)
try:
self.assertEqual(f.read(4), b"appl")
self.assertIn(f, select.select([f], [], [], 0.0)[0])
diff --git a/Lib/test/test_xdrlib.py b/Lib/test/test_xdrlib.py
index 073448c..6004c9f 100644
--- a/Lib/test/test_xdrlib.py
+++ b/Lib/test/test_xdrlib.py
@@ -12,6 +12,7 @@ class XDRTest(unittest.TestCase):
a = [b'what', b'is', b'hapnin', b'doctor']
p.pack_int(42)
+ p.pack_int(-17)
p.pack_uint(9)
p.pack_bool(True)
p.pack_bool(False)
@@ -29,6 +30,7 @@ class XDRTest(unittest.TestCase):
self.assertEqual(up.get_position(), 0)
self.assertEqual(up.unpack_int(), 42)
+ self.assertEqual(up.unpack_int(), -17)
self.assertEqual(up.unpack_uint(), 9)
self.assertTrue(up.unpack_bool() is True)
diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py
index b293e06..4e48677 100644
--- a/Lib/xdrlib.py
+++ b/Lib/xdrlib.py
@@ -50,7 +50,9 @@ class Packer:
def pack_uint(self, x):
self.__buf.write(struct.pack('>L', x))
- pack_int = pack_uint
+ def pack_int(self, x):
+ self.__buf.write(struct.pack('>l', x))
+
pack_enum = pack_int
def pack_bool(self, x):
diff --git a/Misc/ACKS b/Misc/ACKS
index 99554da..f5fa82f 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -303,6 +303,7 @@ Eddy De Greef
Duncan Grisby
Fabian Groffen
Dag Gruneau
+Filip Gruszczyński
Michael Guravage
Lars Gustäbel
Thomas Güttler
@@ -325,6 +326,7 @@ Jason Harper
Larry Hastings
Shane Hathaway
Rycharde Hawkes
+Ben Hayden
Jochen Hayek
Christian Heimes
Thomas Heller
@@ -529,6 +531,7 @@ Chris McDonough
Greg McFarlane
Alan McIntyre
Michael McLay
+Mark Mc Mahon
Gordon McMillan
Caolan McNamara
Andrew McNamara
diff --git a/Misc/NEWS b/Misc/NEWS
index 91d9ce6..a03477a 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -44,6 +44,20 @@ Core and Builtins
Library
-------
+- Issue #11696: Fix ID generation in msilib.
+
+- Issue #9696: Fix exception incorrectly raised by xdrlib.Packer.pack_int when
+ trying to pack a negative (in-range) integer.
+
+- Issue #11675: multiprocessing.[Raw]Array objects created from an integer size
+ are now zeroed on creation. This matches the behaviour specified by the
+ documentation.
+
+- Issue #7639: Fix short file name generation in bdist_msi.
+
+- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459.
+ Patch by Ben Hayden.
+
- Issue #11662: Make urllib and urllib2 ignore redirections if the
scheme is not HTTP, HTTPS or FTP (CVE-2011-1521).
@@ -234,6 +248,9 @@ Library
Extensions
----------
+- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set
+ to an instance of the class.
+
- Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
Build
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 04b07cc..bdf7ab4 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -587,7 +587,10 @@ static PyObject *
CDataType_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
- if (1 == PyObject_IsInstance(value, type)) {
+ int res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -600,10 +603,14 @@ CDataType_from_param(PyObject *type, PyObject *value)
/* If we got a PyCArgObject, we must check if the object packed in it
is an instance of the type's dict->proto */
- if(dict && ob
- && PyObject_IsInstance(ob, dict->proto)) {
- Py_INCREF(value);
- return value;
+ if(dict && ob) {
+ res = PyObject_IsInstance(ob, dict->proto);
+ if (res == -1)
+ return NULL;
+ if (res) {
+ Py_INCREF(value);
+ return value;
+ }
}
ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
PyErr_Format(PyExc_TypeError,
@@ -953,8 +960,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
Py_INCREF(value); /* _byref steals a refcount */
return _byref(value);
case -1:
- PyErr_Clear();
- break;
+ return NULL;
default:
break;
}
@@ -1445,6 +1451,7 @@ static PyObject *
c_wchar_p_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
+ int res;
if (value == Py_None) {
Py_INCREF(Py_None);
return Py_None;
@@ -1465,7 +1472,10 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
}
return (PyObject *)parg;
}
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -1506,6 +1516,7 @@ static PyObject *
c_char_p_from_param(PyObject *type, PyObject *value)
{
PyObject *as_parameter;
+ int res;
if (value == Py_None) {
Py_INCREF(Py_None);
return Py_None;
@@ -1526,7 +1537,10 @@ c_char_p_from_param(PyObject *type, PyObject *value)
}
return (PyObject *)parg;
}
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -1568,6 +1582,7 @@ c_void_p_from_param(PyObject *type, PyObject *value)
{
StgDictObject *stgd;
PyObject *as_parameter;
+ int res;
/* None */
if (value == Py_None) {
@@ -1645,7 +1660,10 @@ c_void_p_from_param(PyObject *type, PyObject *value)
return (PyObject *)parg;
}
/* c_void_p instance (or subclass) */
- if (PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
/* c_void_p instances */
Py_INCREF(value);
return value;
@@ -2004,10 +2022,14 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
PyCArgObject *parg;
struct fielddesc *fd;
PyObject *as_parameter;
+ int res;
/* If the value is already an instance of the requested type,
we can use it as is */
- if (1 == PyObject_IsInstance(value, type)) {
+ res = PyObject_IsInstance(value, type);
+ if (res == -1)
+ return NULL;
+ if (res) {
Py_INCREF(value);
return value;
}
@@ -2036,7 +2058,12 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
if (as_parameter) {
+ if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
+ Py_DECREF(as_parameter);
+ return NULL;
+ }
value = PyCSimpleType_from_param(type, as_parameter);
+ Py_LeaveRecursiveCall();
Py_DECREF(as_parameter);
return value;
}
@@ -2728,6 +2755,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Py_ssize_t size, char *ptr)
{
CDataObject *src;
+ int err;
if (setfunc)
return setfunc(ptr, value, size);
@@ -2768,7 +2796,10 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
}
src = (CDataObject *)value;
- if (PyObject_IsInstance(value, type)) {
+ err = PyObject_IsInstance(value, type);
+ if (err == -1)
+ return NULL;
+ if (err) {
memcpy(ptr,
src->b_ptr,
size);
@@ -4763,14 +4794,17 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict); /* Cannot be NULL fr pointer instances */
assert(stgdict->proto);
- if (!CDataObject_Check(value)
- || 0 == PyObject_IsInstance(value, stgdict->proto)) {
- /* XXX PyObject_IsInstance could return -1! */
- PyErr_Format(PyExc_TypeError,
- "expected %s instead of %s",
- ((PyTypeObject *)(stgdict->proto))->tp_name,
- Py_TYPE(value)->tp_name);
- return -1;
+ if (!CDataObject_Check(value)) {
+ int res = PyObject_IsInstance(value, stgdict->proto);
+ if (res == -1)
+ return -1;
+ if (!res) {
+ PyErr_Format(PyExc_TypeError,
+ "expected %s instead of %s",
+ ((PyTypeObject *)(stgdict->proto))->tp_name,
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
}
dst = (CDataObject *)value;
diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c
index ac51881..7069b6e 100644
--- a/Modules/getbuildinfo.c
+++ b/Modules/getbuildinfo.c
@@ -42,9 +42,9 @@
const char *
Py_GetBuildInfo(void)
{
- static char buildinfo[50 + sizeof HGVERSION +
- ((sizeof HGTAG > sizeof HGBRANCH) ?
- sizeof HGTAG : sizeof HGBRANCH)];
+ static char buildinfo[50 + sizeof(HGVERSION) +
+ ((sizeof(HGTAG) > sizeof(HGBRANCH)) ?
+ sizeof(HGTAG) : sizeof(HGBRANCH))];
const char *revision = _Py_hgversion();
const char *sep = *revision ? ":" : "";
const char *hgid = _Py_hgidentifier();