Python-checkins
Threads by month
- ----- 2024 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
November 2018
- 2 participants
- 507 discussions
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-35167: Specify program for gzip and json.tool command line options. (GH-10332)
by Serhiy Storchaka 05 Nov '18
by Serhiy Storchaka 05 Nov '18
05 Nov '18
https://github.com/python/cpython/commit/083a7a172b8c8888252d72031f21dcfea3…
commit: 083a7a172b8c8888252d72031f21dcfea3c0d73f
branch: master
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-05T17:47:27+02:00
summary:
bpo-35167: Specify program for gzip and json.tool command line options. (GH-10332)
files:
M Doc/library/gzip.rst
M Doc/library/json.rst
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index a93f37743854..a57307b0e499 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -211,6 +211,9 @@ Example of how to GZIP compress a binary string::
The basic data compression module needed to support the :program:`gzip` file
format.
+
+.. program:: gzip
+
Command Line Interface
----------------------
diff --git a/Doc/library/json.rst b/Doc/library/json.rst
index 8ce493d63995..510e30733fed 100644
--- a/Doc/library/json.rst
+++ b/Doc/library/json.rst
@@ -648,7 +648,9 @@ when serializing Python :class:`int` values of extremely large magnitude, or
when serializing instances of "exotic" numerical types such as
:class:`decimal.Decimal`.
+
.. _json-commandline:
+.. program:: json.tool
Command Line Interface
----------------------
@@ -680,6 +682,7 @@ specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively:
:option:`--sort-keys` option to sort the output of dictionaries
alphabetically by key.
+
Command line options
^^^^^^^^^^^^^^^^^^^^
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
[3.6] bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284) (GH-10335)
by Serhiy Storchaka 05 Nov '18
by Serhiy Storchaka 05 Nov '18
05 Nov '18
https://github.com/python/cpython/commit/7054e5c80b6e98cd44e22d1bc2d7f0a943…
commit: 7054e5c80b6e98cd44e22d1bc2d7f0a94343089d
branch: 3.6
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-05T17:13:50+02:00
summary:
[3.6] bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284) (GH-10335)
Two kind of mistakes:
1. Missed space. After concatenating there is no space between words.
2. Missed comma. Causes unintentional concatenating in a list of strings..
(cherry picked from commit 34fd4c20198dea6ab2fe8dc6d32d744d9bde868d)
files:
M Lib/_pydecimal.py
M Lib/distutils/command/bdist_dumb.py
M Lib/distutils/command/bdist_msi.py
M Lib/distutils/command/bdist_rpm.py
M Lib/distutils/command/bdist_wininst.py
M Lib/distutils/command/build_ext.py
M Lib/email/_header_value_parser.py
M Lib/idlelib/hyperparser.py
M Lib/idlelib/idle_test/htest.py
M Lib/idlelib/idle_test/mock_tk.py
M Lib/test/test_compile.py
M Lib/test/test_decimal.py
M Lib/test/test_http_cookiejar.py
M Lib/test/test_range.py
M Lib/test/test_smtplib.py
M Lib/test/test_strptime.py
M Lib/trace.py
M Lib/unittest/mock.py
M Modules/_datetimemodule.c
M Modules/_pickle.c
M Python/import.c
M Tools/scripts/texi2html.py
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 0b40928ff8d1..e7df67dc9b9d 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -2062,7 +2062,7 @@ def _power_modulo(self, other, modulo, context=None):
if not other and not self:
return context._raise_error(InvalidOperation,
'at least one of pow() 1st argument '
- 'and 2nd argument must be nonzero ;'
+ 'and 2nd argument must be nonzero; '
'0**0 is not defined')
# compute sign of result
diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py
index e9274d925afa..f0d6b5b8cd8a 100644
--- a/Lib/distutils/command/bdist_dumb.py
+++ b/Lib/distutils/command/bdist_dumb.py
@@ -32,7 +32,7 @@ class bdist_dumb(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('relative', None,
- "build the archive using relative paths"
+ "build the archive using relative paths "
"(default: false)"),
('owner=', 'u',
"Owner name used when creating a tar file"
diff --git a/Lib/distutils/command/bdist_msi.py b/Lib/distutils/command/bdist_msi.py
index a4bd5a589d38..80104c372d9a 100644
--- a/Lib/distutils/command/bdist_msi.py
+++ b/Lib/distutils/command/bdist_msi.py
@@ -98,14 +98,14 @@ class bdist_msi(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py
index ac4621791d56..02f10dd89d91 100644
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -58,7 +58,7 @@ class bdist_rpm(Command):
"RPM \"vendor\" (eg. \"Joe Blow <joe(a)example.com>\") "
"[default: maintainer or author from setup script]"),
('packager=', None,
- "RPM packager (eg. \"Jane Doe <jane(a)example.net>\")"
+ "RPM packager (eg. \"Jane Doe <jane(a)example.net>\") "
"[default: vendor]"),
('doc-files=', None,
"list of documentation files (space or comma-separated)"),
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 0871a4f7d6b2..fde56754e891 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -29,7 +29,7 @@ class bdist_wininst(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
@@ -40,7 +40,7 @@ class bdist_wininst(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 74de782d8a66..8ed4065bb5f0 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -365,7 +365,7 @@ def check_extensions_list(self, extensions):
ext_name, build_info = ext
log.warn("old-style (ext_name, build_info) tuple found in "
- "ext_modules for extension '%s'"
+ "ext_modules for extension '%s' "
"-- please convert to Extension instance", ext_name)
if not (isinstance(ext_name, str) and
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index de7ab5d12e78..1fb8cb448a01 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -2210,8 +2210,8 @@ def get_section(value):
digits += value[0]
value = value[1:]
if digits[0] == '0' and digits != '0':
- section.defects.append(errors.InvalidHeaderError("section number"
- "has an invalid leading 0"))
+ section.defects.append(errors.InvalidHeaderError(
+ "section number has an invalid leading 0"))
section.number = int(digits)
section.append(ValueTerminal(digits, 'digits'))
return section, value
diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py
index 7581fe274b21..7e7e0ae80247 100644
--- a/Lib/idlelib/hyperparser.py
+++ b/Lib/idlelib/hyperparser.py
@@ -224,7 +224,7 @@ def get_expression(self):
given index, which is empty if there is no real one.
"""
if not self.is_in_code():
- raise ValueError("get_expression should only be called"
+ raise ValueError("get_expression should only be called "
"if index is inside a code.")
rawtext = self.rawtext
diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py
index 8c1c24d070cc..583e607b767e 100644
--- a/Lib/idlelib/idle_test/htest.py
+++ b/Lib/idlelib/idle_test/htest.py
@@ -117,7 +117,7 @@ def _wrapper(parent): # htest #
"font face of the text in the area below it.\nIn the "
"'Highlighting' tab, try different color schemes. Clicking "
"items in the sample program should update the choices above it."
- "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings"
+ "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings "
"of interest."
"\n[Ok] to close the dialog.[Apply] to apply the settings and "
"and [Cancel] to revert all changes.\nRe-run the test to ensure "
@@ -152,7 +152,7 @@ def _wrapper(parent): # htest #
'msg': "Test for different key modifier sequences.\n"
"<nothing> is invalid.\n"
"No modifier key is invalid.\n"
- "Shift key with [a-z],[0-9], function key, move key, tab, space"
+ "Shift key with [a-z],[0-9], function key, move key, tab, space "
"is invalid.\nNo validity checking if advanced key binding "
"entry is used."
}
@@ -234,7 +234,7 @@ def _wrapper(parent): # htest #
'file': 'percolator',
'kwds': {},
'msg': "There are two tracers which can be toggled using a checkbox.\n"
- "Toggling a tracer 'on' by checking it should print tracer"
+ "Toggling a tracer 'on' by checking it should print tracer "
"output to the console or to the IDLE shell.\n"
"If both the tracers are 'on', the output from the tracer which "
"was switched 'on' later, should be printed first\n"
@@ -335,7 +335,7 @@ def _wrapper(parent): # htest #
_widget_redirector_spec = {
'file': 'redirector',
'kwds': {},
- 'msg': "Every text insert should be printed to the console."
+ 'msg': "Every text insert should be printed to the console "
"or the IDLE shell."
}
diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py
index 6e351297d75d..a54f51f1949c 100644
--- a/Lib/idlelib/idle_test/mock_tk.py
+++ b/Lib/idlelib/idle_test/mock_tk.py
@@ -260,7 +260,7 @@ def compare(self, index1, op, index2):
elif op == '!=':
return line1 != line2 or char1 != char2
else:
- raise TclError('''bad comparison operator "%s":'''
+ raise TclError('''bad comparison operator "%s": '''
'''must be <, <=, ==, >=, >, or !=''' % op)
# The following Text methods normally do something and return None.
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index c9812e46b486..745ce029aa57 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -285,7 +285,7 @@ def test_import(self):
'from sys import stdin)',
'from sys import stdin, stdout,\nstderr',
'from sys import stdin si',
- 'from sys import stdin,'
+ 'from sys import stdin,',
'from sys import (*)',
'from sys import (stdin,, stdout, stderr)',
'from sys import (stdin, stdout),',
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 45d80cec810f..8808a670f939 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1178,10 +1178,10 @@ def test_wide_char_separator_decimal_point(self):
decimal_point = locale.localeconv()['decimal_point']
thousands_sep = locale.localeconv()['thousands_sep']
if decimal_point != '\u066b':
- self.skipTest('inappropriate decimal point separator'
+ self.skipTest('inappropriate decimal point separator '
'({!a} not {!a})'.format(decimal_point, '\u066b'))
if thousands_sep != '\u066c':
- self.skipTest('inappropriate thousands separator'
+ self.skipTest('inappropriate thousands separator '
'({!a} not {!a})'.format(thousands_sep, '\u066c'))
self.assertEqual(format(Decimal('100000000.123'), 'n'),
diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py
index 6fee4df10a40..abc625d672a7 100644
--- a/Lib/test/test_http_cookiejar.py
+++ b/Lib/test/test_http_cookiejar.py
@@ -174,12 +174,10 @@ def test_iso2time_garbage(self):
'1980-01-01 00:61:00',
'01-01-1980 00:00:62',
'01-01-1980T00:00:62',
- '19800101T250000Z'
- '1980-01-01 00:00:00 -2500',
+ '19800101T250000Z',
]:
self.assertIsNone(iso2time(test),
- "iso2time(%s) is not None\n"
- "iso2time(test) %s" % (test, iso2time(test)))
+ "iso2time(%r)" % test)
class HeaderTests(unittest.TestCase):
diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py
index 679759ec6d67..b6f948dc6a8f 100644
--- a/Lib/test/test_range.py
+++ b/Lib/test/test_range.py
@@ -40,7 +40,7 @@ def assert_iterators_equal(self, xs, ys, test_id, limit=None):
self.fail('{}: unexpected excess element {} at '
'position {}'.format(test_id, x, i))
else:
- self.fail('{}: wrong element at position {};'
+ self.fail('{}: wrong element at position {}; '
'expected {}, got {}'.format(test_id, i, y, x))
def test_range(self):
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 18110191dc3b..87047514e7aa 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -767,7 +767,7 @@ def _auth_cram_md5(self, arg=None):
try:
user, hashed_pass = logpass.split()
except ValueError as e:
- self.push('535 Splitting response {!r} into user and password'
+ self.push('535 Splitting response {!r} into user and password '
'failed: {}'.format(logpass, e))
return False
valid_hashed_pass = hmac.HMAC(
diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py
index 2cf0926239c0..1438487161f9 100644
--- a/Lib/test/test_strptime.py
+++ b/Lib/test/test_strptime.py
@@ -457,7 +457,7 @@ def test_gregorian_calculation(self):
self.assertTrue(result.tm_year == self.time_tuple.tm_year and
result.tm_mon == self.time_tuple.tm_mon and
result.tm_mday == self.time_tuple.tm_mday,
- "Calculation of Gregorian date failed;"
+ "Calculation of Gregorian date failed; "
"%s-%s-%s != %s-%s-%s" %
(result.tm_year, result.tm_mon, result.tm_mday,
self.time_tuple.tm_year, self.time_tuple.tm_mon,
@@ -469,7 +469,7 @@ def test_day_of_week_calculation(self):
result = _strptime._strptime_time(time.strftime(format_string, self.time_tuple),
format_string)
self.assertTrue(result.tm_wday == self.time_tuple.tm_wday,
- "Calculation of day of the week failed;"
+ "Calculation of day of the week failed; "
"%s != %s" % (result.tm_wday, self.time_tuple.tm_wday))
if support.is_android:
diff --git a/Lib/trace.py b/Lib/trace.py
index d171577e3991..e5fa94fc948f 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -313,7 +313,7 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None):
try:
outfile = open(path, "w", encoding=encoding)
except OSError as err:
- print(("trace: Could not open %r for writing: %s"
+ print(("trace: Could not open %r for writing: %s "
"- skipping" % (path, err)), file=sys.stderr)
return 0, 0
@@ -655,7 +655,7 @@ def main():
grp = parser.add_argument_group('Filters',
'Can be specified multiple times')
grp.add_argument('--ignore-module', action='append', default=[],
- help='Ignore the given module(s) and its submodules'
+ help='Ignore the given module(s) and its submodules '
'(if it is a package). Accepts comma separated list of '
'module names.')
grp.add_argument('--ignore-dir', action='append', default=[],
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 86183adc1905..31b198516161 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1737,7 +1737,7 @@ def method(self, *args, **kw):
_unsupported_magics = {
'__getattr__', '__setattr__',
- '__init__', '__new__', '__prepare__'
+ '__init__', '__new__', '__prepare__',
'__instancecheck__', '__subclasscheck__',
'__del__'
}
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index afc865e466de..b2e0176b3232 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -3158,7 +3158,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
return result;
Inconsistent:
- PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
+ PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
"inconsistent results; cannot convert");
/* fall through to failure */
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 0a7e20e10592..6830d93f503e 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -4527,7 +4527,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be a PicklerMemoProxy object"
+ "'memo' attribute must be a PicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
@@ -6969,7 +6969,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be an UnpicklerMemoProxy object"
+ "'memo' attribute must be an UnpicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
diff --git a/Python/import.c b/Python/import.c
index fa0a9e1f2a43..db1650a9ddd2 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -715,7 +715,7 @@ remove_module(PyObject *name)
if (PyDict_GetItem(modules, name) == NULL)
return;
if (PyDict_DelItem(modules, name) < 0)
- Py_FatalError("import: deleting existing key in"
+ Py_FatalError("import: deleting existing key in "
"sys.modules failed");
}
diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py
index 9c1e9fe8d8c4..5565c210dabb 100755
--- a/Tools/scripts/texi2html.py
+++ b/Tools/scripts/texi2html.py
@@ -1806,7 +1806,7 @@ def finalize(self):
print('<!-- This file defines the table of contents -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
@@ -1831,7 +1831,7 @@ def finalize(self):
print('<!-- This file defines the index -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284)
by Miss Islington (bot) 05 Nov '18
by Miss Islington (bot) 05 Nov '18
05 Nov '18
https://github.com/python/cpython/commit/7beb8c54ede7669a59bb9b912ba0ffd8aa…
commit: 7beb8c54ede7669a59bb9b912ba0ffd8aa3998c6
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-05T06:52:58-08:00
summary:
bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284)
Two kind of mistakes:
1. Missed space. After concatenating there is no space between words.
2. Missed comma. Causes unintentional concatenating in a list of strings.
(cherry picked from commit 34fd4c20198dea6ab2fe8dc6d32d744d9bde868d)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
files:
M Lib/_pydecimal.py
M Lib/concurrent/futures/thread.py
M Lib/distutils/command/bdist_dumb.py
M Lib/distutils/command/bdist_msi.py
M Lib/distutils/command/bdist_rpm.py
M Lib/distutils/command/bdist_wininst.py
M Lib/distutils/command/build_ext.py
M Lib/email/_header_value_parser.py
M Lib/idlelib/hyperparser.py
M Lib/idlelib/idle_test/htest.py
M Lib/idlelib/idle_test/mock_tk.py
M Lib/importlib/abc.py
M Lib/test/test_builtin.py
M Lib/test/test_compile.py
M Lib/test/test_decimal.py
M Lib/test/test_http_cookiejar.py
M Lib/test/test_range.py
M Lib/test/test_smtplib.py
M Lib/test/test_strptime.py
M Lib/trace.py
M Lib/unittest/mock.py
M Modules/_datetimemodule.c
M Modules/_io/textio.c
M Modules/_pickle.c
M Python/import.c
M Tools/scripts/texi2html.py
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 359690003fe1..44ea5b41b2a1 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -2021,7 +2021,7 @@ def _power_modulo(self, other, modulo, context=None):
if not other and not self:
return context._raise_error(InvalidOperation,
'at least one of pow() 1st argument '
- 'and 2nd argument must be nonzero ;'
+ 'and 2nd argument must be nonzero; '
'0**0 is not defined')
# compute sign of result
diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py
index b65dee11f727..78359711d5d9 100644
--- a/Lib/concurrent/futures/thread.py
+++ b/Lib/concurrent/futures/thread.py
@@ -150,7 +150,7 @@ def submit(self, fn, *args, **kwargs):
if self._shutdown:
raise RuntimeError('cannot schedule new futures after shutdown')
if _shutdown:
- raise RuntimeError('cannot schedule new futures after'
+ raise RuntimeError('cannot schedule new futures after '
'interpreter shutdown')
f = _base.Future()
diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py
index e9274d925afa..f0d6b5b8cd8a 100644
--- a/Lib/distutils/command/bdist_dumb.py
+++ b/Lib/distutils/command/bdist_dumb.py
@@ -32,7 +32,7 @@ class bdist_dumb(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('relative', None,
- "build the archive using relative paths"
+ "build the archive using relative paths "
"(default: false)"),
('owner=', 'u',
"Owner name used when creating a tar file"
diff --git a/Lib/distutils/command/bdist_msi.py b/Lib/distutils/command/bdist_msi.py
index a4bd5a589d38..80104c372d9a 100644
--- a/Lib/distutils/command/bdist_msi.py
+++ b/Lib/distutils/command/bdist_msi.py
@@ -98,14 +98,14 @@ class bdist_msi(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py
index ac4621791d56..02f10dd89d91 100644
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -58,7 +58,7 @@ class bdist_rpm(Command):
"RPM \"vendor\" (eg. \"Joe Blow <joe(a)example.com>\") "
"[default: maintainer or author from setup script]"),
('packager=', None,
- "RPM packager (eg. \"Jane Doe <jane(a)example.net>\")"
+ "RPM packager (eg. \"Jane Doe <jane(a)example.net>\") "
"[default: vendor]"),
('doc-files=', None,
"list of documentation files (space or comma-separated)"),
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 0871a4f7d6b2..fde56754e891 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -29,7 +29,7 @@ class bdist_wininst(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
@@ -40,7 +40,7 @@ class bdist_wininst(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 8fad9cdc2b47..158465d2338c 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -365,7 +365,7 @@ def check_extensions_list(self, extensions):
ext_name, build_info = ext
log.warn("old-style (ext_name, build_info) tuple found in "
- "ext_modules for extension '%s'"
+ "ext_modules for extension '%s' "
"-- please convert to Extension instance", ext_name)
if not (isinstance(ext_name, str) and
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index e805a75fbd93..416da1a80d9c 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -2209,8 +2209,8 @@ def get_section(value):
digits += value[0]
value = value[1:]
if digits[0] == '0' and digits != '0':
- section.defects.append(errors.InvalidHeaderError("section number"
- "has an invalid leading 0"))
+ section.defects.append(errors.InvalidHeaderError(
+ "section number has an invalid leading 0"))
section.number = int(digits)
section.append(ValueTerminal(digits, 'digits'))
return section, value
diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py
index 7581fe274b21..7e7e0ae80247 100644
--- a/Lib/idlelib/hyperparser.py
+++ b/Lib/idlelib/hyperparser.py
@@ -224,7 +224,7 @@ def get_expression(self):
given index, which is empty if there is no real one.
"""
if not self.is_in_code():
- raise ValueError("get_expression should only be called"
+ raise ValueError("get_expression should only be called "
"if index is inside a code.")
rawtext = self.rawtext
diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py
index 8c1c24d070cc..583e607b767e 100644
--- a/Lib/idlelib/idle_test/htest.py
+++ b/Lib/idlelib/idle_test/htest.py
@@ -117,7 +117,7 @@ def _wrapper(parent): # htest #
"font face of the text in the area below it.\nIn the "
"'Highlighting' tab, try different color schemes. Clicking "
"items in the sample program should update the choices above it."
- "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings"
+ "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings "
"of interest."
"\n[Ok] to close the dialog.[Apply] to apply the settings and "
"and [Cancel] to revert all changes.\nRe-run the test to ensure "
@@ -152,7 +152,7 @@ def _wrapper(parent): # htest #
'msg': "Test for different key modifier sequences.\n"
"<nothing> is invalid.\n"
"No modifier key is invalid.\n"
- "Shift key with [a-z],[0-9], function key, move key, tab, space"
+ "Shift key with [a-z],[0-9], function key, move key, tab, space "
"is invalid.\nNo validity checking if advanced key binding "
"entry is used."
}
@@ -234,7 +234,7 @@ def _wrapper(parent): # htest #
'file': 'percolator',
'kwds': {},
'msg': "There are two tracers which can be toggled using a checkbox.\n"
- "Toggling a tracer 'on' by checking it should print tracer"
+ "Toggling a tracer 'on' by checking it should print tracer "
"output to the console or to the IDLE shell.\n"
"If both the tracers are 'on', the output from the tracer which "
"was switched 'on' later, should be printed first\n"
@@ -335,7 +335,7 @@ def _wrapper(parent): # htest #
_widget_redirector_spec = {
'file': 'redirector',
'kwds': {},
- 'msg': "Every text insert should be printed to the console."
+ 'msg': "Every text insert should be printed to the console "
"or the IDLE shell."
}
diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py
index 6e351297d75d..a54f51f1949c 100644
--- a/Lib/idlelib/idle_test/mock_tk.py
+++ b/Lib/idlelib/idle_test/mock_tk.py
@@ -260,7 +260,7 @@ def compare(self, index1, op, index2):
elif op == '!=':
return line1 != line2 or char1 != char2
else:
- raise TclError('''bad comparison operator "%s":'''
+ raise TclError('''bad comparison operator "%s": '''
'''must be <, <=, ==, >=, >, or !=''' % op)
# The following Text methods normally do something and return None.
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index dbdd5bf64192..4b2d3de6d96f 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -66,7 +66,7 @@ def find_module(self, fullname, path):
"""
warnings.warn("MetaPathFinder.find_module() is deprecated since Python "
- "3.4 in favor of MetaPathFinder.find_spec()"
+ "3.4 in favor of MetaPathFinder.find_spec() "
"(available since 3.4)",
DeprecationWarning,
stacklevel=2)
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index e7202cd70c9c..7c9768a337bb 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1600,7 +1600,7 @@ def test_envar_good_path_empty_string(self):
@unittest.skipIf(sys.flags.ignore_environment, '-E was given')
def test_envar_unimportable(self):
for envar in (
- '.', '..', '.foo', 'foo.', '.int', 'int.'
+ '.', '..', '.foo', 'foo.', '.int', 'int.',
'nosuchbuiltin',
'nosuchmodule.nosuchcallable',
):
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index acebdbdc4636..d8a57e5e0925 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -285,7 +285,7 @@ def test_import(self):
'from sys import stdin)',
'from sys import stdin, stdout,\nstderr',
'from sys import stdin si',
- 'from sys import stdin,'
+ 'from sys import stdin,',
'from sys import (*)',
'from sys import (stdin,, stdout, stderr)',
'from sys import (stdin, stdout),',
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 58bde54b0a88..1f37b5372a3e 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1172,10 +1172,10 @@ def test_wide_char_separator_decimal_point(self):
decimal_point = locale.localeconv()['decimal_point']
thousands_sep = locale.localeconv()['thousands_sep']
if decimal_point != '\u066b':
- self.skipTest('inappropriate decimal point separator'
+ self.skipTest('inappropriate decimal point separator '
'({!a} not {!a})'.format(decimal_point, '\u066b'))
if thousands_sep != '\u066c':
- self.skipTest('inappropriate thousands separator'
+ self.skipTest('inappropriate thousands separator '
'({!a} not {!a})'.format(thousands_sep, '\u066c'))
self.assertEqual(format(Decimal('100000000.123'), 'n'),
diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py
index 6fee4df10a40..abc625d672a7 100644
--- a/Lib/test/test_http_cookiejar.py
+++ b/Lib/test/test_http_cookiejar.py
@@ -174,12 +174,10 @@ def test_iso2time_garbage(self):
'1980-01-01 00:61:00',
'01-01-1980 00:00:62',
'01-01-1980T00:00:62',
- '19800101T250000Z'
- '1980-01-01 00:00:00 -2500',
+ '19800101T250000Z',
]:
self.assertIsNone(iso2time(test),
- "iso2time(%s) is not None\n"
- "iso2time(test) %s" % (test, iso2time(test)))
+ "iso2time(%r)" % test)
class HeaderTests(unittest.TestCase):
diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py
index ce1584748d7e..94c96a941b12 100644
--- a/Lib/test/test_range.py
+++ b/Lib/test/test_range.py
@@ -39,7 +39,7 @@ def assert_iterators_equal(self, xs, ys, test_id, limit=None):
self.fail('{}: unexpected excess element {} at '
'position {}'.format(test_id, x, i))
else:
- self.fail('{}: wrong element at position {};'
+ self.fail('{}: wrong element at position {}; '
'expected {}, got {}'.format(test_id, i, y, x))
def test_range(self):
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 8a29e98a4f30..b4149d3ef007 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -770,7 +770,7 @@ def _auth_cram_md5(self, arg=None):
try:
user, hashed_pass = logpass.split()
except ValueError as e:
- self.push('535 Splitting response {!r} into user and password'
+ self.push('535 Splitting response {!r} into user and password '
'failed: {}'.format(logpass, e))
return False
valid_hashed_pass = hmac.HMAC(
diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py
index de2773f6aa29..a3358a493e53 100644
--- a/Lib/test/test_strptime.py
+++ b/Lib/test/test_strptime.py
@@ -506,7 +506,7 @@ def test_gregorian_calculation(self):
self.assertTrue(result.tm_year == self.time_tuple.tm_year and
result.tm_mon == self.time_tuple.tm_mon and
result.tm_mday == self.time_tuple.tm_mday,
- "Calculation of Gregorian date failed;"
+ "Calculation of Gregorian date failed; "
"%s-%s-%s != %s-%s-%s" %
(result.tm_year, result.tm_mon, result.tm_mday,
self.time_tuple.tm_year, self.time_tuple.tm_mon,
@@ -518,7 +518,7 @@ def test_day_of_week_calculation(self):
result = _strptime._strptime_time(time.strftime(format_string, self.time_tuple),
format_string)
self.assertTrue(result.tm_wday == self.time_tuple.tm_wday,
- "Calculation of day of the week failed;"
+ "Calculation of day of the week failed; "
"%s != %s" % (result.tm_wday, self.time_tuple.tm_wday))
if support.is_android:
diff --git a/Lib/trace.py b/Lib/trace.py
index 86b2101763bf..0ed7ba95b520 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -299,7 +299,7 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None):
try:
outfile = open(path, "w", encoding=encoding)
except OSError as err:
- print(("trace: Could not open %r for writing: %s"
+ print(("trace: Could not open %r for writing: %s "
"- skipping" % (path, err)), file=sys.stderr)
return 0, 0
@@ -644,7 +644,7 @@ def main():
grp = parser.add_argument_group('Filters',
'Can be specified multiple times')
grp.add_argument('--ignore-module', action='append', default=[],
- help='Ignore the given module(s) and its submodules'
+ help='Ignore the given module(s) and its submodules '
'(if it is a package). Accepts comma separated list of '
'module names.')
grp.add_argument('--ignore-dir', action='append', default=[],
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1a6c251d2cf7..b0c03c03bd6f 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1749,7 +1749,7 @@ def method(self, *args, **kw):
_unsupported_magics = {
'__getattr__', '__setattr__',
- '__init__', '__new__', '__prepare__'
+ '__init__', '__new__', '__prepare__',
'__instancecheck__', '__subclasscheck__',
'__del__'
}
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index f53880808d21..1f15367d3fa3 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -3443,7 +3443,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
return result;
Inconsistent:
- PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
+ PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
"inconsistent results; cannot convert");
/* fall through to failure */
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 73d1b2e8a23b..9d0d9cac40db 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1313,7 +1313,7 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
/* Check if something is in the read buffer */
if (self->decoded_chars != NULL) {
if (encoding != Py_None || errors != Py_None || newline_obj != NULL) {
- _unsupported("It is not possible to set the encoding or newline"
+ _unsupported("It is not possible to set the encoding or newline "
"of stream after the first read");
return NULL;
}
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index ba8962d686de..03f575e4621c 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -4614,7 +4614,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be a PicklerMemoProxy object"
+ "'memo' attribute must be a PicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
@@ -7060,7 +7060,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be an UnpicklerMemoProxy object"
+ "'memo' attribute must be an UnpicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
diff --git a/Python/import.c b/Python/import.c
index 5d1794720cfc..709fc4324e6f 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -833,7 +833,7 @@ remove_module(PyObject *name)
if (!PyMapping_HasKey(modules, name)) {
return;
}
- Py_FatalError("import: deleting existing key in"
+ Py_FatalError("import: deleting existing key in "
"sys.modules failed");
}
}
diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py
index 9c1e9fe8d8c4..5565c210dabb 100755
--- a/Tools/scripts/texi2html.py
+++ b/Tools/scripts/texi2html.py
@@ -1806,7 +1806,7 @@ def finalize(self):
print('<!-- This file defines the table of contents -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
@@ -1831,7 +1831,7 @@ def finalize(self):
print('<!-- This file defines the index -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284)
by Serhiy Storchaka 05 Nov '18
by Serhiy Storchaka 05 Nov '18
05 Nov '18
https://github.com/python/cpython/commit/34fd4c20198dea6ab2fe8dc6d32d744d9b…
commit: 34fd4c20198dea6ab2fe8dc6d32d744d9bde868d
branch: master
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-05T16:20:25+02:00
summary:
bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284)
Two kind of mistakes:
1. Missed space. After concatenating there is no space between words.
2. Missed comma. Causes unintentional concatenating in a list of strings.
files:
M Lib/_pydecimal.py
M Lib/concurrent/futures/thread.py
M Lib/distutils/command/bdist_dumb.py
M Lib/distutils/command/bdist_msi.py
M Lib/distutils/command/bdist_rpm.py
M Lib/distutils/command/bdist_wininst.py
M Lib/distutils/command/build_ext.py
M Lib/email/_header_value_parser.py
M Lib/idlelib/hyperparser.py
M Lib/idlelib/idle_test/htest.py
M Lib/idlelib/idle_test/mock_tk.py
M Lib/importlib/abc.py
M Lib/test/test_builtin.py
M Lib/test/test_compile.py
M Lib/test/test_decimal.py
M Lib/test/test_http_cookiejar.py
M Lib/test/test_range.py
M Lib/test/test_smtplib.py
M Lib/test/test_strptime.py
M Lib/trace.py
M Lib/unittest/mock.py
M Modules/_datetimemodule.c
M Modules/_io/textio.c
M Modules/_pickle.c
M Python/import.c
M Tools/scripts/texi2html.py
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 359690003fe1..44ea5b41b2a1 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -2021,7 +2021,7 @@ def _power_modulo(self, other, modulo, context=None):
if not other and not self:
return context._raise_error(InvalidOperation,
'at least one of pow() 1st argument '
- 'and 2nd argument must be nonzero ;'
+ 'and 2nd argument must be nonzero; '
'0**0 is not defined')
# compute sign of result
diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py
index b65dee11f727..78359711d5d9 100644
--- a/Lib/concurrent/futures/thread.py
+++ b/Lib/concurrent/futures/thread.py
@@ -150,7 +150,7 @@ def submit(self, fn, *args, **kwargs):
if self._shutdown:
raise RuntimeError('cannot schedule new futures after shutdown')
if _shutdown:
- raise RuntimeError('cannot schedule new futures after'
+ raise RuntimeError('cannot schedule new futures after '
'interpreter shutdown')
f = _base.Future()
diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py
index e9274d925afa..f0d6b5b8cd8a 100644
--- a/Lib/distutils/command/bdist_dumb.py
+++ b/Lib/distutils/command/bdist_dumb.py
@@ -32,7 +32,7 @@ class bdist_dumb(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('relative', None,
- "build the archive using relative paths"
+ "build the archive using relative paths "
"(default: false)"),
('owner=', 'u',
"Owner name used when creating a tar file"
diff --git a/Lib/distutils/command/bdist_msi.py b/Lib/distutils/command/bdist_msi.py
index a4bd5a589d38..80104c372d9a 100644
--- a/Lib/distutils/command/bdist_msi.py
+++ b/Lib/distutils/command/bdist_msi.py
@@ -98,14 +98,14 @@ class bdist_msi(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py
index ac4621791d56..02f10dd89d91 100644
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -58,7 +58,7 @@ class bdist_rpm(Command):
"RPM \"vendor\" (eg. \"Joe Blow <joe(a)example.com>\") "
"[default: maintainer or author from setup script]"),
('packager=', None,
- "RPM packager (eg. \"Jane Doe <jane(a)example.net>\")"
+ "RPM packager (eg. \"Jane Doe <jane(a)example.net>\") "
"[default: vendor]"),
('doc-files=', None,
"list of documentation files (space or comma-separated)"),
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 0871a4f7d6b2..fde56754e891 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -29,7 +29,7 @@ class bdist_wininst(Command):
('no-target-compile', 'c',
"do not compile .py to .pyc on the target system"),
('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized)"
+ "do not compile .py to .pyo (optimized) "
"on the target system"),
('dist-dir=', 'd',
"directory to put final built distributions in"),
@@ -40,7 +40,7 @@ class bdist_wininst(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
('install-script=', None,
- "basename of installation script to be run after"
+ "basename of installation script to be run after "
"installation or before deinstallation"),
('pre-install-script=', None,
"Fully qualified filename of a script to be run before "
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 8fad9cdc2b47..158465d2338c 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -365,7 +365,7 @@ def check_extensions_list(self, extensions):
ext_name, build_info = ext
log.warn("old-style (ext_name, build_info) tuple found in "
- "ext_modules for extension '%s'"
+ "ext_modules for extension '%s' "
"-- please convert to Extension instance", ext_name)
if not (isinstance(ext_name, str) and
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index e805a75fbd93..416da1a80d9c 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -2209,8 +2209,8 @@ def get_section(value):
digits += value[0]
value = value[1:]
if digits[0] == '0' and digits != '0':
- section.defects.append(errors.InvalidHeaderError("section number"
- "has an invalid leading 0"))
+ section.defects.append(errors.InvalidHeaderError(
+ "section number has an invalid leading 0"))
section.number = int(digits)
section.append(ValueTerminal(digits, 'digits'))
return section, value
diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py
index 7581fe274b21..7e7e0ae80247 100644
--- a/Lib/idlelib/hyperparser.py
+++ b/Lib/idlelib/hyperparser.py
@@ -224,7 +224,7 @@ def get_expression(self):
given index, which is empty if there is no real one.
"""
if not self.is_in_code():
- raise ValueError("get_expression should only be called"
+ raise ValueError("get_expression should only be called "
"if index is inside a code.")
rawtext = self.rawtext
diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py
index 8c1c24d070cc..583e607b767e 100644
--- a/Lib/idlelib/idle_test/htest.py
+++ b/Lib/idlelib/idle_test/htest.py
@@ -117,7 +117,7 @@ def _wrapper(parent): # htest #
"font face of the text in the area below it.\nIn the "
"'Highlighting' tab, try different color schemes. Clicking "
"items in the sample program should update the choices above it."
- "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings"
+ "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings "
"of interest."
"\n[Ok] to close the dialog.[Apply] to apply the settings and "
"and [Cancel] to revert all changes.\nRe-run the test to ensure "
@@ -152,7 +152,7 @@ def _wrapper(parent): # htest #
'msg': "Test for different key modifier sequences.\n"
"<nothing> is invalid.\n"
"No modifier key is invalid.\n"
- "Shift key with [a-z],[0-9], function key, move key, tab, space"
+ "Shift key with [a-z],[0-9], function key, move key, tab, space "
"is invalid.\nNo validity checking if advanced key binding "
"entry is used."
}
@@ -234,7 +234,7 @@ def _wrapper(parent): # htest #
'file': 'percolator',
'kwds': {},
'msg': "There are two tracers which can be toggled using a checkbox.\n"
- "Toggling a tracer 'on' by checking it should print tracer"
+ "Toggling a tracer 'on' by checking it should print tracer "
"output to the console or to the IDLE shell.\n"
"If both the tracers are 'on', the output from the tracer which "
"was switched 'on' later, should be printed first\n"
@@ -335,7 +335,7 @@ def _wrapper(parent): # htest #
_widget_redirector_spec = {
'file': 'redirector',
'kwds': {},
- 'msg': "Every text insert should be printed to the console."
+ 'msg': "Every text insert should be printed to the console "
"or the IDLE shell."
}
diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py
index 6e351297d75d..a54f51f1949c 100644
--- a/Lib/idlelib/idle_test/mock_tk.py
+++ b/Lib/idlelib/idle_test/mock_tk.py
@@ -260,7 +260,7 @@ def compare(self, index1, op, index2):
elif op == '!=':
return line1 != line2 or char1 != char2
else:
- raise TclError('''bad comparison operator "%s":'''
+ raise TclError('''bad comparison operator "%s": '''
'''must be <, <=, ==, >=, >, or !=''' % op)
# The following Text methods normally do something and return None.
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index dbdd5bf64192..4b2d3de6d96f 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -66,7 +66,7 @@ def find_module(self, fullname, path):
"""
warnings.warn("MetaPathFinder.find_module() is deprecated since Python "
- "3.4 in favor of MetaPathFinder.find_spec()"
+ "3.4 in favor of MetaPathFinder.find_spec() "
"(available since 3.4)",
DeprecationWarning,
stacklevel=2)
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index dafcf004c095..e2a4f2fa6d2f 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1607,7 +1607,7 @@ def test_envar_good_path_empty_string(self):
@unittest.skipIf(sys.flags.ignore_environment, '-E was given')
def test_envar_unimportable(self):
for envar in (
- '.', '..', '.foo', 'foo.', '.int', 'int.'
+ '.', '..', '.foo', 'foo.', '.int', 'int.',
'nosuchbuiltin',
'nosuchmodule.nosuchcallable',
):
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 6b45a2433438..6851f84b85a6 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -285,7 +285,7 @@ def test_import(self):
'from sys import stdin)',
'from sys import stdin, stdout,\nstderr',
'from sys import stdin si',
- 'from sys import stdin,'
+ 'from sys import stdin,',
'from sys import (*)',
'from sys import (stdin,, stdout, stderr)',
'from sys import (stdin, stdout),',
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 58bde54b0a88..1f37b5372a3e 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1172,10 +1172,10 @@ def test_wide_char_separator_decimal_point(self):
decimal_point = locale.localeconv()['decimal_point']
thousands_sep = locale.localeconv()['thousands_sep']
if decimal_point != '\u066b':
- self.skipTest('inappropriate decimal point separator'
+ self.skipTest('inappropriate decimal point separator '
'({!a} not {!a})'.format(decimal_point, '\u066b'))
if thousands_sep != '\u066c':
- self.skipTest('inappropriate thousands separator'
+ self.skipTest('inappropriate thousands separator '
'({!a} not {!a})'.format(thousands_sep, '\u066c'))
self.assertEqual(format(Decimal('100000000.123'), 'n'),
diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py
index 968725901f22..8dbea3325d9b 100644
--- a/Lib/test/test_http_cookiejar.py
+++ b/Lib/test/test_http_cookiejar.py
@@ -174,12 +174,10 @@ def test_iso2time_garbage(self):
'1980-01-01 00:61:00',
'01-01-1980 00:00:62',
'01-01-1980T00:00:62',
- '19800101T250000Z'
- '1980-01-01 00:00:00 -2500',
+ '19800101T250000Z',
]:
self.assertIsNone(iso2time(test),
- "iso2time(%s) is not None\n"
- "iso2time(test) %s" % (test, iso2time(test)))
+ "iso2time(%r)" % test)
class HeaderTests(unittest.TestCase):
diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py
index ce1584748d7e..94c96a941b12 100644
--- a/Lib/test/test_range.py
+++ b/Lib/test/test_range.py
@@ -39,7 +39,7 @@ def assert_iterators_equal(self, xs, ys, test_id, limit=None):
self.fail('{}: unexpected excess element {} at '
'position {}'.format(test_id, x, i))
else:
- self.fail('{}: wrong element at position {};'
+ self.fail('{}: wrong element at position {}; '
'expected {}, got {}'.format(test_id, i, y, x))
def test_range(self):
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 07d760bd01fd..fdcf6f219256 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -805,7 +805,7 @@ def _auth_cram_md5(self, arg=None):
try:
user, hashed_pass = logpass.split()
except ValueError as e:
- self.push('535 Splitting response {!r} into user and password'
+ self.push('535 Splitting response {!r} into user and password '
'failed: {}'.format(logpass, e))
return False
valid_hashed_pass = hmac.HMAC(
diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py
index de2773f6aa29..a3358a493e53 100644
--- a/Lib/test/test_strptime.py
+++ b/Lib/test/test_strptime.py
@@ -506,7 +506,7 @@ def test_gregorian_calculation(self):
self.assertTrue(result.tm_year == self.time_tuple.tm_year and
result.tm_mon == self.time_tuple.tm_mon and
result.tm_mday == self.time_tuple.tm_mday,
- "Calculation of Gregorian date failed;"
+ "Calculation of Gregorian date failed; "
"%s-%s-%s != %s-%s-%s" %
(result.tm_year, result.tm_mon, result.tm_mday,
self.time_tuple.tm_year, self.time_tuple.tm_mon,
@@ -518,7 +518,7 @@ def test_day_of_week_calculation(self):
result = _strptime._strptime_time(time.strftime(format_string, self.time_tuple),
format_string)
self.assertTrue(result.tm_wday == self.time_tuple.tm_wday,
- "Calculation of day of the week failed;"
+ "Calculation of day of the week failed; "
"%s != %s" % (result.tm_wday, self.time_tuple.tm_wday))
if support.is_android:
diff --git a/Lib/trace.py b/Lib/trace.py
index 86b2101763bf..0ed7ba95b520 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -299,7 +299,7 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None):
try:
outfile = open(path, "w", encoding=encoding)
except OSError as err:
- print(("trace: Could not open %r for writing: %s"
+ print(("trace: Could not open %r for writing: %s "
"- skipping" % (path, err)), file=sys.stderr)
return 0, 0
@@ -644,7 +644,7 @@ def main():
grp = parser.add_argument_group('Filters',
'Can be specified multiple times')
grp.add_argument('--ignore-module', action='append', default=[],
- help='Ignore the given module(s) and its submodules'
+ help='Ignore the given module(s) and its submodules '
'(if it is a package). Accepts comma separated list of '
'module names.')
grp.add_argument('--ignore-dir', action='append', default=[],
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1977b870834b..a9c82dcb5d3e 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1772,7 +1772,7 @@ def method(self, *args, **kw):
_unsupported_magics = {
'__getattr__', '__setattr__',
- '__init__', '__new__', '__prepare__'
+ '__init__', '__new__', '__prepare__',
'__instancecheck__', '__subclasscheck__',
'__del__'
}
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index bc4caa02d5f1..2db95b45345b 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -3446,7 +3446,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
return result;
Inconsistent:
- PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
+ PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
"inconsistent results; cannot convert");
/* fall through to failure */
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index be427772817a..8924834eb81c 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1313,7 +1313,7 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
/* Check if something is in the read buffer */
if (self->decoded_chars != NULL) {
if (encoding != Py_None || errors != Py_None || newline_obj != NULL) {
- _unsupported("It is not possible to set the encoding or newline"
+ _unsupported("It is not possible to set the encoding or newline "
"of stream after the first read");
return NULL;
}
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 0e3bd225dbd8..2166d296abe4 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -4612,7 +4612,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be a PicklerMemoProxy object"
+ "'memo' attribute must be a PicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
@@ -7048,7 +7048,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
}
else {
PyErr_Format(PyExc_TypeError,
- "'memo' attribute must be an UnpicklerMemoProxy object"
+ "'memo' attribute must be an UnpicklerMemoProxy object "
"or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
diff --git a/Python/import.c b/Python/import.c
index 67911ff0e41b..c0ea968fb8b0 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -839,7 +839,7 @@ remove_module(PyObject *name)
if (!PyMapping_HasKey(modules, name)) {
return;
}
- Py_FatalError("import: deleting existing key in"
+ Py_FatalError("import: deleting existing key in "
"sys.modules failed");
}
}
diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py
index 9c1e9fe8d8c4..5565c210dabb 100755
--- a/Tools/scripts/texi2html.py
+++ b/Tools/scripts/texi2html.py
@@ -1806,7 +1806,7 @@ def finalize(self):
print('<!-- This file defines the table of contents -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
@@ -1831,7 +1831,7 @@ def finalize(self):
print('<!-- This file defines the index -->', file=fp)
print('<HTML>', file=fp)
print('<HEAD>', file=fp)
- print('<meta name="GENERATOR"'
+ print('<meta name="GENERATOR" '
'content="Microsoft® HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp)
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
05 Nov '18
https://github.com/python/cpython/commit/ad1a25f499362eaf9cbfcafa0b8e2454eb…
commit: ad1a25f499362eaf9cbfcafa0b8e2454eb43dcf1
branch: master
author: Mario Corchero <mariocj89(a)gmail.com>
committer: Nick Coghlan <ncoghlan(a)gmail.com>
date: 2018-11-05T22:03:46+10:00
summary:
bpo-32512: Add -m option to profile for profiling modules (#5132)
The new option in the CLI of the profile module allow to profile
executable modules. This change follows the same implementation as the
one already present in `cProfile`.
As the argument is now present on both modules, move the tests to the
common test case to be run with profile as well.
files:
A Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst
M Doc/library/profile.rst
M Lib/profile.py
M Lib/test/test_cprofile.py
M Lib/test/test_profile.py
diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst
index 1a772fb7f941..9ceb81603c95 100644
--- a/Doc/library/profile.rst
+++ b/Doc/library/profile.rst
@@ -120,8 +120,8 @@ results to a file by specifying a filename to the :func:`run` function::
The :class:`pstats.Stats` class reads profile results from a file and formats
them in various ways.
-The file :mod:`cProfile` can also be invoked as a script to profile another
-script. For example::
+The files :mod:`cProfile` and :mod:`profile` can also be invoked as a script to
+profile another script. For example::
python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)
@@ -133,7 +133,10 @@ the output by. This only applies when ``-o`` is not supplied.
``-m`` specifies that a module is being profiled instead of a script.
.. versionadded:: 3.7
- Added the ``-m`` option.
+ Added the ``-m`` option to :mod:`cProfile`.
+
+ .. versionadded:: 3.8
+ Added the ``-m`` option to :mod:`profile`.
The :mod:`pstats` module's :class:`~pstats.Stats` class has a variety of methods
for manipulating and printing the data saved into a profile results file::
diff --git a/Lib/profile.py b/Lib/profile.py
index 0340a7907bfd..5df43604acdd 100755
--- a/Lib/profile.py
+++ b/Lib/profile.py
@@ -553,11 +553,13 @@ def main():
import os
from optparse import OptionParser
- usage = "profile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
+ usage = "profile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
parser = OptionParser(usage=usage)
parser.allow_interspersed_args = False
parser.add_option('-o', '--outfile', dest="outfile",
help="Save stats to <outfile>", default=None)
+ parser.add_option('-m', dest="module", action="store_true",
+ help="Profile a library module.", default=False)
parser.add_option('-s', '--sort', dest="sort",
help="Sort order when printing to stdout, based on pstats.Stats class",
default=-1)
@@ -570,16 +572,24 @@ def main():
sys.argv[:] = args
if len(args) > 0:
- progname = args[0]
- sys.path.insert(0, os.path.dirname(progname))
- with open(progname, 'rb') as fp:
- code = compile(fp.read(), progname, 'exec')
- globs = {
- '__file__': progname,
- '__name__': '__main__',
- '__package__': None,
- '__cached__': None,
- }
+ if options.module:
+ import runpy
+ code = "run_module(modname, run_name='__main__')"
+ globs = {
+ 'run_module': runpy.run_module,
+ 'modname': args[0]
+ }
+ else:
+ progname = args[0]
+ sys.path.insert(0, os.path.dirname(progname))
+ with open(progname, 'rb') as fp:
+ code = compile(fp.read(), progname, 'exec')
+ globs = {
+ '__file__': progname,
+ '__name__': '__main__',
+ '__package__': None,
+ '__cached__': None,
+ }
runctx(code, globs, None, options.outfile, options.sort)
else:
parser.print_usage()
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 406d70305f9e..efcf6bc92803 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -37,19 +37,6 @@ def test_bad_counter_during_dealloc(self):
finally:
unlink(TESTFN)
- # Issue 21862
- def test_module_path_option(self):
- # Test -m switch with modules
-
- # Test that -m switch needs an argument
- assert_python_failure('-m', 'cProfile', '-m')
-
- # Test failure for not-existent module
- assert_python_failure('-m', 'cProfile', '-m', 'random_module_xyz')
-
- # Test successful run
- assert_python_ok('-m', 'cProfile', '-m', 'timeit', '-n', '1')
-
def test_profile_enable_disable(self):
prof = self.profilerclass()
# Make sure we clean ourselves up if the test fails for some reason.
diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py
index a9982663175a..01a8a6eaf5a2 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -11,6 +11,7 @@
import profile
from test.profilee import testfunc, timer
+from test.support.script_helper import assert_python_failure, assert_python_ok
class ProfileTest(unittest.TestCase):
@@ -98,6 +99,18 @@ def test_runctx(self):
filename=TESTFN)
self.assertTrue(os.path.exists(TESTFN))
+ def test_run_profile_as_module(self):
+ # Test that -m switch needs an argument
+ assert_python_failure('-m', self.profilermodule.__name__, '-m')
+
+ # Test failure for not-existent module
+ assert_python_failure('-m', self.profilermodule.__name__,
+ '-m', 'random_module_xyz')
+
+ # Test successful run
+ assert_python_ok('-m', self.profilermodule.__name__,
+ '-m', 'timeit', '-n', '1')
+
def regenerate_expected_output(filename, cls):
filename = filename.rstrip('co')
diff --git a/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst b/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst
new file mode 100644
index 000000000000..0a7763daffad
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst
@@ -0,0 +1,2 @@
+:mod:`profile` CLI accepts `-m module_name` as an alternative to
+script path.
1
0
results for 4243df51fe43 on branch "default"
--------------------------------------------
test_collections leaked [7, -7, 1] memory blocks, sum=1
test_functools leaked [0, 3, 1] memory blocks, sum=4
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogFILtoQ', '--timeout', '7200']
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
04 Nov '18
https://github.com/python/cpython/commit/2810dd7be9876236f74ac80716d113572c…
commit: 2810dd7be9876236f74ac80716d113572c9098dd
branch: master
author: Max Bélanger <aeromax(a)gmail.com>
committer: Benjamin Peterson <benjamin(a)python.org>
date: 2018-11-04T15:58:24-08:00
summary:
closes bpo-32285: Add unicodedata.is_normalized. (GH-4806)
files:
A Misc/NEWS.d/next/Core and Builtins/2017-12-12-13-43-13.bpo-32285.LzKSwz.rst
M Doc/library/unicodedata.rst
M Doc/whatsnew/3.8.rst
M Lib/test/test_normalization.py
M Modules/clinic/unicodedata.c.h
M Modules/unicodedata.c
diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst
index 59548f3e8b4a..17e848bf552b 100644
--- a/Doc/library/unicodedata.rst
+++ b/Doc/library/unicodedata.rst
@@ -133,6 +133,13 @@ following functions:
a human reader, if one has combining characters and the other
doesn't, they may not compare equal.
+.. function:: is_normalized(form, unistr)
+
+ Return whether the Unicode string *unistr* is in the normal form *form*. Valid
+ values for *form* are 'NFC', 'NFKC', 'NFD', and 'NFKD'.
+
+ .. versionadded:: 3.8
+
In addition, the module exposes the following constant:
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 5397206030fe..566c369c85bd 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -204,6 +204,13 @@ Added method :meth:`~tkinter.Canvas.moveto`
in the :class:`tkinter.Canvas` class.
(Contributed by Juliette Monsel in :issue:`23831`.)
+unicodedata
+-----------
+
+* New function :func:`~unicodedata.is_normalized` can be used to verify a string
+ is in a specific normal form. (Contributed by Max Belanger and David Euresti in
+ :issue:`32285`).
+
venv
----
diff --git a/Lib/test/test_normalization.py b/Lib/test/test_normalization.py
index 304245644502..ba877e73f7d9 100644
--- a/Lib/test/test_normalization.py
+++ b/Lib/test/test_normalization.py
@@ -3,7 +3,7 @@
from http.client import HTTPException
import sys
-from unicodedata import normalize, unidata_version
+from unicodedata import normalize, is_normalized, unidata_version
TESTDATAFILE = "NormalizationTest.txt"
TESTDATAURL = "http://www.pythontest.net/unicode/" + unidata_version + "/" + TESTDATAFILE
@@ -88,6 +88,15 @@ def run_normalization_tests(self, testdata):
NFKD(c3) == NFKD(c4) == NFKD(c5),
line)
+ self.assertTrue(is_normalized("NFC", c2))
+ self.assertTrue(is_normalized("NFC", c4))
+
+ self.assertTrue(is_normalized("NFD", c3))
+ self.assertTrue(is_normalized("NFD", c5))
+
+ self.assertTrue(is_normalized("NFKC", c4))
+ self.assertTrue(is_normalized("NFKD", c5))
+
# Record part 1 data
if part == "@Part1":
part1_data[c1] = 1
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-12-13-43-13.bpo-32285.LzKSwz.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-12-13-43-13.bpo-32285.LzKSwz.rst
new file mode 100644
index 000000000000..87f84b02eb84
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-12-13-43-13.bpo-32285.LzKSwz.rst
@@ -0,0 +1,2 @@
+New function unicodedata.is_normalized, which can check whether a string is
+in a specific normal form.
diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h
index 72e3f6545778..54021fedba41 100644
--- a/Modules/clinic/unicodedata.c.h
+++ b/Modules/clinic/unicodedata.c.h
@@ -284,6 +284,38 @@ unicodedata_UCD_decomposition(PyObject *self, PyObject *arg)
return return_value;
}
+PyDoc_STRVAR(unicodedata_UCD_is_normalized__doc__,
+"is_normalized($self, form, unistr, /)\n"
+"--\n"
+"\n"
+"Return whether the Unicode string unistr is in the normal form \'form\'.\n"
+"\n"
+"Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'.");
+
+#define UNICODEDATA_UCD_IS_NORMALIZED_METHODDEF \
+ {"is_normalized", (PyCFunction)unicodedata_UCD_is_normalized, METH_FASTCALL, unicodedata_UCD_is_normalized__doc__},
+
+static PyObject *
+unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form,
+ PyObject *input);
+
+static PyObject *
+unicodedata_UCD_is_normalized(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *form;
+ PyObject *input;
+
+ if (!_PyArg_ParseStack(args, nargs, "UU:is_normalized",
+ &form, &input)) {
+ goto exit;
+ }
+ return_value = unicodedata_UCD_is_normalized_impl(self, form, input);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(unicodedata_UCD_normalize__doc__,
"normalize($self, form, unistr, /)\n"
"--\n"
@@ -296,17 +328,17 @@ PyDoc_STRVAR(unicodedata_UCD_normalize__doc__,
{"normalize", (PyCFunction)unicodedata_UCD_normalize, METH_FASTCALL, unicodedata_UCD_normalize__doc__},
static PyObject *
-unicodedata_UCD_normalize_impl(PyObject *self, const char *form,
+unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form,
PyObject *input);
static PyObject *
unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
- const char *form;
+ PyObject *form;
PyObject *input;
- if (!_PyArg_ParseStack(args, nargs, "sU:normalize",
+ if (!_PyArg_ParseStack(args, nargs, "UU:normalize",
&form, &input)) {
goto exit;
}
@@ -379,4 +411,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=dc899bff0ecd14c1 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2c5fbf597c18f6b8 input=a9049054013a1b77]*/
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index e8788f5036dd..9ceab1b3db4f 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -19,6 +19,11 @@
#include "ucnhash.h"
#include "structmember.h"
+_Py_IDENTIFIER(NFC);
+_Py_IDENTIFIER(NFD);
+_Py_IDENTIFIER(NFKC);
+_Py_IDENTIFIER(NFKD);
+
/*[clinic input]
module unicodedata
class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type'
@@ -770,8 +775,10 @@ nfc_nfkc(PyObject *self, PyObject *input, int k)
return result;
}
-/* Return 1 if the input is certainly normalized, 0 if it might not be. */
-static int
+typedef enum {YES, NO, MAYBE} NormalMode;
+
+/* Return YES if the input is certainly normalized, NO or MAYBE if it might not be. */
+static NormalMode
is_normalized(PyObject *self, PyObject *input, int nfc, int k)
{
Py_ssize_t i, len;
@@ -782,7 +789,7 @@ is_normalized(PyObject *self, PyObject *input, int nfc, int k)
/* An older version of the database is requested, quickchecks must be
disabled. */
if (self && UCD_Check(self))
- return 0;
+ return NO;
/* The two quickcheck bits at this shift mean 0=Yes, 1=Maybe, 2=No,
as described in http://unicode.org/reports/tr15/#Annex8. */
@@ -799,19 +806,92 @@ is_normalized(PyObject *self, PyObject *input, int nfc, int k)
unsigned char quickcheck = record->normalization_quick_check;
if (quickcheck & quickcheck_mask)
- return 0; /* this string might need normalization */
+ return MAYBE; /* this string might need normalization */
if (combining && prev_combining > combining)
- return 0; /* non-canonical sort order, not normalized */
+ return NO; /* non-canonical sort order, not normalized */
prev_combining = combining;
}
- return 1; /* certainly normalized */
+ return YES; /* certainly normalized */
+}
+
+/*[clinic input]
+unicodedata.UCD.is_normalized
+
+ self: self
+ form: unicode
+ unistr as input: unicode
+ /
+
+Return whether the Unicode string unistr is in the normal form 'form'.
+
+Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.
+[clinic start generated code]*/
+
+static PyObject *
+unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form,
+ PyObject *input)
+/*[clinic end generated code: output=11e5a3694e723ca5 input=a544f14cea79e508]*/
+{
+ if (PyUnicode_READY(input) == -1) {
+ return NULL;
+ }
+
+ if (PyUnicode_GET_LENGTH(input) == 0) {
+ /* special case empty input strings. */
+ Py_RETURN_TRUE;
+ }
+
+ PyObject *result;
+ int nfc = 0;
+ int k = 0;
+ NormalMode m;
+
+ PyObject *cmp;
+ int match = 0;
+
+ if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) {
+ nfc = 1;
+ }
+ else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) {
+ nfc = 1;
+ k = 1;
+ }
+ else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) {
+ /* matches default values for `nfc` and `k` */
+ }
+ else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) {
+ k = 1;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "invalid normalization form");
+ return NULL;
+ }
+
+ m = is_normalized(self, input, nfc, k);
+
+ if (m == MAYBE) {
+ cmp = (nfc ? nfc_nfkc : nfd_nfkd)(self, input, k);
+ if (cmp == NULL) {
+ return NULL;
+ }
+ match = PyUnicode_Compare(input, cmp);
+ Py_DECREF(cmp);
+ result = (match == 0) ? Py_True : Py_False;
+ }
+ else {
+ result = (m == YES) ? Py_True : Py_False;
+ }
+
+ Py_INCREF(result);
+ return result;
}
+
/*[clinic input]
unicodedata.UCD.normalize
self: self
- form: str
+ form: unicode
unistr as input: unicode
/
@@ -821,9 +901,9 @@ Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.
[clinic start generated code]*/
static PyObject *
-unicodedata_UCD_normalize_impl(PyObject *self, const char *form,
+unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form,
PyObject *input)
-/*[clinic end generated code: output=62d1f8870027efdc input=1744c55f4ab79bf0]*/
+/*[clinic end generated code: output=05ca4385a2ad6983 input=3a5206c0ad2833fb]*/
{
if (PyUnicode_GET_LENGTH(input) == 0) {
/* Special case empty input strings, since resizing
@@ -832,29 +912,29 @@ unicodedata_UCD_normalize_impl(PyObject *self, const char *form,
return input;
}
- if (strcmp(form, "NFC") == 0) {
- if (is_normalized(self, input, 1, 0)) {
+ if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) {
+ if (is_normalized(self, input, 1, 0) == YES) {
Py_INCREF(input);
return input;
}
return nfc_nfkc(self, input, 0);
}
- if (strcmp(form, "NFKC") == 0) {
- if (is_normalized(self, input, 1, 1)) {
+ if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) {
+ if (is_normalized(self, input, 1, 1) == YES) {
Py_INCREF(input);
return input;
}
return nfc_nfkc(self, input, 1);
}
- if (strcmp(form, "NFD") == 0) {
- if (is_normalized(self, input, 0, 0)) {
+ if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) {
+ if (is_normalized(self, input, 0, 0) == YES) {
Py_INCREF(input);
return input;
}
return nfd_nfkd(self, input, 0);
}
- if (strcmp(form, "NFKD") == 0) {
- if (is_normalized(self, input, 0, 1)) {
+ if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) {
+ if (is_normalized(self, input, 0, 1) == YES) {
Py_INCREF(input);
return input;
}
@@ -1271,6 +1351,7 @@ static PyMethodDef unicodedata_functions[] = {
UNICODEDATA_UCD_DECOMPOSITION_METHODDEF
UNICODEDATA_UCD_NAME_METHODDEF
UNICODEDATA_UCD_LOOKUP_METHODDEF
+ UNICODEDATA_UCD_IS_NORMALIZED_METHODDEF
UNICODEDATA_UCD_NORMALIZE_METHODDEF
{NULL, NULL} /* sentinel */
};
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-19675: Terminate processes if construction of a pool is failing. (GH-5614)
by Julien Palard 04 Nov '18
by Julien Palard 04 Nov '18
04 Nov '18
https://github.com/python/cpython/commit/5d236cafd7126e640fb25541fcc7e0a494…
commit: 5d236cafd7126e640fb25541fcc7e0a494450143
branch: master
author: Julien Palard <julien(a)palard.fr>
committer: GitHub <noreply(a)github.com>
date: 2018-11-04T23:40:32+01:00
summary:
bpo-19675: Terminate processes if construction of a pool is failing. (GH-5614)
files:
A Misc/NEWS.d/next/Library/2018-02-10-23-41-05.bpo-19675.-dj35-.rst
M Lib/multiprocessing/pool.py
M Lib/test/_test_multiprocessing.py
diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py
index 574b5db5afb6..7a6d01490146 100644
--- a/Lib/multiprocessing/pool.py
+++ b/Lib/multiprocessing/pool.py
@@ -174,7 +174,15 @@ def __init__(self, processes=None, initializer=None, initargs=(),
self._processes = processes
self._pool = []
- self._repopulate_pool()
+ try:
+ self._repopulate_pool()
+ except Exception:
+ for p in self._pool:
+ if p.exitcode is None:
+ p.terminate()
+ for p in self._pool:
+ p.join()
+ raise
self._worker_handler = threading.Thread(
target=Pool._handle_workers,
@@ -251,10 +259,10 @@ def _repopulate_pool_static(ctx, Process, processes, pool, inqueue,
initargs, maxtasksperchild,
wrap_exception)
)
- pool.append(w)
w.name = w.name.replace('Process', 'PoolWorker')
w.daemon = True
w.start()
+ pool.append(w)
util.debug('added worker')
@staticmethod
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index dc59e9fd740a..7993fcb08e46 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3,6 +3,7 @@
#
import unittest
+import unittest.mock
import queue as pyqueue
import contextlib
import time
@@ -4635,6 +4636,48 @@ def test_empty(self):
proc.join()
+class TestPoolNotLeakOnFailure(unittest.TestCase):
+
+ def test_release_unused_processes(self):
+ # Issue #19675: During pool creation, if we can't create a process,
+ # don't leak already created ones.
+ will_fail_in = 3
+ forked_processes = []
+
+ class FailingForkProcess:
+ def __init__(self, **kwargs):
+ self.name = 'Fake Process'
+ self.exitcode = None
+ self.state = None
+ forked_processes.append(self)
+
+ def start(self):
+ nonlocal will_fail_in
+ if will_fail_in <= 0:
+ raise OSError("Manually induced OSError")
+ will_fail_in -= 1
+ self.state = 'started'
+
+ def terminate(self):
+ self.state = 'stopping'
+
+ def join(self):
+ if self.state == 'stopping':
+ self.state = 'stopped'
+
+ def is_alive(self):
+ return self.state == 'started' or self.state == 'stopping'
+
+ with self.assertRaisesRegex(OSError, 'Manually induced OSError'):
+ p = multiprocessing.pool.Pool(5, context=unittest.mock.MagicMock(
+ Process=FailingForkProcess))
+ p.close()
+ p.join()
+ self.assertFalse(
+ any(process.is_alive() for process in forked_processes))
+
+
+
class MiscTestCase(unittest.TestCase):
def test__all__(self):
# Just make sure names in blacklist are excluded
diff --git a/Misc/NEWS.d/next/Library/2018-02-10-23-41-05.bpo-19675.-dj35-.rst b/Misc/NEWS.d/next/Library/2018-02-10-23-41-05.bpo-19675.-dj35-.rst
new file mode 100644
index 000000000000..958550d3e8d7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-02-10-23-41-05.bpo-19675.-dj35-.rst
@@ -0,0 +1 @@
+``multiprocessing.Pool`` no longer leaks processes if its initialization fails.
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
04 Nov '18
https://github.com/python/cpython/commit/b4db249c9544fc4425c32feb86d610f322…
commit: b4db249c9544fc4425c32feb86d610f3224ca3d8
branch: master
author: Pablo Galindo <Pablogsal(a)gmail.com>
committer: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
date: 2018-11-04T14:36:25-08:00
summary:
bpo-9842: Add cross-reference to the ellipsis object (GH-4063)
This PR adds a cross-reference to the ellipsis object and the representation of recursive item in containers as indicated in [issue 9842](https://bugs.python.org/issue9842) by @bitdancer.
https://bugs.python.org/issue9842
files:
M Doc/glossary.rst
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index b8e773741ce7..02adc0c56ece 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -13,10 +13,14 @@ Glossary
examples which can be executed interactively in the interpreter.
``...``
- The default Python prompt of the interactive shell when entering code for
- an indented code block, when within a pair of matching left and right
- delimiters (parentheses, square brackets, curly braces or triple quotes),
- or after specifying a decorator.
+ Can refer to:
+
+ * The default Python prompt of the interactive shell when entering code for
+ an indented code block, when within a pair of matching left and right
+ delimiters (parentheses, square brackets, curly braces or triple quotes),
+ or after specifying a decorator.
+
+ * The :const:`Ellipsis` built-in constant.
2to3
A tool that tries to convert Python 2.x code to Python 3.x code by
1
0
https://github.com/python/cpython/commit/98b85354153883b0a080f678f213729cd0…
commit: 98b85354153883b0a080f678f213729cd0764fee
branch: master
author: Windson yang <wiwindson(a)outlook.com>
committer: Raymond Hettinger <rhettinger(a)users.noreply.github.com>
date: 2018-11-04T14:34:22-08:00
summary:
bpo-35118: Improve docs regarding indexing (GH-10265)
files:
M Doc/library/collections.rst
M Doc/library/queue.rst
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 495cfc2c234f..6b9d85abaae7 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -531,9 +531,9 @@ or subtracting from an empty counter.
In addition to the above, deques support iteration, pickling, ``len(d)``,
``reversed(d)``, ``copy.copy(d)``, ``copy.deepcopy(d)``, membership testing with
-the :keyword:`in` operator, and subscript references such as ``d[-1]``. Indexed
-access is O(1) at both ends but slows to O(n) in the middle. For fast random
-access, use lists instead.
+the :keyword:`in` operator, and subscript references such as ``d[0]`` to access
+the first element. Indexed access is O(1) at both ends but slows to O(n) in
+the middle. For fast random access, use lists instead.
Starting in version 3.5, deques support ``__add__()``, ``__mul__()``,
and ``__imul__()``.
diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst
index 1fea86bfc5cd..f99f6ffb05f6 100644
--- a/Doc/library/queue.rst
+++ b/Doc/library/queue.rst
@@ -275,4 +275,5 @@ SimpleQueue Objects
:class:`collections.deque` is an alternative implementation of unbounded
queues with fast atomic :meth:`~collections.deque.append` and
- :meth:`~collections.deque.popleft` operations that do not require locking.
+ :meth:`~collections.deque.popleft` operations that do not require locking
+ and also support indexing.
1
0