summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2016-06-27 02:53:18 (GMT)
committerLarry Hastings <larry@hastings.org>2016-06-27 02:53:18 (GMT)
commit1b329e791ae3a3a2989f05e8c2019b67b4e1a7df (patch)
tree91e137c00f35f21a2c17b385f9746492b8347558 /Lib
parent9bb200545970bb920c83124658cb89c7d295166d (diff)
parent1e957d145fa1fc05ca1fbb9f135ab162c939ae14 (diff)
downloadcpython-1b329e791ae3a3a2989f05e8c2019b67b4e1a7df.zip
cpython-1b329e791ae3a3a2989f05e8c2019b67b4e1a7df.tar.gz
cpython-1b329e791ae3a3a2989f05e8c2019b67b4e1a7df.tar.bz2
Merge.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/contextlib.py3
-rw-r--r--Lib/ctypes/test/test_find.py7
-rw-r--r--Lib/ctypes/test/test_structures.py6
-rw-r--r--Lib/ctypes/util.py131
-rw-r--r--Lib/curses/ascii.py6
-rw-r--r--Lib/distutils/_msvccompiler.py6
-rw-r--r--Lib/distutils/command/upload.py2
-rw-r--r--Lib/distutils/tests/test_config.py28
-rw-r--r--Lib/distutils/tests/test_msvccompiler.py18
-rw-r--r--Lib/distutils/tests/test_register.py4
-rw-r--r--Lib/distutils/tests/test_sdist.py4
-rw-r--r--Lib/distutils/tests/test_upload.py7
-rw-r--r--Lib/idlelib/NEWS.txt13
-rw-r--r--Lib/idlelib/aboutDialog.py2
-rw-r--r--Lib/idlelib/configDialog.py8
-rw-r--r--Lib/idlelib/idle_test/test_help_about.py52
-rw-r--r--Lib/idlelib/textView.py4
-rw-r--r--Lib/importlib/_bootstrap_external.py3
-rw-r--r--Lib/importlib/util.py2
-rw-r--r--Lib/lib2to3/tests/test_refactor.py5
-rwxr-xr-xLib/pydoc.py5
-rw-r--r--Lib/sqlite3/test/dbapi.py205
-rw-r--r--Lib/sqlite3/test/hooks.py38
-rw-r--r--Lib/sqlite3/test/regression.py37
-rw-r--r--Lib/sqlite3/test/transactions.py33
-rw-r--r--Lib/sqlite3/test/types.py20
-rw-r--r--Lib/sqlite3/test/userfunctions.py62
-rw-r--r--Lib/test/support/__init__.py3
-rw-r--r--Lib/test/support/script_helper.py4
-rw-r--r--Lib/test/test_asyncio/test_base_events.py8
-rw-r--r--Lib/test/test_compile.py7
-rw-r--r--Lib/test/test_contextlib.py34
-rw-r--r--Lib/test/test_coroutines.py2
-rw-r--r--Lib/test/test_curses.py54
-rw-r--r--Lib/test/test_decimal.py5
-rw-r--r--Lib/test/test_doctest.py24
-rw-r--r--Lib/test/test_extcall.py4
-rw-r--r--Lib/test/test_functools.py61
-rw-r--r--Lib/test/test_importlib/test_lazy.py16
-rw-r--r--Lib/test/test_parser.py16
-rw-r--r--Lib/test/test_pydoc.py2
-rw-r--r--Lib/test/test_readline.py161
-rw-r--r--Lib/test/test_symtable.py6
-rw-r--r--Lib/test/test_unpack_ex.py5
-rw-r--r--Lib/test/test_xml_etree.py8
-rw-r--r--Lib/test/test_zipimport.py15
-rw-r--r--Lib/tkinter/__init__.py19
-rw-r--r--Lib/tkinter/test/test_tkinter/test_variables.py51
-rw-r--r--Lib/tkinter/test/test_ttk/test_widgets.py51
-rw-r--r--Lib/tkinter/ttk.py4
-rw-r--r--Lib/turtle.py18
-rw-r--r--Lib/unittest/mock.py1
52 files changed, 865 insertions, 425 deletions
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index 5377987..d44edd6 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -82,6 +82,9 @@ class _GeneratorContextManager(ContextDecorator):
# raised inside the "with" statement from being suppressed.
return exc is not value
except RuntimeError as exc:
+ # Don't re-raise the passed in exception. (issue27112)
+ if exc is value:
+ return False
# Likewise, avoid suppressing if a StopIteration exception
# was passed to throw() and later wrapped into a RuntimeError
# (see PEP 479).
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
index e6bc19d..20c5337 100644
--- a/Lib/ctypes/test/test_find.py
+++ b/Lib/ctypes/test/test_find.py
@@ -1,5 +1,5 @@
import unittest
-import os
+import os, os.path
import sys
import test.support
from ctypes import *
@@ -64,6 +64,11 @@ class Test_OpenGL_libs(unittest.TestCase):
self.skipTest('lib_gle not available')
self.gle.gleGetJoinStyle
+ def test_shell_injection(self):
+ result = find_library('; echo Hello shell > ' + test.support.TESTFN)
+ self.assertFalse(os.path.lexists(test.support.TESTFN))
+ self.assertIsNone(result)
+
# On platforms where the default shared library suffix is '.so',
# at least some libraries can be loaded as attributes of the cdll
# object, since ctypes now tries loading the lib again
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index 84d456c..d998c27 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -227,10 +227,10 @@ class StructureTestCase(unittest.TestCase):
def test_conflicting_initializers(self):
class POINT(Structure):
- _fields_ = [("x", c_int), ("y", c_int)]
+ _fields_ = [("phi", c_float), ("rho", c_float)]
# conflicting positional and keyword args
- self.assertRaises(TypeError, POINT, 2, 3, x=4)
- self.assertRaises(TypeError, POINT, 2, 3, y=4)
+ self.assertRaisesRegex(TypeError, "phi", POINT, 2, 3, phi=4)
+ self.assertRaisesRegex(TypeError, "rho", POINT, 2, 3, rho=4)
# too many initializers
self.assertRaises(TypeError, POINT, 2, 3, 4)
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 8ff4aff..7684eab 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -1,6 +1,7 @@
-import sys, os
-import contextlib
+import os
+import shutil
import subprocess
+import sys
# find_library(name) returns the pathname of a library, or None.
if os.name == "nt":
@@ -94,28 +95,46 @@ elif os.name == "posix":
import re, tempfile
def _findLib_gcc(name):
- expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
- fdout, ccout = tempfile.mkstemp()
- os.close(fdout)
- cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \
- 'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
+ # Run GCC's linker with the -t (aka --trace) option and examine the
+ # library name it prints out. The GCC command will fail because we
+ # haven't supplied a proper program with main(), but that does not
+ # matter.
+ expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name))
+
+ c_compiler = shutil.which('gcc')
+ if not c_compiler:
+ c_compiler = shutil.which('cc')
+ if not c_compiler:
+ # No C compiler available, give up
+ return None
+
+ temp = tempfile.NamedTemporaryFile()
try:
- f = os.popen(cmd)
+ args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name]
+
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+ env['LANG'] = 'C'
try:
- trace = f.read()
- finally:
- rv = f.close()
+ proc = subprocess.Popen(args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ env=env)
+ except OSError: # E.g. bad executable
+ return None
+ with proc:
+ trace = proc.stdout.read()
finally:
try:
- os.unlink(ccout)
+ temp.close()
except FileNotFoundError:
+ # Raised if the file was already removed, which is the normal
+ # behaviour of GCC if linking fails
pass
- if rv == 10:
- raise OSError('gcc or cc command not found')
res = re.search(expr, trace)
if not res:
return None
- return res.group(0)
+ return os.fsdecode(res.group(0))
if sys.platform == "sunos5":
@@ -123,55 +142,75 @@ elif os.name == "posix":
def _get_soname(f):
if not f:
return None
- cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f
- with contextlib.closing(os.popen(cmd)) as f:
- data = f.read()
- res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data)
+
+ try:
+ proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL)
+ except OSError: # E.g. command not found
+ return None
+ with proc:
+ data = proc.stdout.read()
+ res = re.search(br'\[.*\]\sSONAME\s+([^\s]+)', data)
if not res:
return None
- return res.group(1)
+ return os.fsdecode(res.group(1))
else:
def _get_soname(f):
# assuming GNU binutils / ELF
if not f:
return None
- cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \
- "objdump -p -j .dynamic 2>/dev/null " + f
- f = os.popen(cmd)
+ objdump = shutil.which('objdump')
+ if not objdump:
+ # objdump is not available, give up
+ return None
+
try:
- dump = f.read()
- finally:
- rv = f.close()
- if rv == 10:
- raise OSError('objdump command not found')
- res = re.search(r'\sSONAME\s+([^\s]+)', dump)
+ proc = subprocess.Popen((objdump, '-p', '-j', '.dynamic', f),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL)
+ except OSError: # E.g. bad executable
+ return None
+ with proc:
+ dump = proc.stdout.read()
+ res = re.search(br'\sSONAME\s+([^\s]+)', dump)
if not res:
return None
- return res.group(1)
+ return os.fsdecode(res.group(1))
if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):
def _num_version(libname):
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
- parts = libname.split(".")
+ parts = libname.split(b".")
nums = []
try:
while parts:
nums.insert(0, int(parts.pop()))
except ValueError:
pass
- return nums or [ sys.maxsize ]
+ return nums or [sys.maxsize]
def find_library(name):
ename = re.escape(name)
expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
- with contextlib.closing(os.popen('/sbin/ldconfig -r 2>/dev/null')) as f:
- data = f.read()
+ expr = os.fsencode(expr)
+
+ try:
+ proc = subprocess.Popen(('/sbin/ldconfig', '-r'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL)
+ except OSError: # E.g. command not found
+ data = b''
+ else:
+ with proc:
+ data = proc.stdout.read()
+
res = re.findall(expr, data)
if not res:
return _get_soname(_findLib_gcc(name))
res.sort(key=_num_version)
- return res[-1]
+ return os.fsdecode(res[-1])
elif sys.platform == "sunos5":
@@ -179,17 +218,27 @@ elif os.name == "posix":
if not os.path.exists('/usr/bin/crle'):
return None
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+
if is64:
- cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null'
+ args = ('/usr/bin/crle', '-64')
else:
- cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null'
+ args = ('/usr/bin/crle',)
paths = None
- with contextlib.closing(os.popen(cmd)) as f:
- for line in f.readlines():
+ try:
+ proc = subprocess.Popen(args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL,
+ env=env)
+ except OSError: # E.g. bad executable
+ return None
+ with proc:
+ for line in proc.stdout:
line = line.strip()
- if line.startswith('Default Library Path (ELF):'):
- paths = line.split()[4]
+ if line.startswith(b'Default Library Path (ELF):'):
+ paths = os.fsdecode(line).split()[4]
if not paths:
return None
diff --git a/Lib/curses/ascii.py b/Lib/curses/ascii.py
index 800fd8b..6a466e0 100644
--- a/Lib/curses/ascii.py
+++ b/Lib/curses/ascii.py
@@ -54,13 +54,13 @@ def _ctoi(c):
def isalnum(c): return isalpha(c) or isdigit(c)
def isalpha(c): return isupper(c) or islower(c)
def isascii(c): return _ctoi(c) <= 127 # ?
-def isblank(c): return _ctoi(c) in (8,32)
-def iscntrl(c): return _ctoi(c) <= 31
+def isblank(c): return _ctoi(c) in (9, 32)
+def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127
def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126
-def ispunct(c): return _ctoi(c) != 32 and not isalnum(c)
+def ispunct(c): return isgraph(c) and not isalnum(c)
def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32)
def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
def isxdigit(c): return isdigit(c) or \
diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py
index d0ba7d6..b120273 100644
--- a/Lib/distutils/_msvccompiler.py
+++ b/Lib/distutils/_msvccompiler.py
@@ -86,11 +86,9 @@ def _get_vc_env(plat_spec):
try:
out = subprocess.check_output(
- '"{}" {} && set'.format(vcvarsall, plat_spec),
- shell=True,
+ 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec),
stderr=subprocess.STDOUT,
- universal_newlines=True,
- )
+ ).decode('utf-16le', errors='replace')
except subprocess.CalledProcessError as exc:
log.error(exc.output)
raise DistutilsPlatformError("Error executing {}"
diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py
index 0afcbf2..1fd574a 100644
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -91,7 +91,7 @@ class upload(PyPIRCCommand):
data = {
# action
':action': 'file_upload',
- 'protcol_version': '1',
+ 'protocol_version': '1',
# identify release
'name': meta.get_name(),
diff --git a/Lib/distutils/tests/test_config.py b/Lib/distutils/tests/test_config.py
index 4de825a..3dd92d6 100644
--- a/Lib/distutils/tests/test_config.py
+++ b/Lib/distutils/tests/test_config.py
@@ -18,6 +18,7 @@ PYPIRC = """\
index-servers =
server1
server2
+ server3
[server1]
username:me
@@ -28,6 +29,10 @@ username:meagain
password: secret
realm:acme
repository:http://another.pypi/
+
+[server3]
+username:cbiggles
+password:yh^%#rest-of-my-password
"""
PYPIRC_OLD = """\
@@ -47,14 +52,14 @@ password:xxx
"""
-class PyPIRCCommandTestCase(support.TempdirManager,
+class BasePyPIRCCommandTestCase(support.TempdirManager,
support.LoggingSilencer,
support.EnvironGuard,
unittest.TestCase):
def setUp(self):
"""Patches the environment."""
- super(PyPIRCCommandTestCase, self).setUp()
+ super(BasePyPIRCCommandTestCase, self).setUp()
self.tmp_dir = self.mkdtemp()
os.environ['HOME'] = self.tmp_dir
self.rc = os.path.join(self.tmp_dir, '.pypirc')
@@ -73,7 +78,10 @@ class PyPIRCCommandTestCase(support.TempdirManager,
def tearDown(self):
"""Removes the patch."""
set_threshold(self.old_threshold)
- super(PyPIRCCommandTestCase, self).tearDown()
+ super(BasePyPIRCCommandTestCase, self).tearDown()
+
+
+class PyPIRCCommandTestCase(BasePyPIRCCommandTestCase):
def test_server_registration(self):
# This test makes sure PyPIRCCommand knows how to:
@@ -113,6 +121,20 @@ class PyPIRCCommandTestCase(support.TempdirManager,
finally:
f.close()
+ def test_config_interpolation(self):
+ # using the % character in .pypirc should not raise an error (#20120)
+ self.write_file(self.rc, PYPIRC)
+ cmd = self._cmd(self.dist)
+ cmd.repository = 'server3'
+ config = cmd._read_pypirc()
+
+ config = list(sorted(config.items()))
+ waited = [('password', 'yh^%#rest-of-my-password'), ('realm', 'pypi'),
+ ('repository', 'https://pypi.python.org/pypi'),
+ ('server', 'server3'), ('username', 'cbiggles')]
+ self.assertEqual(config, waited)
+
+
def test_suite():
return unittest.makeSuite(PyPIRCCommandTestCase)
diff --git a/Lib/distutils/tests/test_msvccompiler.py b/Lib/distutils/tests/test_msvccompiler.py
index c4d911f..4dc2488 100644
--- a/Lib/distutils/tests/test_msvccompiler.py
+++ b/Lib/distutils/tests/test_msvccompiler.py
@@ -83,6 +83,24 @@ class msvccompilerTestCase(support.TempdirManager,
self.assertFalse(os.path.isfile(os.path.join(
tempdir, os.path.basename(dll))))
+ def test_get_vc_env_unicode(self):
+ import distutils._msvccompiler as _msvccompiler
+
+ test_var = 'ṰḖṤṪ┅ṼẨṜ'
+ test_value = '₃⁴₅'
+
+ # Ensure we don't early exit from _get_vc_env
+ old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None)
+ os.environ[test_var] = test_value
+ try:
+ env = _msvccompiler._get_vc_env('x86')
+ self.assertIn(test_var.lower(), env)
+ self.assertEqual(test_value, env[test_var.lower()])
+ finally:
+ os.environ.pop(test_var)
+ if old_distutils_use_sdk:
+ os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk
+
def test_suite():
return unittest.makeSuite(msvccompilerTestCase)
diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py
index 01acf23..e68b0af 100644
--- a/Lib/distutils/tests/test_register.py
+++ b/Lib/distutils/tests/test_register.py
@@ -12,7 +12,7 @@ from distutils.command.register import register
from distutils.errors import DistutilsSetupError
from distutils.log import INFO
-from distutils.tests.test_config import PyPIRCCommandTestCase
+from distutils.tests.test_config import BasePyPIRCCommandTestCase
try:
import docutils
@@ -72,7 +72,7 @@ class FakeOpener(object):
}.get(name.lower(), default)
-class RegisterTestCase(PyPIRCCommandTestCase):
+class RegisterTestCase(BasePyPIRCCommandTestCase):
def setUp(self):
super(RegisterTestCase, self).setUp()
diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py
index 5a04e0d..5444b81 100644
--- a/Lib/distutils/tests/test_sdist.py
+++ b/Lib/distutils/tests/test_sdist.py
@@ -23,7 +23,7 @@ except ImportError:
from distutils.command.sdist import sdist, show_formats
from distutils.core import Distribution
-from distutils.tests.test_config import PyPIRCCommandTestCase
+from distutils.tests.test_config import BasePyPIRCCommandTestCase
from distutils.errors import DistutilsOptionError
from distutils.spawn import find_executable
from distutils.log import WARN
@@ -52,7 +52,7 @@ somecode%(sep)sdoc.dat
somecode%(sep)sdoc.txt
"""
-class SDistTestCase(PyPIRCCommandTestCase):
+class SDistTestCase(BasePyPIRCCommandTestCase):
def setUp(self):
# PyPIRCCommandTestCase creates a temp dir already
diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py
index 964aac7..e836cc4 100644
--- a/Lib/distutils/tests/test_upload.py
+++ b/Lib/distutils/tests/test_upload.py
@@ -12,7 +12,7 @@ from distutils.core import Distribution
from distutils.errors import DistutilsError
from distutils.log import ERROR, INFO
-from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
+from distutils.tests.test_config import PYPIRC, BasePyPIRCCommandTestCase
PYPIRC_LONG_PASSWORD = """\
[distutils]
@@ -66,7 +66,7 @@ class FakeOpen(object):
return self.code
-class uploadTestCase(PyPIRCCommandTestCase):
+class uploadTestCase(BasePyPIRCCommandTestCase):
def setUp(self):
super(uploadTestCase, self).setUp()
@@ -130,13 +130,14 @@ class uploadTestCase(PyPIRCCommandTestCase):
# what did we send ?
headers = dict(self.last_open.req.headers)
- self.assertEqual(headers['Content-length'], '2161')
+ self.assertEqual(headers['Content-length'], '2162')
content_type = headers['Content-type']
self.assertTrue(content_type.startswith('multipart/form-data'))
self.assertEqual(self.last_open.req.get_method(), 'POST')
expected_url = 'https://pypi.python.org/pypi'
self.assertEqual(self.last_open.req.get_full_url(), expected_url)
self.assertTrue(b'xxx' in self.last_open.req.data)
+ self.assertIn(b'protocol_version', self.last_open.req.data)
# The PyPI response body was echoed
results = self.get_logs(INFO)
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 00d5005..6ef2aa5 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -1,6 +1,17 @@
+What's New in IDLE 3.5.3?
+=========================
+*Release date: 2017-01-01?*
+
+- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names.
+
+- Issue #27245: IDLE: Cleanly delete custom themes and key bindings.
+ Previously, when IDLE was started from a console or by import, a cascade
+ of warnings was emitted. Patch by Serhiy Storchaka.
+
+
What's New in IDLE 3.5.2?
=========================
-*Release date: 2016-06-30?*
+*Release date: 2016-06-26*
- Issue #5124: Paste with text selected now replaces the selection on X11.
This matches how paste works on Windows, Mac, most modern Linux apps,
diff --git a/Lib/idlelib/aboutDialog.py b/Lib/idlelib/aboutDialog.py
index 0457c43..a8f75d2 100644
--- a/Lib/idlelib/aboutDialog.py
+++ b/Lib/idlelib/aboutDialog.py
@@ -145,5 +145,7 @@ class AboutDialog(Toplevel):
self.destroy()
if __name__ == '__main__':
+ import unittest
+ unittest.main('idlelib.idle_test.test_helpabout', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(AboutDialog)
diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py
index b702253..5f5bd36 100644
--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -751,6 +751,7 @@ class ConfigDialog(Toplevel):
if not tkMessageBox.askyesno(
'Delete Key Set', delmsg % keySetName, parent=self):
return
+ self.DeactivateCurrentConfig()
#remove key set from config
idleConf.userCfg['keys'].remove_section(keySetName)
if keySetName in self.changedItems['keys']:
@@ -769,7 +770,8 @@ class ConfigDialog(Toplevel):
self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
#user can't back out of these changes, they must be applied now
- self.Apply()
+ self.SaveAllChangedConfigs()
+ self.ActivateConfigChanges()
self.SetKeysType()
def DeleteCustomTheme(self):
@@ -778,6 +780,7 @@ class ConfigDialog(Toplevel):
if not tkMessageBox.askyesno(
'Delete Theme', delmsg % themeName, parent=self):
return
+ self.DeactivateCurrentConfig()
#remove theme from config
idleConf.userCfg['highlight'].remove_section(themeName)
if themeName in self.changedItems['highlight']:
@@ -796,7 +799,8 @@ class ConfigDialog(Toplevel):
self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
#user can't back out of these changes, they must be applied now
- self.Apply()
+ self.SaveAllChangedConfigs()
+ self.ActivateConfigChanges()
self.SetThemeType()
def GetColour(self):
diff --git a/Lib/idlelib/idle_test/test_help_about.py b/Lib/idlelib/idle_test/test_help_about.py
new file mode 100644
index 0000000..d0a0127
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_help_about.py
@@ -0,0 +1,52 @@
+'''Test idlelib.help_about.
+
+Coverage:
+'''
+from idlelib import aboutDialog as help_about
+from idlelib import textView as textview
+from idlelib.idle_test.mock_idle import Func
+from idlelib.idle_test.mock_tk import Mbox
+import unittest
+
+About = help_about.AboutDialog
+class Dummy_about_dialog():
+ # Dummy class for testing file display functions.
+ idle_credits = About.ShowIDLECredits
+ idle_readme = About.ShowIDLEAbout
+ idle_news = About.ShowIDLENEWS
+ # Called by the above
+ display_file_text = About.display_file_text
+
+
+class DisplayFileTest(unittest.TestCase):
+ "Test that .txt files are found and properly decoded."
+ dialog = Dummy_about_dialog()
+
+ @classmethod
+ def setUpClass(cls):
+ cls.orig_mbox = textview.tkMessageBox
+ cls.orig_view = textview.view_text
+ cls.mbox = Mbox()
+ cls.view = Func()
+ textview.tkMessageBox = cls.mbox
+ textview.view_text = cls.view
+ cls.About = Dummy_about_dialog()
+
+ @classmethod
+ def tearDownClass(cls):
+ textview.tkMessageBox = cls.orig_mbox
+ textview.view_text = cls.orig_view
+
+ def test_file_isplay(self):
+ for handler in (self.dialog.idle_credits,
+ self.dialog.idle_readme,
+ self.dialog.idle_news):
+ self.mbox.showerror.message = ''
+ self.view.called = False
+ handler()
+ self.assertEqual(self.mbox.showerror.message, '')
+ self.assertEqual(self.view.called, True)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/Lib/idlelib/textView.py b/Lib/idlelib/textView.py
index 01b2d8f..12ac319 100644
--- a/Lib/idlelib/textView.py
+++ b/Lib/idlelib/textView.py
@@ -76,6 +76,10 @@ def view_file(parent, title, filename, encoding=None, modal=True):
tkMessageBox.showerror(title='File Load Error',
message='Unable to load file %r .' % filename,
parent=parent)
+ except UnicodeDecodeError as err:
+ tkMessageBox.showerror(title='Unicode Decode Error',
+ message=str(err),
+ parent=parent)
else:
return view_text(parent, title, contents, modal)
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 9788828..08ddb2b 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -223,6 +223,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations)
# Python 3.5b2 3340 (fix dictionary display evaluation order #11205)
# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400)
+# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
@@ -231,7 +232,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3351).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 4525b3f..e1fa07a 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -241,7 +241,7 @@ class _LazyModule(types.ModuleType):
if id(self) != id(sys.modules[original_name]):
msg = ('module object for {!r} substituted in sys.modules '
'during a lazy load')
- raise ValueError(msg.format(original_name))
+ raise ValueError(msg.format(original_name))
# Update after loading since that's what would happen in an eager
# loading situation.
self.__dict__.update(attrs_updated)
diff --git a/Lib/lib2to3/tests/test_refactor.py b/Lib/lib2to3/tests/test_refactor.py
index f30c1e8..8563001 100644
--- a/Lib/lib2to3/tests/test_refactor.py
+++ b/Lib/lib2to3/tests/test_refactor.py
@@ -9,6 +9,7 @@ import os
import codecs
import operator
import io
+import re
import tempfile
import shutil
import unittest
@@ -226,8 +227,8 @@ from __future__ import print_function"""
actually_write=False)
# Testing that it logged this message when write=False was passed is
# sufficient to see that it did not bail early after "No changes".
- message_regex = r"Not writing changes to .*%s%s" % (
- os.sep, os.path.basename(test_file))
+ message_regex = r"Not writing changes to .*%s" % \
+ re.escape(os.sep + os.path.basename(test_file))
for message in debug_messages:
if "Not writing changes" in message:
self.assertRegex(message, message_regex)
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 3ca08c9..0d0d0ab 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -28,7 +28,7 @@ to a file named "<name>.html".
Module docs for core modules are assumed to be in
- http://docs.python.org/X.Y/library/
+ https://docs.python.org/X.Y/library/
This can be overridden by setting the PYTHONDOCS environment variable
to a different URL or to a local directory containing the Library
@@ -395,6 +395,7 @@ class Doc:
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
+ basedir = os.path.normcase(basedir)
if (isinstance(object, type(os)) and
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
'marshal', 'posix', 'signal', 'sys',
@@ -402,7 +403,7 @@ class Doc:
(file.startswith(basedir) and
not file.startswith(os.path.join(basedir, 'site-packages')))) and
object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
- if docloc.startswith("http://"):
+ if docloc.startswith(("http://", "https://")):
docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
else:
docloc = os.path.join(docloc, object.__name__.lower() + ".html")
diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py
index 04649fc..ec42eb7 100644
--- a/Lib/sqlite3/test/dbapi.py
+++ b/Lib/sqlite3/test/dbapi.py
@@ -122,11 +122,8 @@ class ConnectionTests(unittest.TestCase):
def CheckFailedOpen(self):
YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
- try:
+ with self.assertRaises(sqlite.OperationalError):
con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
- except sqlite.OperationalError:
- return
- self.fail("should have raised an OperationalError")
def CheckClose(self):
self.cx.close()
@@ -180,6 +177,12 @@ class ConnectionTests(unittest.TestCase):
with self.assertRaises(sqlite.OperationalError):
cx.execute('insert into test(id) values(1)')
+ @unittest.skipIf(sqlite.sqlite_version_info >= (3, 3, 1),
+ 'needs sqlite versions older than 3.3.1')
+ def CheckSameThreadErrorOnOldVersion(self):
+ with self.assertRaises(sqlite.NotSupportedError) as cm:
+ sqlite.connect(':memory:', check_same_thread=False)
+ self.assertEqual(str(cm.exception), 'shared connections not available')
class CursorTests(unittest.TestCase):
def setUp(self):
@@ -196,22 +199,12 @@ class CursorTests(unittest.TestCase):
self.cu.execute("delete from test")
def CheckExecuteIllegalSql(self):
- try:
+ with self.assertRaises(sqlite.OperationalError):
self.cu.execute("select asdf")
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError:
- return
- except:
- self.fail("raised wrong exception")
def CheckExecuteTooMuchSql(self):
- try:
+ with self.assertRaises(sqlite.Warning):
self.cu.execute("select 5+4; select 4+5")
- self.fail("should have raised a Warning")
- except sqlite.Warning:
- return
- except:
- self.fail("raised wrong exception")
def CheckExecuteTooMuchSql2(self):
self.cu.execute("select 5+4; -- foo bar")
@@ -226,13 +219,8 @@ class CursorTests(unittest.TestCase):
""")
def CheckExecuteWrongSqlArg(self):
- try:
+ with self.assertRaises(ValueError):
self.cu.execute(42)
- self.fail("should have raised a ValueError")
- except ValueError:
- return
- except:
- self.fail("raised wrong exception.")
def CheckExecuteArgInt(self):
self.cu.execute("insert into test(id) values (?)", (42,))
@@ -250,29 +238,25 @@ class CursorTests(unittest.TestCase):
row = self.cu.fetchone()
self.assertEqual(row[0], "Hu\x00go")
+ def CheckExecuteNonIterable(self):
+ with self.assertRaises(ValueError) as cm:
+ self.cu.execute("insert into test(id) values (?)", 42)
+ self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
+
def CheckExecuteWrongNoOfArgs1(self):
# too many parameters
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckExecuteWrongNoOfArgs2(self):
# too little parameters
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("insert into test(id) values (?)")
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckExecuteWrongNoOfArgs3(self):
# no parameters, parameters are needed
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("insert into test(id) values (?)")
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckExecuteParamList(self):
self.cu.execute("insert into test(name) values ('foo')")
@@ -311,27 +295,18 @@ class CursorTests(unittest.TestCase):
def CheckExecuteDictMappingTooLittleArgs(self):
self.cu.execute("insert into test(name) values ('foo')")
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckExecuteDictMappingNoArgs(self):
self.cu.execute("insert into test(name) values ('foo')")
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("select name from test where name=:name")
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckExecuteDictMappingUnnamed(self):
self.cu.execute("insert into test(name) values ('foo')")
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.execute("select name from test where name=?", {"name": "foo"})
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
def CheckClose(self):
self.cu.close()
@@ -360,8 +335,7 @@ class CursorTests(unittest.TestCase):
def CheckTotalChanges(self):
self.cu.execute("insert into test(name) values ('foo')")
self.cu.execute("insert into test(name) values ('foo')")
- if self.cx.total_changes < 2:
- self.fail("total changes reported wrong value")
+ self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
# Checks for executemany:
# Sequences are required by the DB-API, iterators
@@ -392,32 +366,16 @@ class CursorTests(unittest.TestCase):
self.cu.executemany("insert into test(income) values (?)", mygen())
def CheckExecuteManyWrongSqlArg(self):
- try:
+ with self.assertRaises(ValueError):
self.cu.executemany(42, [(3,)])
- self.fail("should have raised a ValueError")
- except ValueError:
- return
- except:
- self.fail("raised wrong exception.")
def CheckExecuteManySelect(self):
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
self.cu.executemany("select ?", [(3,)])
- self.fail("should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- return
- except:
- self.fail("raised wrong exception.")
def CheckExecuteManyNotIterable(self):
- try:
+ with self.assertRaises(TypeError):
self.cu.executemany("insert into test(income) values (?)", 42)
- self.fail("should have raised a TypeError")
- except TypeError:
- return
- except Exception as e:
- print("raised", e.__class__)
- self.fail("raised wrong exception.")
def CheckFetchIter(self):
# Optional DB-API extension.
@@ -494,22 +452,15 @@ class CursorTests(unittest.TestCase):
self.assertEqual(self.cu.connection, self.cx)
def CheckWrongCursorCallable(self):
- try:
+ with self.assertRaises(TypeError):
def f(): pass
cur = self.cx.cursor(f)
- self.fail("should have raised a TypeError")
- except TypeError:
- return
- self.fail("should have raised a ValueError")
def CheckCursorWrongClass(self):
class Foo: pass
foo = Foo()
- try:
+ with self.assertRaises(TypeError):
cur = sqlite.Cursor(foo)
- self.fail("should have raised a ValueError")
- except TypeError:
- pass
@unittest.skipUnless(threading, 'This test requires threading.')
class ThreadTests(unittest.TestCase):
@@ -708,22 +659,21 @@ class ExtensionTests(unittest.TestCase):
def CheckScriptSyntaxError(self):
con = sqlite.connect(":memory:")
cur = con.cursor()
- raised = False
- try:
+ with self.assertRaises(sqlite.OperationalError):
cur.executescript("create table test(x); asdf; create table test2(x)")
- except sqlite.OperationalError:
- raised = True
- self.assertEqual(raised, True, "should have raised an exception")
def CheckScriptErrorNormal(self):
con = sqlite.connect(":memory:")
cur = con.cursor()
- raised = False
- try:
+ with self.assertRaises(sqlite.OperationalError):
cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
- except sqlite.OperationalError:
- raised = True
- self.assertEqual(raised, True, "should have raised an exception")
+
+ def CheckCursorExecutescriptAsBytes(self):
+ con = sqlite.connect(":memory:")
+ cur = con.cursor()
+ with self.assertRaises(ValueError) as cm:
+ cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
+ self.assertEqual(str(cm.exception), 'script argument must be unicode.')
def CheckConnectionExecute(self):
con = sqlite.connect(":memory:")
@@ -745,68 +695,37 @@ class ExtensionTests(unittest.TestCase):
self.assertEqual(result, 5, "Basic test of Connection.executescript")
class ClosedConTests(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
def CheckClosedConCursor(self):
con = sqlite.connect(":memory:")
con.close()
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
cur = con.cursor()
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedConCommit(self):
con = sqlite.connect(":memory:")
con.close()
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.commit()
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedConRollback(self):
con = sqlite.connect(":memory:")
con.close()
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.rollback()
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedCurExecute(self):
con = sqlite.connect(":memory:")
cur = con.cursor()
con.close()
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
cur.execute("select 4")
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedCreateFunction(self):
con = sqlite.connect(":memory:")
con.close()
def f(x): return 17
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.create_function("foo", 1, f)
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedCreateAggregate(self):
con = sqlite.connect(":memory:")
@@ -818,57 +737,31 @@ class ClosedConTests(unittest.TestCase):
pass
def finalize(self):
return 17
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.create_aggregate("foo", 1, Agg)
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedSetAuthorizer(self):
con = sqlite.connect(":memory:")
con.close()
def authorizer(*args):
return sqlite.DENY
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.set_authorizer(authorizer)
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedSetProgressCallback(self):
con = sqlite.connect(":memory:")
con.close()
def progress(): pass
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.set_progress_handler(progress, 100)
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
def CheckClosedCall(self):
con = sqlite.connect(":memory:")
con.close()
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con()
- self.fail("Should have raised a ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError")
class ClosedCurTests(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
def CheckClosed(self):
con = sqlite.connect(":memory:")
cur = con.cursor()
@@ -882,15 +775,9 @@ class ClosedCurTests(unittest.TestCase):
else:
params = []
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
method = getattr(cur, method_name)
-
method(*params)
- self.fail("Should have raised a ProgrammingError: method " + method_name)
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("Should have raised a ProgrammingError: " + method_name)
def suite():
module_suite = unittest.makeSuite(ModuleTests, "Check")
diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py
index ede0bec..cafff93 100644
--- a/Lib/sqlite3/test/hooks.py
+++ b/Lib/sqlite3/test/hooks.py
@@ -25,27 +25,16 @@ import unittest
import sqlite3 as sqlite
class CollationTests(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
def CheckCreateCollationNotCallable(self):
con = sqlite.connect(":memory:")
- try:
+ with self.assertRaises(TypeError) as cm:
con.create_collation("X", 42)
- self.fail("should have raised a TypeError")
- except TypeError as e:
- self.assertEqual(e.args[0], "parameter must be callable")
+ self.assertEqual(str(cm.exception), 'parameter must be callable')
def CheckCreateCollationNotAscii(self):
con = sqlite.connect(":memory:")
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
con.create_collation("coll", lambda x, y: (x > y) - (x < y))
- self.fail("should have raised a ProgrammingError")
- except sqlite.ProgrammingError as e:
- pass
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 1),
'old SQLite versions crash on this test')
@@ -66,15 +55,13 @@ class CollationTests(unittest.TestCase):
) order by x collate mycoll
"""
result = con.execute(sql).fetchall()
- if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a":
- self.fail("the expected order was not returned")
+ self.assertEqual(result, [('c',), ('b',), ('a',)],
+ msg='the expected order was not returned')
con.create_collation("mycoll", None)
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
result = con.execute(sql).fetchall()
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll")
+ self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll')
def CheckCollationReturnsLargeInteger(self):
def mycoll(x, y):
@@ -106,8 +93,8 @@ class CollationTests(unittest.TestCase):
result = con.execute("""
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
""").fetchall()
- if result[0][0] != 'b' or result[1][0] != 'a':
- self.fail("wrong collation function is used")
+ self.assertEqual(result[0][0], 'b')
+ self.assertEqual(result[1][0], 'a')
def CheckDeregisterCollation(self):
"""
@@ -117,12 +104,9 @@ class CollationTests(unittest.TestCase):
con = sqlite.connect(":memory:")
con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
con.create_collation("mycoll", None)
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- if not e.args[0].startswith("no such collation sequence"):
- self.fail("wrong OperationalError raised")
+ self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll')
class ProgressTests(unittest.TestCase):
def CheckProgressHandlerUsed(self):
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py
index 11adb30..44974b0 100644
--- a/Lib/sqlite3/test/regression.py
+++ b/Lib/sqlite3/test/regression.py
@@ -84,9 +84,8 @@ class RegressionTests(unittest.TestCase):
cur.execute("select 1 x union select " + str(i))
con.close()
+ @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), 'needs sqlite 3.2.2 or newer')
def CheckOnConflictRollback(self):
- if sqlite.sqlite_version_info < (3, 2, 2):
- return
con = sqlite.connect(":memory:")
con.execute("create table foo(x, unique(x) on conflict rollback)")
con.execute("insert into foo(x) values (1)")
@@ -134,17 +133,11 @@ class RegressionTests(unittest.TestCase):
def CheckErrorMsgDecodeError(self):
# When porting the module to Python 3.0, the error message about
# decoding errors disappeared. This verifies they're back again.
- failure = None
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
self.con.execute("select 'xxx' || ? || 'yyy' colname",
(bytes(bytearray([250])),)).fetchone()
- failure = "should have raised an OperationalError with detailed description"
- except sqlite.OperationalError as e:
- msg = e.args[0]
- if not msg.startswith("Could not decode to UTF-8 column 'colname' with text 'xxx"):
- failure = "OperationalError did not have expected description text"
- if failure:
- self.fail(failure)
+ msg = "Could not decode to UTF-8 column 'colname' with text 'xxx"
+ self.assertIn(msg, str(cm.exception))
def CheckRegisterAdapter(self):
"""
@@ -170,14 +163,8 @@ class RegressionTests(unittest.TestCase):
con = sqlite.connect(":memory:")
cur = Cursor(con)
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
cur.execute("select 4+5").fetchall()
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("should have raised ProgrammingError")
-
def CheckStrSubclass(self):
"""
@@ -196,13 +183,8 @@ class RegressionTests(unittest.TestCase):
pass
con = Connection(":memory:")
- try:
+ with self.assertRaises(sqlite.ProgrammingError):
cur = con.cursor()
- self.fail("should have raised ProgrammingError")
- except sqlite.ProgrammingError:
- pass
- except:
- self.fail("should have raised ProgrammingError")
def CheckCursorRegistration(self):
"""
@@ -223,13 +205,8 @@ class RegressionTests(unittest.TestCase):
cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)])
cur.execute("select x from foo")
con.rollback()
- try:
+ with self.assertRaises(sqlite.InterfaceError):
cur.fetchall()
- self.fail("should have raised InterfaceError")
- except sqlite.InterfaceError:
- pass
- except:
- self.fail("should have raised InterfaceError")
def CheckAutoCommit(self):
"""
diff --git a/Lib/sqlite3/test/transactions.py b/Lib/sqlite3/test/transactions.py
index feb4fa1..a25360a 100644
--- a/Lib/sqlite3/test/transactions.py
+++ b/Lib/sqlite3/test/transactions.py
@@ -111,39 +111,25 @@ class TransactionTests(unittest.TestCase):
res = self.cur2.fetchall()
self.assertEqual(len(res), 1)
+ @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
+ 'test hangs on sqlite versions older than 3.2.2')
def CheckRaiseTimeout(self):
- if sqlite.sqlite_version_info < (3, 2, 2):
- # This will fail (hang) on earlier versions of sqlite.
- # Determine exact version it was fixed. 3.2.1 hangs.
- return
self.cur1.execute("create table test(i)")
self.cur1.execute("insert into test(i) values (5)")
- try:
+ with self.assertRaises(sqlite.OperationalError):
self.cur2.execute("insert into test(i) values (5)")
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError:
- pass
- except:
- self.fail("should have raised an OperationalError")
+ @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
+ 'test hangs on sqlite versions older than 3.2.2')
def CheckLocking(self):
"""
This tests the improved concurrency with pysqlite 2.3.4. You needed
to roll back con2 before you could commit con1.
"""
- if sqlite.sqlite_version_info < (3, 2, 2):
- # This will fail (hang) on earlier versions of sqlite.
- # Determine exact version it was fixed. 3.2.1 hangs.
- return
self.cur1.execute("create table test(i)")
self.cur1.execute("insert into test(i) values (5)")
- try:
+ with self.assertRaises(sqlite.OperationalError):
self.cur2.execute("insert into test(i) values (5)")
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError:
- pass
- except:
- self.fail("should have raised an OperationalError")
# NO self.con2.rollback() HERE!!!
self.con1.commit()
@@ -159,13 +145,8 @@ class TransactionTests(unittest.TestCase):
cur.execute("select 1 union select 2 union select 3")
con.rollback()
- try:
+ with self.assertRaises(sqlite.InterfaceError):
cur.fetchall()
- self.fail("InterfaceError should have been raised")
- except sqlite.InterfaceError as e:
- pass
- except:
- self.fail("InterfaceError should have been raised")
class SpecialCommandTests(unittest.TestCase):
def setUp(self):
diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py
index adad571..6667bc8 100644
--- a/Lib/sqlite3/test/types.py
+++ b/Lib/sqlite3/test/types.py
@@ -185,24 +185,14 @@ class DeclTypesTests(unittest.TestCase):
def CheckUnsupportedSeq(self):
class Bar: pass
val = Bar()
- try:
+ with self.assertRaises(sqlite.InterfaceError):
self.cur.execute("insert into test(f) values (?)", (val,))
- self.fail("should have raised an InterfaceError")
- except sqlite.InterfaceError:
- pass
- except:
- self.fail("should have raised an InterfaceError")
def CheckUnsupportedDict(self):
class Bar: pass
val = Bar()
- try:
+ with self.assertRaises(sqlite.InterfaceError):
self.cur.execute("insert into test(f) values (:val)", {"val": val})
- self.fail("should have raised an InterfaceError")
- except sqlite.InterfaceError:
- pass
- except:
- self.fail("should have raised an InterfaceError")
def CheckBlob(self):
# default
@@ -350,11 +340,9 @@ class DateTimeTests(unittest.TestCase):
ts2 = self.cur.fetchone()[0]
self.assertEqual(ts, ts2)
+ @unittest.skipIf(sqlite.sqlite_version_info < (3, 1),
+ 'the date functions are available on 3.1 or later')
def CheckSqlTimestamp(self):
- # The date functions are only available in SQLite version 3.1 or later
- if sqlite.sqlite_version_info < (3, 1):
- return
-
# SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time.
now = datetime.datetime.now()
self.cur.execute("insert into test(ts) values (current_timestamp)")
diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py
index 8a4bbab..4075045 100644
--- a/Lib/sqlite3/test/userfunctions.py
+++ b/Lib/sqlite3/test/userfunctions.py
@@ -162,11 +162,8 @@ class FunctionTests(unittest.TestCase):
self.con.close()
def CheckFuncErrorOnCreate(self):
- try:
+ with self.assertRaises(sqlite.OperationalError):
self.con.create_function("bla", -100, lambda x: 2*x)
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError:
- pass
def CheckFuncRefCount(self):
def getfunc():
@@ -231,12 +228,10 @@ class FunctionTests(unittest.TestCase):
def CheckFuncException(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
cur.execute("select raiseexception()")
cur.fetchone()
- self.fail("should have raised OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0], 'user-defined function raised exception')
+ self.assertEqual(str(cm.exception), 'user-defined function raised exception')
def CheckParamString(self):
cur = self.con.cursor()
@@ -312,55 +307,42 @@ class AggregateTests(unittest.TestCase):
pass
def CheckAggrErrorOnCreate(self):
- try:
+ with self.assertRaises(sqlite.OperationalError):
self.con.create_function("bla", -100, AggrSum)
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError:
- pass
def CheckAggrNoStep(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(AttributeError) as cm:
cur.execute("select nostep(t) from test")
- self.fail("should have raised an AttributeError")
- except AttributeError as e:
- self.assertEqual(e.args[0], "'AggrNoStep' object has no attribute 'step'")
+ self.assertEqual(str(cm.exception), "'AggrNoStep' object has no attribute 'step'")
def CheckAggrNoFinalize(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
cur.execute("select nofinalize(t) from test")
val = cur.fetchone()[0]
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
+ self.assertEqual(str(cm.exception), "user-defined aggregate's 'finalize' method raised error")
def CheckAggrExceptionInInit(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
cur.execute("select excInit(t) from test")
val = cur.fetchone()[0]
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0], "user-defined aggregate's '__init__' method raised error")
+ self.assertEqual(str(cm.exception), "user-defined aggregate's '__init__' method raised error")
def CheckAggrExceptionInStep(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
cur.execute("select excStep(t) from test")
val = cur.fetchone()[0]
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0], "user-defined aggregate's 'step' method raised error")
+ self.assertEqual(str(cm.exception), "user-defined aggregate's 'step' method raised error")
def CheckAggrExceptionInFinalize(self):
cur = self.con.cursor()
- try:
+ with self.assertRaises(sqlite.OperationalError) as cm:
cur.execute("select excFinalize(t) from test")
val = cur.fetchone()[0]
- self.fail("should have raised an OperationalError")
- except sqlite.OperationalError as e:
- self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
+ self.assertEqual(str(cm.exception), "user-defined aggregate's 'finalize' method raised error")
def CheckAggrCheckParamStr(self):
cur = self.con.cursor()
@@ -433,22 +415,14 @@ class AuthorizerTests(unittest.TestCase):
pass
def test_table_access(self):
- try:
+ with self.assertRaises(sqlite.DatabaseError) as cm:
self.con.execute("select * from t2")
- except sqlite.DatabaseError as e:
- if not e.args[0].endswith("prohibited"):
- self.fail("wrong exception text: %s" % e.args[0])
- return
- self.fail("should have raised an exception due to missing privileges")
+ self.assertIn('prohibited', str(cm.exception))
def test_column_access(self):
- try:
+ with self.assertRaises(sqlite.DatabaseError) as cm:
self.con.execute("select c2 from t1")
- except sqlite.DatabaseError as e:
- if not e.args[0].endswith("prohibited"):
- self.fail("wrong exception text: %s" % e.args[0])
- return
- self.fail("should have raised an exception due to missing privileges")
+ self.assertIn('prohibited', str(cm.exception))
class AuthorizerRaiseExceptionTests(AuthorizerTests):
@staticmethod
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index e124fab..c9e36fb 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -1349,7 +1349,8 @@ def transient_internet(resource_name, *, timeout=30.0, errnos=()):
500 <= err.code <= 599) or
(isinstance(err, urllib.error.URLError) and
(("ConnectionRefusedError" in err.reason) or
- ("TimeoutError" in err.reason))) or
+ ("TimeoutError" in err.reason) or
+ ("EOFError" in err.reason))) or
n in captured_errnos):
if not verbose:
sys.stderr.write(denied.args[0] + "\n")
diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py
index 9c2e9eb..c45d010 100644
--- a/Lib/test/support/script_helper.py
+++ b/Lib/test/support/script_helper.py
@@ -73,6 +73,10 @@ def run_python_until_end(*args, **env_vars):
# Need to preserve the original environment, for in-place testing of
# shared library builds.
env = os.environ.copy()
+ # set TERM='' unless the TERM environment variable is passed explicitly
+ # see issues #11390 and #18300
+ if 'TERM' not in env_vars:
+ env['TERM'] = ''
# But a special flag that can be set to override -- in this case, the
# caller is responsible to pass the full environment.
if env_vars.pop('__cleanenv', None):
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 0807dfb..206ebc6 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -1185,14 +1185,14 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
test_utils.run_briefly(self.loop) # allow transport to close
sock.family = socket.AF_INET6
- coro = self.loop.create_connection(asyncio.Protocol, '::2', 80)
+ coro = self.loop.create_connection(asyncio.Protocol, '::1', 80)
t, p = self.loop.run_until_complete(coro)
try:
- # Without inet_pton we use getaddrinfo, which transforms ('::2', 80)
- # to ('::0.0.0.2', 80, 0, 0). The last 0s are flow info, scope id.
+ # Without inet_pton we use getaddrinfo, which transforms ('::1', 80)
+ # to ('::1', 80, 0, 0). The last 0s are flow info, scope id.
[address] = sock.connect.call_args[0]
host, port = address[:2]
- self.assertRegex(host, r'::(0\.)*2')
+ self.assertRegex(host, r'::(0\.)*1')
self.assertEqual(port, 80)
_, kwargs = m_socket.socket.call_args
self.assertEqual(kwargs['family'], m_socket.AF_INET6)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index e0fdee3..824e843 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -472,6 +472,13 @@ if 1:
d = {f(): f(), f(): f()}
self.assertEqual(d, {1: 2, 3: 4})
+ def test_compile_filename(self):
+ for filename in ('file.py', b'file.py',
+ bytearray(b'file.py'), memoryview(b'file.py')):
+ code = compile('pass', filename, 'exec')
+ self.assertEqual(code.co_filename, 'file.py')
+ self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec')
+
@support.cpython_only
def test_same_filename_used(self):
s = """def f(): pass\ndef g(): pass"""
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index 30a6377..516403e 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -762,6 +762,40 @@ class TestExitStack(unittest.TestCase):
stack.push(cm)
self.assertIs(stack._exit_callbacks[-1], cm)
+ def test_dont_reraise_RuntimeError(self):
+ # https://bugs.python.org/issue27122
+ class UniqueException(Exception): pass
+ class UniqueRuntimeError(RuntimeError): pass
+
+ @contextmanager
+ def second():
+ try:
+ yield 1
+ except Exception as exc:
+ raise UniqueException("new exception") from exc
+
+ @contextmanager
+ def first():
+ try:
+ yield 1
+ except Exception as exc:
+ raise exc
+
+ # The UniqueRuntimeError should be caught by second()'s exception
+ # handler which chain raised a new UniqueException.
+ with self.assertRaises(UniqueException) as err_ctx:
+ with ExitStack() as es_ctx:
+ es_ctx.enter_context(second())
+ es_ctx.enter_context(first())
+ raise UniqueRuntimeError("please no infinite loop.")
+
+ exc = err_ctx.exception
+ self.assertIsInstance(exc, UniqueException)
+ self.assertIsInstance(exc.__context__, UniqueRuntimeError)
+ self.assertIsNone(exc.__context__.__context__)
+ self.assertIsNone(exc.__context__.__cause__)
+ self.assertIs(exc.__cause__, exc.__context__)
+
class TestRedirectStream:
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py
index 4f725ae..d0cefb0 100644
--- a/Lib/test/test_coroutines.py
+++ b/Lib/test/test_coroutines.py
@@ -1423,7 +1423,7 @@ class CoroutineTest(unittest.TestCase):
with warnings.catch_warnings():
warnings.simplefilter("error")
- # Test that __aiter__ that returns an asyncronous iterator
+ # Test that __aiter__ that returns an asynchronous iterator
# directly does not throw any warnings.
run_async(main())
self.assertEqual(I, 111011)
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 8411cdb..897d738 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -10,6 +10,7 @@
#
import os
+import string
import sys
import tempfile
import unittest
@@ -399,6 +400,55 @@ class MiscTests(unittest.TestCase):
class TestAscii(unittest.TestCase):
+ def test_controlnames(self):
+ for name in curses.ascii.controlnames:
+ self.assertTrue(hasattr(curses.ascii, name), name)
+
+ def test_ctypes(self):
+ def check(func, expected):
+ with self.subTest(ch=c, func=func):
+ self.assertEqual(func(i), expected)
+ self.assertEqual(func(c), expected)
+
+ for i in range(256):
+ c = chr(i)
+ b = bytes([i])
+ check(curses.ascii.isalnum, b.isalnum())
+ check(curses.ascii.isalpha, b.isalpha())
+ check(curses.ascii.isdigit, b.isdigit())
+ check(curses.ascii.islower, b.islower())
+ check(curses.ascii.isspace, b.isspace())
+ check(curses.ascii.isupper, b.isupper())
+
+ check(curses.ascii.isascii, i < 128)
+ check(curses.ascii.ismeta, i >= 128)
+ check(curses.ascii.isctrl, i < 32)
+ check(curses.ascii.iscntrl, i < 32 or i == 127)
+ check(curses.ascii.isblank, c in ' \t')
+ check(curses.ascii.isgraph, 32 < i <= 126)
+ check(curses.ascii.isprint, 32 <= i <= 126)
+ check(curses.ascii.ispunct, c in string.punctuation)
+ check(curses.ascii.isxdigit, c in string.hexdigits)
+
+ def test_ascii(self):
+ ascii = curses.ascii.ascii
+ self.assertEqual(ascii('\xc1'), 'A')
+ self.assertEqual(ascii('A'), 'A')
+ self.assertEqual(ascii(ord('\xc1')), ord('A'))
+
+ def test_ctrl(self):
+ ctrl = curses.ascii.ctrl
+ self.assertEqual(ctrl('J'), '\n')
+ self.assertEqual(ctrl('\n'), '\n')
+ self.assertEqual(ctrl('@'), '\0')
+ self.assertEqual(ctrl(ord('J')), ord('\n'))
+
+ def test_alt(self):
+ alt = curses.ascii.alt
+ self.assertEqual(alt('\n'), '\x8a')
+ self.assertEqual(alt('A'), '\xc1')
+ self.assertEqual(alt(ord('A')), 0xc1)
+
def test_unctrl(self):
unctrl = curses.ascii.unctrl
self.assertEqual(unctrl('a'), 'a')
@@ -408,9 +458,13 @@ class TestAscii(unittest.TestCase):
self.assertEqual(unctrl('\x7f'), '^?')
self.assertEqual(unctrl('\n'), '^J')
self.assertEqual(unctrl('\0'), '^@')
+ self.assertEqual(unctrl(ord('A')), 'A')
+ self.assertEqual(unctrl(ord('\n')), '^J')
# Meta-bit characters
self.assertEqual(unctrl('\x8a'), '!^J')
self.assertEqual(unctrl('\xc1'), '!A')
+ self.assertEqual(unctrl(ord('\x8a')), '!^J')
+ self.assertEqual(unctrl(ord('\xc1')), '!A')
if __name__ == '__main__':
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index c0d21b1..cde5d78 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -2491,7 +2491,8 @@ class PythonAPItests(unittest.TestCase):
Decimal = self.decimal.Decimal
class MyDecimal(Decimal):
- pass
+ def __init__(self, _):
+ self.x = 'y'
self.assertTrue(issubclass(MyDecimal, Decimal))
@@ -2499,6 +2500,8 @@ class PythonAPItests(unittest.TestCase):
self.assertEqual(type(r), MyDecimal)
self.assertEqual(str(r),
'0.1000000000000000055511151231257827021181583404541015625')
+ self.assertEqual(r.x, 'y')
+
bigint = 12345678901234567890123456789
self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 29426a3..33163b9 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -2719,12 +2719,6 @@ output into something we can doctest against:
>>> def normalize(s):
... return '\n'.join(s.decode().splitlines())
-Note: we also pass TERM='' to all the assert_python calls to avoid a bug
-in the readline library that is triggered in these tests because we are
-running them in a new python process. See:
-
- http://lists.gnu.org/archive/html/bug-readline/2013-06/msg00000.html
-
With those preliminaries out of the way, we'll start with a file with two
simple tests and no errors. We'll run both the unadorned doctest command, and
the verbose version, and then check the output:
@@ -2741,9 +2735,9 @@ the verbose version, and then check the output:
... _ = f.write('\n')
... _ = f.write('And that is it.\n')
... rc1, out1, err1 = script_helper.assert_python_ok(
- ... '-m', 'doctest', fn, TERM='')
+ ... '-m', 'doctest', fn)
... rc2, out2, err2 = script_helper.assert_python_ok(
- ... '-m', 'doctest', '-v', fn, TERM='')
+ ... '-m', 'doctest', '-v', fn)
With no arguments and passing tests, we should get no output:
@@ -2806,17 +2800,17 @@ text files).
... _ = f.write(' \"\"\"\n')
... import shutil
... rc1, out1, err1 = script_helper.assert_python_failure(
- ... '-m', 'doctest', fn, fn2, TERM='')
+ ... '-m', 'doctest', fn, fn2)
... rc2, out2, err2 = script_helper.assert_python_ok(
- ... '-m', 'doctest', '-o', 'ELLIPSIS', fn, TERM='')
+ ... '-m', 'doctest', '-o', 'ELLIPSIS', fn)
... rc3, out3, err3 = script_helper.assert_python_ok(
... '-m', 'doctest', '-o', 'ELLIPSIS',
- ... '-o', 'NORMALIZE_WHITESPACE', fn, fn2, TERM='')
+ ... '-o', 'NORMALIZE_WHITESPACE', fn, fn2)
... rc4, out4, err4 = script_helper.assert_python_failure(
- ... '-m', 'doctest', '-f', fn, fn2, TERM='')
+ ... '-m', 'doctest', '-f', fn, fn2)
... rc5, out5, err5 = script_helper.assert_python_ok(
... '-m', 'doctest', '-v', '-o', 'ELLIPSIS',
- ... '-o', 'NORMALIZE_WHITESPACE', fn, fn2, TERM='')
+ ... '-o', 'NORMALIZE_WHITESPACE', fn, fn2)
Our first test run will show the errors from the first file (doctest stops if a
file has errors). Note that doctest test-run error output appears on stdout,
@@ -2922,7 +2916,7 @@ We should also check some typical error cases.
Invalid file name:
>>> rc, out, err = script_helper.assert_python_failure(
- ... '-m', 'doctest', 'nosuchfile', TERM='')
+ ... '-m', 'doctest', 'nosuchfile')
>>> rc, out
(1, b'')
>>> print(normalize(err)) # doctest: +ELLIPSIS
@@ -2933,7 +2927,7 @@ Invalid file name:
Invalid doctest option:
>>> rc, out, err = script_helper.assert_python_failure(
- ... '-m', 'doctest', '-o', 'nosuchoption', TERM='')
+ ... '-m', 'doctest', '-o', 'nosuchoption')
>>> rc, out
(2, b'')
>>> print(normalize(err)) # doctest: +ELLIPSIS
diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py
index d526b5f..5eea379 100644
--- a/Lib/test/test_extcall.py
+++ b/Lib/test/test_extcall.py
@@ -57,6 +57,10 @@ Here we add keyword arguments
Traceback (most recent call last):
...
TypeError: f() got multiple values for keyword argument 'a'
+ >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5})
+ Traceback (most recent call last):
+ ...
+ TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7})
(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
>>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9})
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 9abe984..ab51a35 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -217,6 +217,33 @@ class TestPartialC(TestPartial, unittest.TestCase):
['{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr)
for kwargs_repr in kwargs_reprs])
+ def test_recursive_repr(self):
+ if self.partial is c_functools.partial:
+ name = 'functools.partial'
+ else:
+ name = self.partial.__name__
+
+ f = self.partial(capture)
+ f.__setstate__((f, (), {}, {}))
+ try:
+ self.assertEqual(repr(f), '%s(%s(...))' % (name, name))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (f,), {}, {}))
+ try:
+ self.assertEqual(repr(f), '%s(%r, %s(...))' % (name, capture, name))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (), {'a': f}, {}))
+ try:
+ self.assertEqual(repr(f), '%s(%r, a=%s(...))' % (name, capture, name))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
def test_pickle(self):
f = self.partial(signature, ['asdf'], bar=[True])
f.attr = []
@@ -297,6 +324,40 @@ class TestPartialC(TestPartial, unittest.TestCase):
self.assertEqual(r, ((1, 2), {}))
self.assertIs(type(r[0]), tuple)
+ def test_recursive_pickle(self):
+ f = self.partial(capture)
+ f.__setstate__((f, (), {}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises(RecursionError):
+ pickle.dumps(f, proto)
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (f,), {}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ f_copy = pickle.loads(pickle.dumps(f, proto))
+ try:
+ self.assertIs(f_copy.args[0], f_copy)
+ finally:
+ f_copy.__setstate__((capture, (), {}, {}))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (), {'a': f}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ f_copy = pickle.loads(pickle.dumps(f, proto))
+ try:
+ self.assertIs(f_copy.keywords['a'], f_copy)
+ finally:
+ f_copy.__setstate__((capture, (), {}, {}))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
# Issue 6083: Reference counting bug
def test_setstate_refcount(self):
class BadSequence:
diff --git a/Lib/test/test_importlib/test_lazy.py b/Lib/test/test_importlib/test_lazy.py
index 774b7a4..cc383c2 100644
--- a/Lib/test/test_importlib/test_lazy.py
+++ b/Lib/test/test_importlib/test_lazy.py
@@ -1,6 +1,8 @@
import importlib
from importlib import abc
from importlib import util
+import sys
+import types
import unittest
from . import util as test_util
@@ -122,12 +124,20 @@ class LazyLoaderTests(unittest.TestCase):
self.assertFalse(hasattr(module, '__name__'))
def test_module_substitution_error(self):
- source_code = 'import sys; sys.modules[__name__] = 42'
- module = self.new_module(source_code)
with test_util.uncache(TestingImporter.module_name):
- with self.assertRaises(ValueError):
+ fresh_module = types.ModuleType(TestingImporter.module_name)
+ sys.modules[TestingImporter.module_name] = fresh_module
+ module = self.new_module()
+ with self.assertRaisesRegex(ValueError, "substituted"):
module.__name__
+ def test_module_already_in_sys(self):
+ with test_util.uncache(TestingImporter.module_name):
+ module = self.new_module()
+ sys.modules[TestingImporter.module_name] = module
+ # Force the load; just care that no exception is raised.
+ module.__name__
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 3d301b4..ab6577f 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -627,6 +627,22 @@ class CompileTestCase(unittest.TestCase):
code2 = parser.compilest(st)
self.assertEqual(eval(code2), -3)
+ def test_compile_filename(self):
+ st = parser.expr('a + 5')
+ code = parser.compilest(st)
+ self.assertEqual(code.co_filename, '<syntax-tree>')
+ code = st.compile()
+ self.assertEqual(code.co_filename, '<syntax-tree>')
+ for filename in ('file.py', b'file.py',
+ bytearray(b'file.py'), memoryview(b'file.py')):
+ code = parser.compilest(st, filename)
+ self.assertEqual(code.co_filename, 'file.py')
+ code = st.compile(filename)
+ self.assertEqual(code.co_filename, 'file.py')
+ self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
+ self.assertRaises(TypeError, st.compile, list(b'file.py'))
+
+
class ParserStackLimitTestCase(unittest.TestCase):
"""try to push the parser to/over its limits.
see http://bugs.python.org/issue1881 for a discussion
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 59aa715..aee979b 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -356,7 +356,7 @@ def get_pydoc_html(module):
def get_pydoc_link(module):
"Returns a documentation web link of a module"
dirname = os.path.dirname
- basedir = os.path.join(dirname(dirname(__file__)))
+ basedir = dirname(dirname(__file__))
doc = pydoc.TextDoc()
loc = doc.getdocloc(module, basedir=basedir)
return loc
diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py
index 35330ab..8c2ad85 100644
--- a/Lib/test/test_readline.py
+++ b/Lib/test/test_readline.py
@@ -1,15 +1,25 @@
"""
Very minimal unittests for parts of the readline module.
"""
+from contextlib import ExitStack
+from errno import EIO
import os
+import selectors
+import subprocess
+import sys
import tempfile
import unittest
-from test.support import import_module, unlink
+from test.support import import_module, unlink, TESTFN
from test.support.script_helper import assert_python_ok
# Skip tests if there is no readline module
readline = import_module('readline')
+is_editline = readline.__doc__ and "libedit" in readline.__doc__
+
+@unittest.skipUnless(hasattr(readline, "clear_history"),
+ "The history update test cannot be run because the "
+ "clear_history method is not available.")
class TestHistoryManipulation (unittest.TestCase):
"""
These tests were added to check that the libedit emulation on OSX and the
@@ -17,9 +27,6 @@ class TestHistoryManipulation (unittest.TestCase):
why the tests cover only a small subset of the interface.
"""
- @unittest.skipUnless(hasattr(readline, "clear_history"),
- "The history update test cannot be run because the "
- "clear_history method is not available.")
def testHistoryUpdates(self):
readline.clear_history()
@@ -82,11 +89,29 @@ class TestHistoryManipulation (unittest.TestCase):
# write_history_file can create the target
readline.write_history_file(hfilename)
+ def test_nonascii_history(self):
+ readline.clear_history()
+ try:
+ readline.add_history("entrée 1")
+ except UnicodeEncodeError as err:
+ self.skipTest("Locale cannot encode test data: " + format(err))
+ readline.add_history("entrée 2")
+ readline.replace_history_item(1, "entrée 22")
+ readline.write_history_file(TESTFN)
+ self.addCleanup(os.remove, TESTFN)
+ readline.clear_history()
+ readline.read_history_file(TESTFN)
+ if is_editline:
+ # An add_history() call seems to be required for get_history_
+ # item() to register items from the file
+ readline.add_history("dummy")
+ self.assertEqual(readline.get_history_item(1), "entrée 1")
+ self.assertEqual(readline.get_history_item(2), "entrée 22")
+
class TestReadline(unittest.TestCase):
- @unittest.skipIf(readline._READLINE_VERSION < 0x0600
- and "libedit" not in readline.__doc__,
+ @unittest.skipIf(readline._READLINE_VERSION < 0x0600 and not is_editline,
"not supported in this library version")
def test_init(self):
# Issue #19884: Ensure that the ANSI sequence "\033[1034h" is not
@@ -96,6 +121,130 @@ class TestReadline(unittest.TestCase):
TERM='xterm-256color')
self.assertEqual(stdout, b'')
+ def test_nonascii(self):
+ try:
+ readline.add_history("\xEB\xEF")
+ except UnicodeEncodeError as err:
+ self.skipTest("Locale cannot encode test data: " + format(err))
+
+ script = r"""import readline
+
+is_editline = readline.__doc__ and "libedit" in readline.__doc__
+inserted = "[\xEFnserted]"
+macro = "|t\xEB[after]"
+set_pre_input_hook = getattr(readline, "set_pre_input_hook", None)
+if is_editline or not set_pre_input_hook:
+ # The insert_line() call via pre_input_hook() does nothing with Editline,
+ # so include the extra text that would have been inserted here
+ macro = inserted + macro
+
+if is_editline:
+ readline.parse_and_bind(r'bind ^B ed-prev-char')
+ readline.parse_and_bind(r'bind "\t" rl_complete')
+ readline.parse_and_bind(r'bind -s ^A "{}"'.format(macro))
+else:
+ readline.parse_and_bind(r'Control-b: backward-char')
+ readline.parse_and_bind(r'"\t": complete')
+ readline.parse_and_bind(r'set disable-completion off')
+ readline.parse_and_bind(r'set show-all-if-ambiguous off')
+ readline.parse_and_bind(r'set show-all-if-unmodified off')
+ readline.parse_and_bind(r'Control-a: "{}"'.format(macro))
+
+def pre_input_hook():
+ readline.insert_text(inserted)
+ readline.redisplay()
+if set_pre_input_hook:
+ set_pre_input_hook(pre_input_hook)
+
+def completer(text, state):
+ if text == "t\xEB":
+ if state == 0:
+ print("text", ascii(text))
+ print("line", ascii(readline.get_line_buffer()))
+ print("indexes", readline.get_begidx(), readline.get_endidx())
+ return "t\xEBnt"
+ if state == 1:
+ return "t\xEBxt"
+ if text == "t\xEBx" and state == 0:
+ return "t\xEBxt"
+ return None
+readline.set_completer(completer)
+
+def display(substitution, matches, longest_match_length):
+ print("substitution", ascii(substitution))
+ print("matches", ascii(matches))
+readline.set_completion_display_matches_hook(display)
+
+print("result", ascii(input()))
+print("history", ascii(readline.get_history_item(1)))
+"""
+
+ input = b"\x01" # Ctrl-A, expands to "|t\xEB[after]"
+ input += b"\x02" * len("[after]") # Move cursor back
+ input += b"\t\t" # Display possible completions
+ input += b"x\t" # Complete "t\xEBx" -> "t\xEBxt"
+ input += b"\r"
+ output = run_pty(script, input)
+ self.assertIn(b"text 't\\xeb'\r\n", output)
+ self.assertIn(b"line '[\\xefnserted]|t\\xeb[after]'\r\n", output)
+ self.assertIn(b"indexes 11 13\r\n", output)
+ if not is_editline and hasattr(readline, "set_pre_input_hook"):
+ self.assertIn(b"substitution 't\\xeb'\r\n", output)
+ self.assertIn(b"matches ['t\\xebnt', 't\\xebxt']\r\n", output)
+ expected = br"'[\xefnserted]|t\xebxt[after]'"
+ self.assertIn(b"result " + expected + b"\r\n", output)
+ self.assertIn(b"history " + expected + b"\r\n", output)
+
+
+def run_pty(script, input=b"dummy input\r"):
+ pty = import_module('pty')
+ output = bytearray()
+ [master, slave] = pty.openpty()
+ args = (sys.executable, '-c', script)
+ proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)
+ os.close(slave)
+ with ExitStack() as cleanup:
+ cleanup.enter_context(proc)
+ def terminate(proc):
+ try:
+ proc.terminate()
+ except ProcessLookupError:
+ # Workaround for Open/Net BSD bug (Issue 16762)
+ pass
+ cleanup.callback(terminate, proc)
+ cleanup.callback(os.close, master)
+ # Avoid using DefaultSelector and PollSelector. Kqueue() does not
+ # work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open
+ # BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4
+ # either (Issue 20472). Hopefully the file descriptor is low enough
+ # to use with select().
+ sel = cleanup.enter_context(selectors.SelectSelector())
+ sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
+ os.set_blocking(master, False)
+ while True:
+ for [_, events] in sel.select():
+ if events & selectors.EVENT_READ:
+ try:
+ chunk = os.read(master, 0x10000)
+ except OSError as err:
+ # Linux raises EIO when slave is closed (Issue 5380)
+ if err.errno != EIO:
+ raise
+ chunk = b""
+ if not chunk:
+ return output
+ output.extend(chunk)
+ if events & selectors.EVENT_WRITE:
+ try:
+ input = input[os.write(master, input):]
+ except OSError as err:
+ # Apparently EIO means the slave was closed
+ if err.errno != EIO:
+ raise
+ input = b"" # Stop writing
+ if not input:
+ sel.modify(master, selectors.EVENT_READ)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index e5e7b83..c5d7fac 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -157,6 +157,12 @@ class SymtableTest(unittest.TestCase):
self.fail("no SyntaxError for %r" % (brokencode,))
checkfilename("def f(x): foo)(") # parse-time
checkfilename("def f(x): global x") # symtable-build-time
+ symtable.symtable("pass", b"spam", "exec")
+ with self.assertRaises(TypeError):
+ symtable.symtable("pass", bytearray(b"spam"), "exec")
+ symtable.symtable("pass", memoryview(b"spam"), "exec")
+ with self.assertRaises(TypeError):
+ symtable.symtable("pass", list(b"spam"), "exec")
def test_eval(self):
symbols = symtable.symtable("42", "?", "eval")
diff --git a/Lib/test/test_unpack_ex.py b/Lib/test/test_unpack_ex.py
index d27eef0..74346b4 100644
--- a/Lib/test/test_unpack_ex.py
+++ b/Lib/test/test_unpack_ex.py
@@ -248,6 +248,11 @@ Overridden parameters
...
TypeError: f() got multiple values for keyword argument 'x'
+ >>> f(x=5, **{'x': 3}, **{'x': 2})
+ Traceback (most recent call last):
+ ...
+ TypeError: f() got multiple values for keyword argument 'x'
+
>>> f(**{1: 3}, **{1: 5})
Traceback (most recent call last):
...
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
index 44e3142..bc1dd14 100644
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -18,7 +18,7 @@ import weakref
from itertools import product
from test import support
-from test.support import TESTFN, findfile, import_fresh_module, gc_collect
+from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr
# pyET is the pure-Python implementation.
#
@@ -1860,6 +1860,12 @@ class BadElementTest(ElementTestCase, unittest.TestCase):
e.extend([ET.Element('bar')])
self.assertRaises(ValueError, e.remove, X('baz'))
+ def test_recursive_repr(self):
+ # Issue #25455
+ e = ET.Element('foo')
+ with swap_attr(e, 'tag', e):
+ with self.assertRaises(RuntimeError):
+ repr(e) # Should not crash
class MutatingElementPath(str):
def __new__(cls, elem, *args):
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
index 0da5906..8e5e12d 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -600,6 +600,19 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
finally:
os.remove(filename)
+ def testBytesPath(self):
+ filename = support.TESTFN + ".zip"
+ self.addCleanup(support.unlink, filename)
+ with ZipFile(filename, "w") as z:
+ zinfo = ZipInfo(TESTMOD + ".py", time.localtime(NOW))
+ zinfo.compress_type = self.compression
+ z.writestr(zinfo, test_src)
+
+ zipimport.zipimporter(filename)
+ zipimport.zipimporter(os.fsencode(filename))
+ zipimport.zipimporter(bytearray(os.fsencode(filename)))
+ zipimport.zipimporter(memoryview(os.fsencode(filename)))
+
@support.requires_zlib
class CompressedZipImportTestCase(UncompressedZipImportTestCase):
@@ -620,6 +633,8 @@ class BadFileZipImportTestCase(unittest.TestCase):
def testBadArgs(self):
self.assertRaises(TypeError, zipimport.zipimporter, None)
self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
+ self.assertRaises(TypeError, zipimport.zipimporter,
+ list(os.fsencode(TESTMOD)))
def testFilenameTooLong(self):
self.assertZipFailure('A' * 33000)
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index aa646dc..55bfb7f 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -271,7 +271,7 @@ class Variable:
Return the name of the callback.
"""
- f = CallWrapper(callback, None, self).__call__
+ f = CallWrapper(callback, None, self._root).__call__
cbname = repr(id(f))
try:
callback = callback.__func__
@@ -295,14 +295,19 @@ class Variable:
CBNAME is the name of the callback returned from trace_variable or trace.
"""
self._tk.call("trace", "vdelete", self._name, mode, cbname)
- self._tk.deletecommand(cbname)
- try:
- self._tclCommands.remove(cbname)
- except ValueError:
- pass
+ cbname = self._tk.splitlist(cbname)[0]
+ for m, ca in self.trace_vinfo():
+ if self._tk.splitlist(ca)[0] == cbname:
+ break
+ else:
+ self._tk.deletecommand(cbname)
+ try:
+ self._tclCommands.remove(cbname)
+ except ValueError:
+ pass
def trace_vinfo(self):
"""Return all trace callback information."""
- return [self._tk.split(x) for x in self._tk.splitlist(
+ return [self._tk.splitlist(x) for x in self._tk.splitlist(
self._tk.call("trace", "vinfo", self._name))]
def __eq__(self, other):
"""Comparison for equality (==).
diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/tkinter/test/test_tkinter/test_variables.py
index abdce96..1f74453 100644
--- a/Lib/tkinter/test/test_tkinter/test_variables.py
+++ b/Lib/tkinter/test/test_tkinter/test_variables.py
@@ -1,5 +1,5 @@
import unittest
-
+import gc
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
@@ -87,6 +87,55 @@ class TestVariable(TestBase):
v.set("value")
self.assertTrue(v.side_effect)
+ def test_trace(self):
+ v = Variable(self.root)
+ vname = str(v)
+ trace = []
+ def read_tracer(*args):
+ trace.append(('read',) + args)
+ def write_tracer(*args):
+ trace.append(('write',) + args)
+ cb1 = v.trace_variable('r', read_tracer)
+ cb2 = v.trace_variable('wu', write_tracer)
+ self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)])
+ self.assertEqual(trace, [])
+
+ v.set('spam')
+ self.assertEqual(trace, [('write', vname, '', 'w')])
+
+ trace = []
+ v.get()
+ self.assertEqual(trace, [('read', vname, '', 'r')])
+
+ trace = []
+ info = sorted(v.trace_vinfo())
+ v.trace_vdelete('w', cb1) # Wrong mode
+ self.assertEqual(sorted(v.trace_vinfo()), info)
+ with self.assertRaises(TclError):
+ v.trace_vdelete('r', 'spam') # Wrong command name
+ self.assertEqual(sorted(v.trace_vinfo()), info)
+ v.trace_vdelete('r', (cb1, 43)) # Wrong arguments
+ self.assertEqual(sorted(v.trace_vinfo()), info)
+ v.get()
+ self.assertEqual(trace, [('read', vname, '', 'r')])
+
+ trace = []
+ v.trace_vdelete('r', cb1)
+ self.assertEqual(v.trace_vinfo(), [('wu', cb2)])
+ v.get()
+ self.assertEqual(trace, [])
+
+ trace = []
+ del write_tracer
+ gc.collect()
+ v.set('eggs')
+ self.assertEqual(trace, [('write', vname, '', 'w')])
+
+ trace = []
+ del v
+ gc.collect()
+ self.assertEqual(trace, [('write', vname, '', 'u')])
+
class TestStringVar(TestBase):
diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py
index c031351..8bd22d0 100644
--- a/Lib/tkinter/test/test_ttk/test_widgets.py
+++ b/Lib/tkinter/test/test_ttk/test_widgets.py
@@ -1486,6 +1486,57 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
value)
+ def test_selection(self):
+ # item 'none' doesn't exist
+ self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none')
+
+ item1 = self.tv.insert('', 'end')
+ item2 = self.tv.insert('', 'end')
+ c1 = self.tv.insert(item1, 'end')
+ c2 = self.tv.insert(item1, 'end')
+ c3 = self.tv.insert(item1, 'end')
+ self.assertEqual(self.tv.selection(), ())
+
+ self.tv.selection_set((c1, item2))
+ self.assertEqual(self.tv.selection(), (c1, item2))
+ self.tv.selection_set(c2)
+ self.assertEqual(self.tv.selection(), (c2,))
+
+ self.tv.selection_add((c1, item2))
+ self.assertEqual(self.tv.selection(), (c1, c2, item2))
+ self.tv.selection_add(item1)
+ self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
+
+ self.tv.selection_remove((item1, c3))
+ self.assertEqual(self.tv.selection(), (c1, c2, item2))
+ self.tv.selection_remove(c2)
+ self.assertEqual(self.tv.selection(), (c1, item2))
+
+ self.tv.selection_toggle((c1, c3))
+ self.assertEqual(self.tv.selection(), (c3, item2))
+ self.tv.selection_toggle(item2)
+ self.assertEqual(self.tv.selection(), (c3,))
+
+ self.tv.insert('', 'end', id='with spaces')
+ self.tv.selection_set('with spaces')
+ self.assertEqual(self.tv.selection(), ('with spaces',))
+
+ self.tv.insert('', 'end', id='{brace')
+ self.tv.selection_set('{brace')
+ self.assertEqual(self.tv.selection(), ('{brace',))
+
+ self.tv.insert('', 'end', id='unicode\u20ac')
+ self.tv.selection_set('unicode\u20ac')
+ self.assertEqual(self.tv.selection(), ('unicode\u20ac',))
+
+ self.tv.insert('', 'end', id=b'bytes\xe2\x82\xac')
+ self.tv.selection_set(b'bytes\xe2\x82\xac')
+ self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',))
+
+
def test_set(self):
self.tv['columns'] = ['A', 'B']
item = self.tv.insert('', 'end', values=['a', 'b'])
diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py
index 8f9369b..0e5759d 100644
--- a/Lib/tkinter/ttk.py
+++ b/Lib/tkinter/ttk.py
@@ -1392,7 +1392,9 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
def selection(self, selop=None, items=None):
"""If selop is not specified, returns selected items."""
- return self.tk.call(self._w, "selection", selop, items)
+ if isinstance(items, (str, bytes)):
+ items = (items,)
+ return self.tk.splitlist(self.tk.call(self._w, "selection", selop, items))
def selection_set(self, items):
diff --git a/Lib/turtle.py b/Lib/turtle.py
index cbd4f47..57cf3d9 100644
--- a/Lib/turtle.py
+++ b/Lib/turtle.py
@@ -179,7 +179,7 @@ def config_dict(filename):
continue
try:
key, value = line.split("=")
- except:
+ except ValueError:
print("Bad line in config-file %s:\n%s" % (filename,line))
continue
key = key.strip()
@@ -192,7 +192,7 @@ def config_dict(filename):
value = float(value)
else:
value = int(value)
- except:
+ except ValueError:
pass # value need not be converted
cfgdict[key] = value
return cfgdict
@@ -220,7 +220,7 @@ def readconfig(cfgdict):
try:
head, tail = split(__file__)
cfg_file2 = join(head, default_cfg)
- except:
+ except Exception:
cfg_file2 = ""
if isfile(cfg_file2):
cfgdict2 = config_dict(cfg_file2)
@@ -229,7 +229,7 @@ def readconfig(cfgdict):
try:
readconfig(_CFG)
-except:
+except Exception:
print ("No configfile read, reason unknown")
@@ -653,7 +653,7 @@ class TurtleScreenBase(object):
x, y = (self.cv.canvasx(event.x)/self.xscale,
-self.cv.canvasy(event.y)/self.yscale)
fun(x, y)
- except:
+ except Exception:
pass
self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
@@ -1158,7 +1158,7 @@ class TurtleScreen(TurtleScreenBase):
raise TurtleGraphicsError("bad color string: %s" % str(color))
try:
r, g, b = color
- except:
+ except (TypeError, ValueError):
raise TurtleGraphicsError("bad color arguments: %s" % str(color))
if self._colormode == 1.0:
r, g, b = [round(255.0*x) for x in (r, g, b)]
@@ -2702,7 +2702,7 @@ class RawTurtle(TPen, TNavigator):
return args
try:
r, g, b = args
- except:
+ except (TypeError, ValueError):
raise TurtleGraphicsError("bad color arguments: %s" % str(args))
if self.screen._colormode == 1.0:
r, g, b = [round(255.0*x) for x in (r, g, b)]
@@ -3865,7 +3865,7 @@ def read_docstrings(lang):
try:
# eval(key).im_func.__doc__ = docsdict[key]
eval(key).__doc__ = docsdict[key]
- except:
+ except Exception:
print("Bad docstring-entry: %s" % key)
_LANGUAGE = _CFG["language"]
@@ -3875,7 +3875,7 @@ try:
read_docstrings(_LANGUAGE)
except ImportError:
print("Cannot find docsdict for", _LANGUAGE)
-except:
+except Exception:
print ("Unknown Error when trying to import %s-docstring-dictionary" %
_LANGUAGE)
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 86a5a3d..1adfcf9 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1694,6 +1694,7 @@ _non_defaults = {
'__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
'__getstate__', '__setstate__', '__getformat__', '__setformat__',
'__repr__', '__dir__', '__subclasses__', '__format__',
+ '__getnewargs_ex__',
}