diff -Nru python3.8-3.8.6/configure python3.8-3.8.7/configure
--- python3.8-3.8.6/configure 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/configure 2020-12-21 16:25:24.000000000 +0000
@@ -7493,6 +7493,31 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MACOSX_DEPLOYMENT_TARGET" >&5
$as_echo "$MACOSX_DEPLOYMENT_TARGET" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if specified universal architectures work" >&5
+$as_echo_n "checking if specified universal architectures work... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include
+int
+main ()
+{
+printf("%d", 42);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "check config.log and use the '--with-universal-archs' option" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
# end of Darwin* tests
;;
esac
@@ -10903,10 +10928,10 @@
main() {
pthread_attr_t attr;
pthread_t id;
- if (pthread_attr_init(&attr)) exit(-1);
- if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) exit(-1);
- if (pthread_create(&id, &attr, foo, NULL)) exit(-1);
- exit(0);
+ if (pthread_attr_init(&attr)) return (-1);
+ if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1);
+ if (pthread_create(&id, &attr, foo, NULL)) return (-1);
+ return (0);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
@@ -14891,7 +14916,7 @@
int main()
{
/* Success: exit code 0 */
- exit((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
+ return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
}
_ACEOF
@@ -15190,13 +15215,7 @@
fi
-
-case $ac_sys_system in
- Linux*|GNU*|Darwin|VxWorks)
- EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
- *)
- EXT_SUFFIX=${SHLIB_SUFFIX};;
-esac
+EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDVERSION" >&5
$as_echo_n "checking LDVERSION... " >&6; }
@@ -15236,7 +15255,7 @@
int main()
{
- exit(((-1)>>3 == -1) ? 0 : 1);
+ return (((-1)>>3 == -1) ? 0 : 1);
}
_ACEOF
@@ -15706,6 +15725,7 @@
/* end confdefs.h. */
#include
+#include
int main()
{
diff -Nru python3.8-3.8.6/configure.ac python3.8-3.8.7/configure.ac
--- python3.8-3.8.6/configure.ac 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/configure.ac 2020-12-21 16:25:24.000000000 +0000
@@ -1931,6 +1931,13 @@
EXPORT_MACOSX_DEPLOYMENT_TARGET=''
AC_MSG_RESULT($MACOSX_DEPLOYMENT_TARGET)
+ AC_MSG_CHECKING(if specified universal architectures work)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[printf("%d", 42);]])],
+ [AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(no)
+ AC_MSG_ERROR(check config.log and use the '--with-universal-archs' option)
+ ])
+
# end of Darwin* tests
;;
esac
@@ -3203,10 +3210,10 @@
main() {
pthread_attr_t attr;
pthread_t id;
- if (pthread_attr_init(&attr)) exit(-1);
- if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) exit(-1);
- if (pthread_create(&id, &attr, foo, NULL)) exit(-1);
- exit(0);
+ if (pthread_attr_init(&attr)) return (-1);
+ if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) return (-1);
+ if (pthread_create(&id, &attr, foo, NULL)) return (-1);
+ return (0);
}]])],
[ac_cv_pthread_system_supported=yes],
[ac_cv_pthread_system_supported=no],
@@ -4609,7 +4616,7 @@
int main()
{
/* Success: exit code 0 */
- exit((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
+ return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1);
}
]])],
[ac_cv_wchar_t_signed=yes],
@@ -4667,12 +4674,7 @@
fi
AC_SUBST(EXT_SUFFIX)
-case $ac_sys_system in
- Linux*|GNU*|Darwin|VxWorks)
- EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
- *)
- EXT_SUFFIX=${SHLIB_SUFFIX};;
-esac
+EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
AC_MSG_CHECKING(LDVERSION)
LDVERSION='$(VERSION)$(ABIFLAGS)'
@@ -4702,7 +4704,7 @@
AC_RUN_IFELSE([AC_LANG_SOURCE([[
int main()
{
- exit(((-1)>>3 == -1) ? 0 : 1);
+ return (((-1)>>3 == -1) ? 0 : 1);
}
]])],
[ac_cv_rshift_extends_sign=yes],
@@ -4849,6 +4851,7 @@
AC_CACHE_VAL(ac_cv_broken_poll,
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include
+#include
int main()
{
diff -Nru python3.8-3.8.6/debian/changelog python3.8-3.8.7/debian/changelog
--- python3.8-3.8.6/debian/changelog 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/changelog 2020-12-21 20:10:35.000000000 +0000
@@ -1,3 +1,9 @@
+python3.8 (3.8.7-1+bionic1) bionic; urgency=medium
+
+ * Python 3.8.7 release.
+
+ -- Anthony Sottile Mon, 21 Dec 2020 12:10:35 -0800
+
python3.8 (3.8.6-1+bionic2) bionic; urgency=medium
* Use faster pgo.
diff -Nru python3.8-3.8.6/debian/libpython.symbols.in python3.8-3.8.7/debian/libpython.symbols.in
--- python3.8-3.8.6/debian/libpython.symbols.in 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/libpython.symbols.in 2020-12-21 20:10:35.000000000 +0000
@@ -1624,6 +1624,7 @@
_PySet_NextEntry@Base @SVER@
_PySet_Update@Base @SVER@
_PySignal_AfterFork@Base @SVER@
+ _PySignal_Init@Base 3.8.7
_PySlice_FromIndices@Base @SVER@
_PySlice_GetLongIndices@Base @SVER@
_PyStack_AsDict@Base @SVER@
diff -Nru python3.8-3.8.6/debian/patches/0033-sysconfigdata-name.patch python3.8-3.8.7/debian/patches/0033-sysconfigdata-name.patch
--- python3.8-3.8.6/debian/patches/0033-sysconfigdata-name.patch 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/0033-sysconfigdata-name.patch 2020-12-21 20:10:35.000000000 +0000
@@ -25,7 +25,7 @@
))
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
-index d941ca9..cf76cb2 100644
+index a17ba62..abadb95 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -345,9 +345,8 @@ def get_makefile_filename():
@@ -65,7 +65,7 @@
-rm -r $(DESTDIR)$(DESTSHARED)/__pycache__
diff --git a/configure.ac b/configure.ac
-index 588faa9..58a7774 100644
+index c50e8d8..30f5cae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,7 +75,7 @@ if test "$cross_compiling" = yes; then
diff -Nru python3.8-3.8.6/debian/patches/ctypes-arm.diff python3.8-3.8.7/debian/patches/ctypes-arm.diff
--- python3.8-3.8.6/debian/patches/ctypes-arm.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/ctypes-arm.diff 2020-12-21 20:10:35.000000000 +0000
@@ -8,10 +8,10 @@
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
-index 97973bc..00189c7 100644
+index 0c2510e..3907247 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
-@@ -256,16 +256,27 @@ elif os.name == "posix":
+@@ -269,16 +269,27 @@ elif os.name == "posix":
def _findSoname_ldconfig(name):
import struct
diff -Nru python3.8-3.8.6/debian/patches/disable-sem-check.diff python3.8-3.8.7/debian/patches/disable-sem-check.diff
--- python3.8-3.8.6/debian/patches/disable-sem-check.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/disable-sem-check.diff 2020-12-21 20:10:35.000000000 +0000
@@ -9,10 +9,10 @@
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
-index 6f4a9f2..588faa9 100644
+index c32e1a1..c50e8d8 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -4510,8 +4510,13 @@ int main(void) {
+@@ -4517,8 +4517,13 @@ int main(void) {
AC_MSG_RESULT($ac_cv_posix_semaphores_enabled)
if test $ac_cv_posix_semaphores_enabled = no
then
@@ -28,7 +28,7 @@
fi
# Multiprocessing check for broken sem_getvalue
-@@ -4546,8 +4551,13 @@ int main(void){
+@@ -4553,8 +4558,13 @@ int main(void){
AC_MSG_RESULT($ac_cv_broken_sem_getvalue)
if test $ac_cv_broken_sem_getvalue = yes
then
diff -Nru python3.8-3.8.6/debian/patches/distutils-install-layout.diff python3.8-3.8.7/debian/patches/distutils-install-layout.diff
--- python3.8-3.8.6/debian/patches/distutils-install-layout.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/distutils-install-layout.diff 2020-12-21 20:10:35.000000000 +0000
@@ -276,7 +276,7 @@
sitepackages.append(prefix)
sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
-index 0100865..f82fba3 100644
+index 6b3dba0..0cb5dee 100644
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -267,10 +267,10 @@ class HelperFunctionsTests(unittest.TestCase):
diff -Nru python3.8-3.8.6/debian/patches/lib2to3-no-pickled-grammar.diff python3.8-3.8.7/debian/patches/lib2to3-no-pickled-grammar.diff
--- python3.8-3.8.6/debian/patches/lib2to3-no-pickled-grammar.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/lib2to3-no-pickled-grammar.diff 2020-12-21 20:10:35.000000000 +0000
@@ -24,7 +24,7 @@
try:
g.dump(gp)
diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py
-index 3a0e7f4..b160d77 100644
+index aafa09c..6e68057 100644
--- a/Lib/lib2to3/tests/test_parser.py
+++ b/Lib/lib2to3/tests/test_parser.py
@@ -38,83 +38,6 @@ class TestDriver(support.TestCase):
diff -Nru python3.8-3.8.6/debian/patches/link-opt.diff python3.8-3.8.7/debian/patches/link-opt.diff
--- python3.8-3.8.6/debian/patches/link-opt.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/link-opt.diff 2020-12-21 20:10:35.000000000 +0000
@@ -9,10 +9,10 @@
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
-index 18a0446..6f4a9f2 100644
+index fc082a3..c32e1a1 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -2598,8 +2598,8 @@ then
+@@ -2605,8 +2605,8 @@ then
fi
;;
Linux*|GNU*|QNX*|VxWorks*)
@@ -23,7 +23,7 @@
FreeBSD*)
if [[ "`$CC -dM -E - {% endif %}
diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html
-index 0edd391..e2f0397 100644
+index 170999e..e439e92 100644
--- a/Lib/idlelib/help.html
+++ b/Lib/idlelib/help.html
-@@ -25,7 +25,7 @@
+@@ -26,7 +26,7 @@
diff -Nru python3.8-3.8.6/debian/patches/multiarch.diff python3.8-3.8.7/debian/patches/multiarch.diff
--- python3.8-3.8.6/debian/patches/multiarch.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/multiarch.diff 2020-12-21 20:10:35.000000000 +0000
@@ -23,10 +23,10 @@
elif os.name == "nt":
if python_build:
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
-index b9e2faf..d941ca9 100644
+index 9caf158..a17ba62 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
-@@ -558,6 +558,12 @@ def get_config_vars(*args):
+@@ -559,6 +559,12 @@ def get_config_vars(*args):
# the init-function.
_CONFIG_VARS['userbase'] = _getuserbase()
diff -Nru python3.8-3.8.6/debian/patches/tkinter-import.diff python3.8-3.8.7/debian/patches/tkinter-import.diff
--- python3.8-3.8.6/debian/patches/tkinter-import.diff 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/patches/tkinter-import.diff 2020-12-21 20:10:35.000000000 +0000
@@ -9,7 +9,7 @@
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
-index 479eb01..6ff4df5 100644
+index f9ece25..ea2292c 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -33,7 +33,10 @@ tk.mainloop()
diff -Nru python3.8-3.8.6/debian/rules python3.8-3.8.7/debian/rules
--- python3.8-3.8.6/debian/rules 2020-10-06 03:22:36.000000000 +0000
+++ python3.8-3.8.7/debian/rules 2020-12-21 20:10:35.000000000 +0000
@@ -83,7 +83,7 @@
else echo Unknown; fi)
VER=3.8
-SVER=3.8.6
+SVER=3.8.7
NVER=3.9
PVER=python$(VER)
EXT_VER=$(subst .,,$(VER))
diff -Nru python3.8-3.8.6/Doc/c-api/dict.rst python3.8-3.8.7/Doc/c-api/dict.rst
--- python3.8-3.8.6/Doc/c-api/dict.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/c-api/dict.rst 2020-12-21 16:25:24.000000000 +0000
@@ -81,14 +81,16 @@
.. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key)
Remove the entry in dictionary *p* with key *key*. *key* must be hashable;
- if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1``
- on failure.
+ if it isn't, :exc:`TypeError` is raised.
+ If *key* is not in the dictionary, :exc:`KeyError` is raised.
+ Return ``0`` on success or ``-1`` on failure.
.. c:function:: int PyDict_DelItemString(PyObject *p, const char *key)
- Remove the entry in dictionary *p* which has a key specified by the string
- *key*. Return ``0`` on success or ``-1`` on failure.
+ Remove the entry in dictionary *p* which has a key specified by the string *key*.
+ If *key* is not in the dictionary, :exc:`KeyError` is raised.
+ Return ``0`` on success or ``-1`` on failure.
.. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key)
diff -Nru python3.8-3.8.6/Doc/c-api/file.rst python3.8-3.8.7/Doc/c-api/file.rst
--- python3.8-3.8.6/Doc/c-api/file.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/c-api/file.rst 2020-12-21 16:25:24.000000000 +0000
@@ -82,6 +82,8 @@
This function is safe to call before :c:func:`Py_Initialize`.
+ .. audit-event:: setopencodehook "" c.PyFile_SetOpenCodeHook
+
.. versionadded:: 3.8
diff -Nru python3.8-3.8.6/Doc/c-api/type.rst python3.8-3.8.7/Doc/c-api/type.rst
--- python3.8-3.8.6/Doc/c-api/type.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/c-api/type.rst 2020-12-21 16:25:24.000000000 +0000
@@ -124,7 +124,8 @@
If *bases* is a tuple, the created heap type contains all types contained
in it as base types.
- If *bases* is ``NULL``, the *Py_tp_base* slot is used instead.
+ If *bases* is ``NULL``, the *Py_tp_bases* slot is used instead.
+ If that also is ``NULL``, the *Py_tp_base* slot is used instead.
If that also is ``NULL``, the new type derives from :class:`object`.
This function calls :c:func:`PyType_Ready` on the new type.
@@ -194,7 +195,8 @@
* :c:member:`~PyBufferProcs.bf_getbuffer`
* :c:member:`~PyBufferProcs.bf_releasebuffer`
- Setting :c:data:`Py_tp_bases` may be problematic on some platforms.
+ Setting :c:data:`Py_tp_bases` or :c:data:`Py_tp_base` may be
+ problematic on some platforms.
To avoid issues, use the *bases* argument of
:py:func:`PyType_FromSpecWithBases` instead.
diff -Nru python3.8-3.8.6/Doc/faq/programming.rst python3.8-3.8.7/Doc/faq/programming.rst
--- python3.8-3.8.6/Doc/faq/programming.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/faq/programming.rst 2020-12-21 16:25:24.000000000 +0000
@@ -1121,7 +1121,7 @@
How do I iterate over a sequence in reverse order?
--------------------------------------------------
-Use the :func:`reversed` built-in function, which is new in Python 2.4::
+Use the :func:`reversed` built-in function::
for x in reversed(sequence):
... # do something with x ...
@@ -1129,11 +1129,6 @@
This won't touch your original sequence, but build a new copy with reversed
order to iterate over.
-With Python 2.3, you can use an extended slice syntax::
-
- for x in sequence[::-1]:
- ... # do something with x ...
-
How do you remove duplicates from a list?
-----------------------------------------
@@ -1163,6 +1158,21 @@
into a list.
+How do you remove multiple items from a list
+--------------------------------------------
+
+As with removing duplicates, explicitly iterating in reverse with a
+delete condition is one possibility. However, it is easier and faster
+to use slice replacement with an implicit or explicit forward iteration.
+Here are three variations.::
+
+ mylist[:] = filter(keep_function, mylist)
+ mylist[:] = (x for x in mylist if keep_condition)
+ mylist[:] = [x for x in mylist if keep_condition]
+
+The list comprehension may be fastest.
+
+
How do you make an array in Python?
-----------------------------------
diff -Nru python3.8-3.8.6/Doc/faq/windows.rst python3.8-3.8.7/Doc/faq/windows.rst
--- python3.8-3.8.6/Doc/faq/windows.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/faq/windows.rst 2020-12-21 16:25:24.000000000 +0000
@@ -140,7 +140,7 @@
How do I make an executable from a Python script?
-------------------------------------------------
-See `cx_Freeze `_ for a distutils extension
+See `cx_Freeze `_ for a distutils extension
that allows you to create console and GUI executables from Python code.
`py2exe `_, the most popular extension for building
Python 2.x-based executables, does not yet support Python 3 but a version that
@@ -279,7 +279,7 @@
How do I check for a keypress without blocking?
-----------------------------------------------
-Use the msvcrt module. This is a standard Windows-specific extension module.
+Use the :mod:`msvcrt` module. This is a standard Windows-specific extension module.
It defines a function ``kbhit()`` which checks whether a keyboard hit is
present, and ``getch()`` which gets one character without echoing it.
diff -Nru python3.8-3.8.6/Doc/glossary.rst python3.8-3.8.7/Doc/glossary.rst
--- python3.8-3.8.6/Doc/glossary.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/glossary.rst 2020-12-21 16:25:24.000000000 +0000
@@ -308,6 +308,12 @@
keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods.
Called a hash in Perl.
+ dictionary comprehension
+ A compact way to process all or part of the elements in an iterable and
+ return a dictionary with the results. ``results = {n: n ** 2 for n in
+ range(10)}`` generates a dictionary containing key ``n`` mapped to
+ value ``n ** 2``. See :ref:`comprehensions`.
+
dictionary view
The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and
:meth:`dict.items` are called dictionary views. They provide a dynamic
@@ -1024,7 +1030,13 @@
:meth:`index`, :meth:`__contains__`, and
:meth:`__reversed__`. Types that implement this expanded
interface can be registered explicitly using
- :func:`~abc.register`.
+ :func:`~abc.ABCMeta.register`.
+
+ set comprehension
+ A compact way to process all or part of the elements in an iterable and
+ return a set with the results. ``results = {c for c in 'abracadabra' if
+ c not in 'abc'}`` generates the set of strings ``{'r', 'd'}``. See
+ :ref:`comprehensions`.
single dispatch
A form of :term:`generic function` dispatch where the implementation is
diff -Nru python3.8-3.8.6/Doc/library/asyncio-policy.rst python3.8-3.8.7/Doc/library/asyncio-policy.rst
--- python3.8-3.8.6/Doc/library/asyncio-policy.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/asyncio-policy.rst 2020-12-21 16:25:24.000000000 +0000
@@ -209,7 +209,7 @@
It works reliably even when the asyncio event loop is run in a non-main OS thread.
There is no noticeable overhead when handling a big number of children (*O(1)* each
- time a child terminates), but stating a thread per process requires extra memory.
+ time a child terminates), but starting a thread per process requires extra memory.
This watcher is used by default.
@@ -219,7 +219,7 @@
This implementation registers a :py:data:`SIGCHLD` signal handler on
instantiation. That can break third-party code that installs a custom handler for
- `SIGCHLD`. signal).
+ :py:data:`SIGCHLD` signal.
The watcher avoids disrupting other code spawning processes
by polling every process explicitly on a :py:data:`SIGCHLD` signal.
diff -Nru python3.8-3.8.6/Doc/library/asyncio-subprocess.rst python3.8-3.8.7/Doc/library/asyncio-subprocess.rst
--- python3.8-3.8.6/Doc/library/asyncio-subprocess.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/asyncio-subprocess.rst 2020-12-21 16:25:24.000000000 +0000
@@ -110,10 +110,8 @@
.. note::
- The default asyncio event loop implementation on **Windows** does not
- support subprocesses. Subprocesses are available for Windows if a
- :class:`ProactorEventLoop` is used.
- See :ref:`Subprocess Support on Windows `
+ Subprocesses are available for Windows if a :class:`ProactorEventLoop` is
+ used. See :ref:`Subprocess Support on Windows `
for details.
.. seealso::
diff -Nru python3.8-3.8.6/Doc/library/asyncio-task.rst python3.8-3.8.7/Doc/library/asyncio-task.rst
--- python3.8-3.8.6/Doc/library/asyncio-task.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/asyncio-task.rst 2020-12-21 16:25:24.000000000 +0000
@@ -501,7 +501,7 @@
return_when=ALL_COMPLETED)
Run :ref:`awaitable objects ` in the *aws*
- set concurrently and block until the condition specified
+ iterable concurrently and block until the condition specified
by *return_when*.
Returns two sets of Tasks/Futures: ``(done, pending)``.
@@ -588,9 +588,9 @@
.. function:: as_completed(aws, \*, loop=None, timeout=None)
Run :ref:`awaitable objects ` in the *aws*
- set concurrently. Return an iterator of coroutines.
+ iterable concurrently. Return an iterator of coroutines.
Each coroutine returned can be awaited to get the earliest next
- result from the set of the remaining awaitables.
+ result from the iterable of the remaining awaitables.
Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
all Futures are done.
diff -Nru python3.8-3.8.6/Doc/library/audit_events.rst python3.8-3.8.7/Doc/library/audit_events.rst
--- python3.8-3.8.6/Doc/library/audit_events.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/audit_events.rst 2020-12-21 16:25:24.000000000 +0000
@@ -19,3 +19,29 @@
specific documentation for actual events raised.
.. audit-event-table::
+
+The following events are raised internally and do not correspond to any
+public API of CPython:
+
++--------------------------+-------------------------------------------+
+| Audit event | Arguments |
++==========================+===========================================+
+| _winapi.CreateFile | ``file_name``, ``desired_access``, |
+| | ``share_mode``, ``creation_disposition``, |
+| | ``flags_and_attributes`` |
++--------------------------+-------------------------------------------+
+| _winapi.CreateJunction | ``src_path``, ``dst_path`` |
++--------------------------+-------------------------------------------+
+| _winapi.CreateNamedPipe | ``name``, ``open_mode``, ``pipe_mode`` |
++--------------------------+-------------------------------------------+
+| _winapi.CreatePipe | |
++--------------------------+-------------------------------------------+
+| _winapi.CreateProcess | ``application_name``, ``command_line``, |
+| | ``current_directory`` |
++--------------------------+-------------------------------------------+
+| _winapi.OpenProcess | ``process_id``, ``desired_access`` |
++--------------------------+-------------------------------------------+
+| _winapi.TerminateProcess | ``handle``, ``exit_code`` |
++--------------------------+-------------------------------------------+
+| ctypes.PyObj_FromPtr | ``obj`` |
++--------------------------+-------------------------------------------+
diff -Nru python3.8-3.8.6/Doc/library/bz2.rst python3.8-3.8.7/Doc/library/bz2.rst
--- python3.8-3.8.6/Doc/library/bz2.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/bz2.rst 2020-12-21 16:25:24.000000000 +0000
@@ -264,7 +264,6 @@
Using :func:`compress` and :func:`decompress` to demonstrate round-trip compression:
>>> import bz2
-
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
@@ -273,11 +272,9 @@
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
-
>>> c = bz2.compress(data)
>>> len(data) / len(c) # Data compression ratio
1.513595166163142
-
>>> d = bz2.decompress(c)
>>> data == d # Check equality to original object after round-trip
True
@@ -285,7 +282,6 @@
Using :class:`BZ2Compressor` for incremental compression:
>>> import bz2
-
>>> def gen_data(chunks=10, chunksize=1000):
... """Yield incremental blocks of chunksize bytes."""
... for _ in range(chunks):
@@ -308,7 +304,6 @@
Writing and reading a bzip2-compressed file in binary mode:
>>> import bz2
-
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
@@ -317,14 +312,11 @@
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
-
>>> with bz2.open("myfile.bz2", "wb") as f:
... # Write compressed data to file
... unused = f.write(data)
-
>>> with bz2.open("myfile.bz2", "rb") as f:
... # Decompress data from file
... content = f.read()
-
>>> content == data # Check equality to original object after round-trip
True
diff -Nru python3.8-3.8.6/Doc/library/concurrent.futures.rst python3.8-3.8.7/Doc/library/concurrent.futures.rst
--- python3.8-3.8.6/Doc/library/concurrent.futures.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/concurrent.futures.rst 2020-12-21 16:25:24.000000000 +0000
@@ -224,9 +224,9 @@
An :class:`Executor` subclass that executes calls asynchronously using a pool
of at most *max_workers* processes. If *max_workers* is ``None`` or not
given, it will default to the number of processors on the machine.
- If *max_workers* is lower or equal to ``0``, then a :exc:`ValueError`
+ If *max_workers* is less than or equal to ``0``, then a :exc:`ValueError`
will be raised.
- On Windows, *max_workers* must be equal or lower than ``61``. If it is not
+ On Windows, *max_workers* must be less than or equal to ``61``. If it is not
then :exc:`ValueError` will be raised. If *max_workers* is ``None``, then
the default chosen will be at most ``61``, even if more processors are
available.
@@ -238,7 +238,7 @@
each worker process; *initargs* is a tuple of arguments passed to the
initializer. Should *initializer* raise an exception, all currently
pending jobs will raise a :exc:`~concurrent.futures.process.BrokenProcessPool`,
- as well any attempt to submit more jobs to the pool.
+ as well as any attempt to submit more jobs to the pool.
.. versionchanged:: 3.3
When one of the worker processes terminates abruptly, a
diff -Nru python3.8-3.8.6/Doc/library/ctypes.rst python3.8-3.8.7/Doc/library/ctypes.rst
--- python3.8-3.8.6/Doc/library/ctypes.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/ctypes.rst 2020-12-21 16:25:24.000000000 +0000
@@ -1326,6 +1326,21 @@
libraries use the standard C calling convention, and are assumed to return
:c:type:`int`.
+ On Windows creating a :class:`CDLL` instance may fail even if the DLL name
+ exists. When a dependent DLL of the loaded DLL is not found, a
+ :exc:`OSError` error is raised with the message *"[WinError 126] The
+ specified module could not be found".* This error message does not contain
+ the name of the missing DLL because the Windows API does not return this
+ information making this error hard to diagnose. To resolve this error and
+ determine which DLL is not found, you need to find the list of dependent
+ DLLs and determine which one is not found using Windows debugging and
+ tracing tools.
+
+.. seealso::
+
+ `Microsoft DUMPBIN tool `_
+ -- A tool to find DLL dependents.
+
.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0)
@@ -1618,7 +1633,7 @@
``ctypes.seh_exception`` with argument ``code`` will be raised, allowing an
audit hook to replace the exception with its own.
-.. audit-event:: ctypes.call_function func_pointer,arguments ctype-foreign-functions
+.. audit-event:: ctypes.call_function func_pointer,arguments foreign-functions
Some ways to invoke foreign function calls may raise an auditing event
``ctypes.call_function`` with arguments ``function pointer`` and ``arguments``.
@@ -2545,4 +2560,3 @@
Returns the object to which to pointer points. Assigning to this
attribute changes the pointer to point to the assigned object.
-
diff -Nru python3.8-3.8.6/Doc/library/functions.rst python3.8-3.8.7/Doc/library/functions.rst
--- python3.8-3.8.6/Doc/library/functions.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/functions.rst 2020-12-21 16:25:24.000000000 +0000
@@ -151,8 +151,8 @@
* If it is an *integer*, the array will have that size and will be
initialized with null bytes.
- * If it is an object conforming to the *buffer* interface, a read-only buffer
- of the object will be used to initialize the bytes array.
+ * If it is an object conforming to the :ref:`buffer interface `,
+ a read-only buffer of the object will be used to initialize the bytes array.
* If it is an *iterable*, it must be an iterable of integers in the range
``0 <= x < 256``, which are used as the initial contents of the array.
@@ -767,6 +767,8 @@
.. impl-detail:: This is the address of the object in memory.
+ .. audit-event:: builtins.id id id
+
.. function:: input([prompt])
diff -Nru python3.8-3.8.6/Doc/library/imaplib.rst python3.8-3.8.7/Doc/library/imaplib.rst
--- python3.8-3.8.6/Doc/library/imaplib.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/imaplib.rst 2020-12-21 16:25:24.000000000 +0000
@@ -163,9 +163,9 @@
.. seealso::
- Documents describing the protocol, and sources and binaries for servers
- implementing it, can all be found at the University of Washington's *IMAP
- Information Center* (https://www.washington.edu/imap/).
+ Documents describing the protocol, sources for servers
+ implementing it, by the University of Washington's IMAP Information Center
+ can all be found at (**Source Code**) https://github.com/uw-imap/imap (**Not Maintained**).
.. _imap4-objects:
diff -Nru python3.8-3.8.6/Doc/library/importlib.metadata.rst python3.8-3.8.7/Doc/library/importlib.metadata.rst
--- python3.8-3.8.6/Doc/library/importlib.metadata.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/importlib.metadata.rst 2020-12-21 16:25:24.000000000 +0000
@@ -1,8 +1,8 @@
.. _using:
-==========================
- Using importlib.metadata
-==========================
+=================================
+ Using :mod:`!importlib.metadata`
+=================================
.. note::
This functionality is provisional and may deviate from the usual
@@ -12,8 +12,8 @@
package metadata. Built in part on Python's import system, this library
intends to replace similar functionality in the `entry point
API`_ and `metadata API`_ of ``pkg_resources``. Along with
-``importlib.resources`` in `Python 3.7
-and newer`_ (backported as `importlib_resources`_ for older versions of
+:mod:`importlib.resources` in Python 3.7
+and newer (backported as `importlib_resources`_ for older versions of
Python), this can eliminate the need to use the older and less efficient
``pkg_resources`` package.
@@ -21,9 +21,9 @@
Python's ``site-packages`` directory via tools such as `pip
`_. Specifically,
it means a package with either a discoverable ``dist-info`` or ``egg-info``
-directory, and metadata defined by `PEP 566`_ or its older specifications.
+directory, and metadata defined by :pep:`566` or its older specifications.
By default, package metadata can live on the file system or in zip archives on
-``sys.path``. Through an extension mechanism, the metadata can live almost
+:data:`sys.path`. Through an extension mechanism, the metadata can live almost
anywhere.
@@ -134,7 +134,7 @@
You can also get the full set of files contained within a distribution. The
``files()`` function takes a distribution package name and returns all of the
files installed by this distribution. Each file object returned is a
-``PackagePath``, a `pathlib.Path`_ derived object with additional ``dist``,
+``PackagePath``, a :class:`pathlib.Path` derived object with additional ``dist``,
``size``, and ``hash`` properties as indicated by the metadata. For example::
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP
@@ -203,18 +203,18 @@
>>> d.metadata['License'] # doctest: +SKIP
'MIT'
-The full set of available metadata is not described here. See `PEP 566
-`_ for additional details.
+The full set of available metadata is not described here. See :pep:`566`
+for additional details.
Extending the search algorithm
==============================
-Because package metadata is not available through ``sys.path`` searches, or
+Because package metadata is not available through :data:`sys.path` searches, or
package loaders directly, the metadata for a package is found through import
-system `finders`_. To find a distribution package's metadata,
-``importlib.metadata`` queries the list of `meta path finders`_ on
-`sys.meta_path`_.
+system :ref:`finders `. To find a distribution package's metadata,
+``importlib.metadata`` queries the list of :term:`meta path finders ` on
+:data:`sys.meta_path`.
The default ``PathFinder`` for Python includes a hook that calls into
``importlib.metadata.MetadataPathFinder`` for finding distributions
@@ -224,7 +224,7 @@
interface expected of finders by Python's import system.
``importlib.metadata`` extends this protocol by looking for an optional
``find_distributions`` callable on the finders from
-``sys.meta_path`` and presents this extended interface as the
+:data:`sys.meta_path` and presents this extended interface as the
``DistributionFinder`` abstract base class, which defines this abstract
method::
@@ -247,20 +247,13 @@
.. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points
.. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api
-.. _`Python 3.7 and newer`: https://docs.python.org/3/library/importlib.html#module-importlib.resources
.. _`importlib_resources`: https://importlib-resources.readthedocs.io/en/latest/index.html
-.. _`PEP 566`: https://www.python.org/dev/peps/pep-0566/
-.. _`finders`: https://docs.python.org/3/reference/import.html#finders-and-loaders
-.. _`meta path finders`: https://docs.python.org/3/glossary.html#term-meta-path-finder
-.. _`sys.meta_path`: https://docs.python.org/3/library/sys.html#sys.meta_path
-.. _`pathlib.Path`: https://docs.python.org/3/library/pathlib.html#pathlib.Path
.. rubric:: Footnotes
.. [#f1] Technically, the returned distribution metadata object is an
- `email.message.Message
- `_
+ :class:`email.message.EmailMessage`
instance, but this is an implementation detail, and not part of the
stable API. You should only use dictionary-like methods and syntax
to access the metadata contents.
diff -Nru python3.8-3.8.6/Doc/library/importlib.rst python3.8-3.8.7/Doc/library/importlib.rst
--- python3.8-3.8.6/Doc/library/importlib.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/importlib.rst 2020-12-21 16:25:24.000000000 +0000
@@ -438,8 +438,9 @@
package. This attribute is not set on modules.
- :attr:`__package__`
- The parent package for the module/package. If the module is
- top-level then it has a value of the empty string. The
+ The fully-qualified name of the package under which the module was
+ loaded as a submodule (or the empty string for top-level modules).
+ For packages, it is the same as :attr:`__name__`. The
:func:`importlib.util.module_for_loader` decorator can handle the
details for :attr:`__package__`.
@@ -1310,8 +1311,8 @@
(``__loader__``)
- The loader to use for loading. For namespace packages this should be
- set to ``None``.
+ The :term:`Loader ` that should be used when loading
+ the module. :term:`Finders ` should always set this.
.. attribute:: origin
@@ -1344,8 +1345,9 @@
(``__package__``)
- (Read-only) Fully-qualified name of the package to which the module
- belongs as a submodule (or ``None``).
+ (Read-only) The fully-qualified name of the package under which the module
+ should be loaded as a submodule (or the empty string for top-level modules).
+ For packages, it is the same as :attr:`__name__`.
.. attribute:: has_location
diff -Nru python3.8-3.8.6/Doc/library/logging.rst python3.8-3.8.7/Doc/library/logging.rst
--- python3.8-3.8.6/Doc/library/logging.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/logging.rst 2020-12-21 16:25:24.000000000 +0000
@@ -1083,8 +1083,8 @@
suitable value.
.. versionchanged:: 3.7
- The *level* parameter was defaulted to level ``CRITICAL``. See Issue
- #28524 for more information about this change.
+ The *level* parameter was defaulted to level ``CRITICAL``. See
+ :issue:`28524` for more information about this change.
.. function:: addLevelName(level, levelName)
diff -Nru python3.8-3.8.6/Doc/library/mailbox.rst python3.8-3.8.7/Doc/library/mailbox.rst
--- python3.8-3.8.6/Doc/library/mailbox.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/mailbox.rst 2020-12-21 16:25:24.000000000 +0000
@@ -426,17 +426,14 @@
.. seealso::
- `maildir man page from qmail `_
- The original specification of the format.
+ `maildir man page from Courier `_
+ A specification of the format. Describes a common extension for
+ supporting folders.
`Using maildir format `_
Notes on Maildir by its inventor. Includes an updated name-creation scheme and
details on "info" semantics.
- `maildir man page from Courier `_
- Another specification of the format. Describes a common extension for supporting
- folders.
-
.. _mailbox-mbox:
@@ -485,11 +482,8 @@
.. seealso::
- `mbox man page from qmail `_
- A specification of the format and its variations.
-
`mbox man page from tin `_
- Another specification of the format, with details on locking.
+ A specification of the format, with details on locking.
`Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad `_
An argument for using the original mbox format rather than a variation.
diff -Nru python3.8-3.8.6/Doc/library/multiprocessing.rst python3.8-3.8.7/Doc/library/multiprocessing.rst
--- python3.8-3.8.6/Doc/library/multiprocessing.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/multiprocessing.rst 2020-12-21 16:25:24.000000000 +0000
@@ -98,7 +98,7 @@
*spawn*
The parent process starts a fresh python interpreter process. The
child process will only inherit those resources necessary to run
- the process objects :meth:`~Process.run` method. In particular,
+ the process object's :meth:`~Process.run` method. In particular,
unnecessary file descriptors and handles from the parent process
will not be inherited. Starting a process using this method is
rather slow compared to using *fork* or *forkserver*.
@@ -2559,9 +2559,9 @@
filesystem.
* An ``'AF_PIPE'`` address is a string of the form
- :samp:`r'\\\\.\\pipe\\{PipeName}'`. To use :func:`Client` to connect to a named
- pipe on a remote computer called *ServerName* one should use an address of the
- form :samp:`r'\\\\{ServerName}\\pipe\\{PipeName}'` instead.
+ :samp:`r'\\\\.\\pipe\\{PipeName}'`. To use :func:`Client` to connect to a named
+ pipe on a remote computer called *ServerName* one should use an address of the
+ form :samp:`r'\\\\{ServerName}\\pipe\\{PipeName}'` instead.
Note that any string beginning with two backslashes is assumed by default to be
an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address.
@@ -2651,6 +2651,46 @@
:mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is
no more than a wrapper around the :mod:`threading` module.
+.. currentmodule:: multiprocessing.pool
+
+In particular, the ``Pool`` function provided by :mod:`multiprocessing.dummy`
+returns an instance of :class:`ThreadPool`, which is a subclass of
+:class:`Pool` that supports all the same method calls but uses a pool of
+worker threads rather than worker processes.
+
+
+.. class:: ThreadPool([processes[, initializer[, initargs]]])
+
+ A thread pool object which controls a pool of worker threads to which jobs
+ can be submitted. :class:`ThreadPool` instances are fully interface
+ compatible with :class:`Pool` instances, and their resources must also be
+ properly managed, either by using the pool as a context manager or by
+ calling :meth:`~multiprocessing.pool.Pool.close` and
+ :meth:`~multiprocessing.pool.Pool.terminate` manually.
+
+ *processes* is the number of worker threads to use. If *processes* is
+ ``None`` then the number returned by :func:`os.cpu_count` is used.
+
+ If *initializer* is not ``None`` then each worker process will call
+ ``initializer(*initargs)`` when it starts.
+
+ Unlike :class:`Pool`, *maxtasksperchild* and *context* cannot be provided.
+
+ .. note::
+
+ A :class:`ThreadPool` shares the same interface as :class:`Pool`, which
+ is designed around a pool of processes and predates the introduction of
+ the :class:`concurrent.futures` module. As such, it inherits some
+ operations that don't make sense for a pool backed by threads, and it
+ has its own type for representing the status of asynchronous jobs,
+ :class:`AsyncResult`, that is not understood by any other libraries.
+
+ Users should generally prefer to use
+ :class:`concurrent.futures.ThreadPoolExecutor`, which has a simpler
+ interface that was designed around threads from the start, and which
+ returns :class:`concurrent.futures.Future` instances that are
+ compatible with many other libraries, including :mod:`asyncio`.
+
.. _multiprocessing-programming:
diff -Nru python3.8-3.8.6/Doc/library/optparse.rst python3.8-3.8.7/Doc/library/optparse.rst
--- python3.8-3.8.6/Doc/library/optparse.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/optparse.rst 2020-12-21 16:25:24.000000000 +0000
@@ -55,7 +55,7 @@
-q -foutfile
-qfoutfile
-Additionally, users can run one of ::
+Additionally, users can run one of the following ::
-h
--help
diff -Nru python3.8-3.8.6/Doc/library/os.rst python3.8-3.8.7/Doc/library/os.rst
--- python3.8-3.8.6/Doc/library/os.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/os.rst 2020-12-21 16:25:24.000000000 +0000
@@ -3664,8 +3664,8 @@
The positional-only arguments *path*, *args*, and *env* are similar to
:func:`execve`.
- The *path* parameter is the path to the executable file.The *path* should
- contain a directory.Use :func:`posix_spawnp` to pass an executable file
+ The *path* parameter is the path to the executable file. The *path* should
+ contain a directory. Use :func:`posix_spawnp` to pass an executable file
without directory.
The *file_actions* argument may be a sequence of tuples describing actions
diff -Nru python3.8-3.8.6/Doc/library/pathlib.rst python3.8-3.8.7/Doc/library/pathlib.rst
--- python3.8-3.8.6/Doc/library/pathlib.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/pathlib.rst 2020-12-21 16:25:24.000000000 +0000
@@ -954,6 +954,10 @@
>>> target.open().read()
'some text'
+ The target path may be absolute or relative. Relative paths are interpreted
+ relative to the current working directory, *not* the directory of the Path
+ object.
+
.. versionchanged:: 3.8
Added return value, return the new Path instance.
@@ -964,6 +968,10 @@
instance pointing to *target*. If *target* points to an existing file or
directory, it will be unconditionally replaced.
+ The target path may be absolute or relative. Relative paths are interpreted
+ relative to the current working directory, *not* the directory of the Path
+ object.
+
.. versionchanged:: 3.8
Added return value, return the new Path instance.
diff -Nru python3.8-3.8.6/Doc/library/platform.rst python3.8-3.8.7/Doc/library/platform.rst
--- python3.8-3.8.6/Doc/library/platform.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/platform.rst 2020-12-21 16:25:24.000000000 +0000
@@ -209,13 +209,6 @@
which means the OS version uses debugging code, i.e. code that checks arguments,
ranges, etc.
- .. note::
-
- This function works best with Mark Hammond's
- :mod:`win32all` package installed, but also on Python 2.3 and
- later (support for this was added in Python 2.6). It obviously
- only runs on Win32 compatible platforms.
-
.. function:: win32_edition()
Returns a string representing the current Windows edition. Possible
diff -Nru python3.8-3.8.6/Doc/library/poplib.rst python3.8-3.8.7/Doc/library/poplib.rst
--- python3.8-3.8.6/Doc/library/poplib.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/poplib.rst 2020-12-21 16:25:24.000000000 +0000
@@ -64,7 +64,7 @@
.. audit-event:: poplib.connect self,host,port poplib.POP3_SSL
- .. audit-event:: poplib.putline self,line popplib.POP3_SSL
+ .. audit-event:: poplib.putline self,line poplib.POP3_SSL
All commands will raise an :ref:`auditing event `
``poplib.putline`` with arguments ``self`` and ``line``,
diff -Nru python3.8-3.8.6/Doc/library/secrets.rst python3.8-3.8.7/Doc/library/secrets.rst
--- python3.8-3.8.6/Doc/library/secrets.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/secrets.rst 2020-12-21 16:25:24.000000000 +0000
@@ -21,7 +21,7 @@
random numbers suitable for managing data such as passwords, account
authentication, security tokens, and related secrets.
-In particularly, :mod:`secrets` should be used in preference to the
+In particular, :mod:`secrets` should be used in preference to the
default pseudo-random number generator in the :mod:`random` module, which
is designed for modelling and simulation, not security or cryptography.
diff -Nru python3.8-3.8.6/Doc/library/shutil.rst python3.8-3.8.7/Doc/library/shutil.rst
--- python3.8-3.8.6/Doc/library/shutil.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/shutil.rst 2020-12-21 16:25:24.000000000 +0000
@@ -158,9 +158,9 @@
.. function:: copy(src, dst, *, follow_symlinks=True)
Copies the file *src* to the file or directory *dst*. *src* and *dst*
- should be strings. If *dst* specifies a directory, the file will be
- copied into *dst* using the base filename from *src*. Returns the
- path to the newly created file.
+ should be :term:`path-like objects ` or strings. If
+ *dst* specifies a directory, the file will be copied into *dst* using the
+ base filename from *src*. Returns the path to the newly created file.
If *follow_symlinks* is false, and *src* is a symbolic link,
*dst* will be created as a symbolic link. If *follow_symlinks*
@@ -349,7 +349,7 @@
will be created in or as *dst* and *src* will be removed.
If *copy_function* is given, it must be a callable that takes two arguments
- *src* and *dst*, and will be used to copy *src* to *dest* if
+ *src* and *dst*, and will be used to copy *src* to *dst* if
:func:`os.rename` cannot be used. If the source is a directory,
:func:`copytree` is called, passing it the :func:`copy_function`. The
default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the
diff -Nru python3.8-3.8.6/Doc/library/signal.rst python3.8-3.8.7/Doc/library/signal.rst
--- python3.8-3.8.6/Doc/library/signal.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/signal.rst 2020-12-21 16:25:24.000000000 +0000
@@ -117,7 +117,7 @@
Child process stopped or terminated.
- .. availability:: Windows.
+ .. availability:: Unix.
.. data:: SIGCLD
diff -Nru python3.8-3.8.6/Doc/library/site.rst python3.8-3.8.7/Doc/library/site.rst
--- python3.8-3.8.6/Doc/library/site.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/site.rst 2020-12-21 16:25:24.000000000 +0000
@@ -231,7 +231,9 @@
Return the path of the user-specific site-packages directory,
:data:`USER_SITE`. If it is not initialized yet, this function will also set
- it, respecting :envvar:`PYTHONNOUSERSITE` and :data:`USER_BASE`.
+ it, respecting :data:`USER_BASE`. To determine if the user-specific
+ site-packages was added to ``sys.path`` :data:`ENABLE_USER_SITE` should be
+ used.
.. versionadded:: 3.2
diff -Nru python3.8-3.8.6/Doc/library/socket.rst python3.8-3.8.7/Doc/library/socket.rst
--- python3.8-3.8.6/Doc/library/socket.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/socket.rst 2020-12-21 16:25:24.000000000 +0000
@@ -1046,6 +1046,19 @@
.. versionchanged:: 3.8
Windows support was added.
+ .. note::
+
+ On Windows network interfaces have different names in different contexts
+ (all names are examples):
+
+ * UUID: ``{FB605B73-AAC2-49A6-9A2F-25416AEA0573}``
+ * name: ``ethernet_32770``
+ * friendly name: ``vEthernet (nat)``
+ * description: ``Hyper-V Virtual Ethernet Adapter``
+
+ This function returns names of the second form from the list, ``ethernet_32770``
+ in this example case.
+
.. function:: if_nametoindex(if_name)
@@ -1060,6 +1073,9 @@
.. versionchanged:: 3.8
Windows support was added.
+ .. seealso::
+ "Interface name" is a name as documented in :func:`if_nameindex`.
+
.. function:: if_indextoname(if_index)
@@ -1074,6 +1090,9 @@
.. versionchanged:: 3.8
Windows support was added.
+ .. seealso::
+ "Interface name" is a name as documented in :func:`if_nameindex`.
+
.. _socket-objects:
diff -Nru python3.8-3.8.6/Doc/library/sqlite3.rst python3.8-3.8.7/Doc/library/sqlite3.rst
--- python3.8-3.8.6/Doc/library/sqlite3.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/sqlite3.rst 2020-12-21 16:25:24.000000000 +0000
@@ -197,7 +197,9 @@
*detect_types* defaults to 0 (i. e. off, no type detection), you can set it to
any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn
- type detection on.
+ type detection on. Due to SQLite behaviour, types can't be detected for generated
+ fields (for example ``max(data)``), even when *detect_types* parameter is set. In
+ such case, the returned type is :class:`str`.
By default, *check_same_thread* is :const:`True` and only the creating thread may
use the connection. If set :const:`False`, the returned connection may be shared
diff -Nru python3.8-3.8.6/Doc/library/stdtypes.rst python3.8-3.8.7/Doc/library/stdtypes.rst
--- python3.8-3.8.6/Doc/library/stdtypes.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/stdtypes.rst 2020-12-21 16:25:24.000000000 +0000
@@ -3994,6 +3994,12 @@
objects. If *iterable* is not specified, a new empty set is
returned.
+ Sets can be created by several means:
+
+ * Use a comma-separated list of elements within braces: ``{'jack', 'sjoerd'}``
+ * Use a set comprehension: ``{c for c in 'abracadabra' if c not in 'abc'}``
+ * Use the type constructor: ``set()``, ``set('foobar')``, ``set(['a', 'b', 'foo'])``
+
Instances of :class:`set` and :class:`frozenset` provide the following
operations:
@@ -4186,6 +4192,14 @@
Return a new dictionary initialized from an optional positional argument
and a possibly empty set of keyword arguments.
+ Dictionaries can be created by several means:
+
+ * Use a comma-separated list of ``key: value`` pairs within braces:
+ ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: 'jack', 4127: 'sjoerd'}``
+ * Use a dict comprehension: ``{}``, ``{x: x ** 2 for x in range(10)}``
+ * Use the type constructor: ``dict()``,
+ ``dict([('foo', 100), ('bar', 200)])``, ``dict(foo=100, bar=200)``
+
If no positional argument is given, an empty dictionary is created.
If a positional argument is given and it is a mapping object, a dictionary
is created with the same key-value pairs as the mapping object. Otherwise,
diff -Nru python3.8-3.8.6/Doc/library/string.rst python3.8-3.8.7/Doc/library/string.rst
--- python3.8-3.8.6/Doc/library/string.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/string.rst 2020-12-21 16:25:24.000000000 +0000
@@ -384,10 +384,10 @@
The ``'#'`` option causes the "alternate form" to be used for the
conversion. The alternate form is defined differently for different
-types. This option is only valid for integer, float, complex and
-Decimal types. For integers, when binary, octal, or hexadecimal output
+types. This option is only valid for integer, float and complex
+types. For integers, when binary, octal, or hexadecimal output
is used, this option adds the prefix respective ``'0b'``, ``'0o'``, or
-``'0x'`` to the output value. For floats, complex and Decimal the
+``'0x'`` to the output value. For float and complex the
alternate form causes the result of the conversion to always contain a
decimal-point character, even if no digits follow it. Normally, a
decimal-point character appears in the result of these conversions
@@ -476,20 +476,36 @@
``'n'`` and ``None``). When doing so, :func:`float` is used to convert the
integer to a floating point number before formatting.
-The available presentation types for floating point and decimal values are:
+The available presentation types for :class:`float` and
+:class:`~decimal.Decimal` values are:
+---------+----------------------------------------------------------+
| Type | Meaning |
+=========+==========================================================+
- | ``'e'`` | Exponent notation. Prints the number in scientific |
- | | notation using the letter 'e' to indicate the exponent. |
- | | The default precision is ``6``. |
- +---------+----------------------------------------------------------+
- | ``'E'`` | Exponent notation. Same as ``'e'`` except it uses an |
- | | upper case 'E' as the separator character. |
- +---------+----------------------------------------------------------+
- | ``'f'`` | Fixed-point notation. Displays the number as a |
- | | fixed-point number. The default precision is ``6``. |
+ | ``'e'`` | Scientific notation. For a given precision ``p``, |
+ | | formats the number in scientific notation with the |
+ | | letter 'e' separating the coefficient from the exponent. |
+ | | The coefficient has one digit before and ``p`` digits |
+ | | after the decimal point, for a total of ``p + 1`` |
+ | | significant digits. With no precision given, uses a |
+ | | precision of ``6`` digits after the decimal point for |
+ | | :class:`float`, and shows all coefficient digits |
+ | | for :class:`~decimal.Decimal`. If no digits follow the |
+ | | decimal point, the decimal point is also removed unless |
+ | | the ``#`` option is used. |
+ +---------+----------------------------------------------------------+
+ | ``'E'`` | Scientific notation. Same as ``'e'`` except it uses |
+ | | an upper case 'E' as the separator character. |
+ +---------+----------------------------------------------------------+
+ | ``'f'`` | Fixed-point notation. For a given precision ``p``, |
+ | | formats the number as a decimal number with exactly |
+ | | ``p`` digits following the decimal point. With no |
+ | | precision given, uses a precision of ``6`` digits after |
+ | | the decimal point for :class:`float`, and uses a |
+ | | precision large enough to show all coefficient digits |
+ | | for :class:`~decimal.Decimal`. If no digits follow the |
+ | | decimal point, the decimal point is also removed unless |
+ | | the ``#`` option is used. |
+---------+----------------------------------------------------------+
| ``'F'`` | Fixed-point notation. Same as ``'f'``, but converts |
| | ``nan`` to ``NAN`` and ``inf`` to ``INF``. |
@@ -498,6 +514,8 @@
| | this rounds the number to ``p`` significant digits and |
| | then formats the result in either fixed-point format |
| | or in scientific notation, depending on its magnitude. |
+ | | A precision of ``0`` is treated as equivalent to a |
+ | | precision of ``1``. |
| | |
| | The precise rules are as follows: suppose that the |
| | result formatted with presentation type ``'e'`` and |
@@ -512,13 +530,19 @@
| | removed if there are no remaining digits following it, |
| | unless the ``'#'`` option is used. |
| | |
+ | | With no precision given, uses a precision of ``6`` |
+ | | significant digits for :class:`float`. For |
+ | | :class:`~decimal.Decimal`, the coefficient of the result |
+ | | is formed from the coefficient digits of the value; |
+ | | scientific notation is used for values smaller than |
+ | | ``1e-6`` in absolute value and values where the place |
+ | | value of the least significant digit is larger than 1, |
+ | | and fixed-point notation is used otherwise. |
+ | | |
| | Positive and negative infinity, positive and negative |
| | zero, and nans, are formatted as ``inf``, ``-inf``, |
| | ``0``, ``-0`` and ``nan`` respectively, regardless of |
| | the precision. |
- | | |
- | | A precision of ``0`` is treated as equivalent to a |
- | | precision of ``1``. The default precision is ``6``. |
+---------+----------------------------------------------------------+
| ``'G'`` | General format. Same as ``'g'`` except switches to |
| | ``'E'`` if the number gets too large. The |
@@ -531,12 +555,18 @@
| ``'%'`` | Percentage. Multiplies the number by 100 and displays |
| | in fixed (``'f'``) format, followed by a percent sign. |
+---------+----------------------------------------------------------+
- | None | Similar to ``'g'``, except that fixed-point notation, |
- | | when used, has at least one digit past the decimal point.|
- | | The default precision is as high as needed to represent |
- | | the particular value. The overall effect is to match the |
- | | output of :func:`str` as altered by the other format |
- | | modifiers. |
+ | None | For :class:`float` this is the same as ``'g'``, except |
+ | | that when fixed-point notation is used to format the |
+ | | result, it always includes at least one digit past the |
+ | | decimal point. The precision used is as large as needed |
+ | | to represent the given value faithfully. |
+ | | |
+ | | For :class:`~decimal.Decimal`, this is the same as |
+ | | either ``'g'`` or ``'G'`` depending on the value of |
+ | | ``context.capitals`` for the current decimal context. |
+ | | |
+ | | The overall effect is to match the output of :func:`str` |
+ | | as altered by the other format modifiers. |
+---------+----------------------------------------------------------+
diff -Nru python3.8-3.8.6/Doc/library/sys.rst python3.8-3.8.7/Doc/library/sys.rst
--- python3.8-3.8.6/Doc/library/sys.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/sys.rst 2020-12-21 16:25:24.000000000 +0000
@@ -31,16 +31,22 @@
When an auditing event is raised through the :func:`sys.audit` function, each
hook will be called in the order it was added with the event name and the
tuple of arguments. Native hooks added by :c:func:`PySys_AddAuditHook` are
- called first, followed by hooks added in the current interpreter.
+ called first, followed by hooks added in the current interpreter. Hooks
+ can then log the event, raise an exception to abort the operation,
+ or terminate the process entirely.
.. audit-event:: sys.addaudithook "" sys.addaudithook
- Raise an auditing event ``sys.addaudithook`` with no arguments. If any
+ Calling :func:`sys.addaudithook` will itself raise an auditing event
+ named ``sys.addaudithook`` with no arguments. If any
existing hooks raise an exception derived from :class:`RuntimeError`, the
new hook will not be added and the exception suppressed. As a result,
callers cannot assume that their hook has been added unless they control
all existing hooks.
+ See the :ref:`audit events table ` for all events raised by
+ CPython, and :pep:`578` for the original design discussion.
+
.. versionadded:: 3.8
.. versionchanged:: 3.8.1
@@ -79,14 +85,23 @@
.. index:: single: auditing
- Raise an auditing event with any active hooks. The event name is a string
- identifying the event and its associated schema, which is the number and
- types of arguments. The schema for a given event is considered public and
- stable API and should not be modified between releases.
-
- This function will raise the first exception raised by any hook. In general,
- these errors should not be handled and should terminate the process as
- quickly as possible.
+ Raise an auditing event and trigger any active auditing hooks.
+ *event* is a string identifying the event, and *args* may contain
+ optional arguments with more information about the event. The
+ number and types of arguments for a given event are considered a
+ public and stable API and should not be modified between releases.
+
+ For example, one auditing event is named ``os.chdir``. This event has
+ one argument called *path* that will contain the requested new
+ working directory.
+
+ :func:`sys.audit` will call the existing auditing hooks, passing
+ the event name and arguments, and will re-raise the first exception
+ from any hook. In general, if an exception is raised, it should not
+ be handled and the process should be terminated as quickly as
+ possible. This allows hook implementations to decide how to respond
+ to particular events: they can merely log the event or abort the
+ operation by raising an exception.
Hooks are added using the :func:`sys.addaudithook` or
:c:func:`PySys_AddAuditHook` functions.
diff -Nru python3.8-3.8.6/Doc/library/types.rst python3.8-3.8.7/Doc/library/types.rst
--- python3.8-3.8.6/Doc/library/types.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/types.rst 2020-12-21 16:25:24.000000000 +0000
@@ -109,6 +109,11 @@
The type of user-defined functions and functions created by
:keyword:`lambda` expressions.
+ .. audit-event:: function.__new__ code types.FunctionType
+
+ The audit event only occurs for direct instantiation of function objects,
+ and is not raised for normal compilation.
+
.. data:: GeneratorType
@@ -138,10 +143,11 @@
The type for code objects such as returned by :func:`compile`.
- .. audit-event:: code.__new__ code,filename,name,argcount,posonlyargcount,kwonlyargcount,nlocals,stacksize,flags CodeType
+ .. audit-event:: code.__new__ code,filename,name,argcount,posonlyargcount,kwonlyargcount,nlocals,stacksize,flags types.CodeType
Note that the audited arguments may not match the names or positions
- required by the initializer.
+ required by the initializer. The audit event only occurs for direct
+ instantiation of code objects, and is not raised for normal compilation.
.. method:: CodeType.replace(**kwargs)
@@ -349,7 +355,9 @@
return "{}({})".format(type(self).__name__, ", ".join(items))
def __eq__(self, other):
- return self.__dict__ == other.__dict__
+ if isinstance(self, SimpleNamespace) and isinstance(other, SimpleNamespace):
+ return self.__dict__ == other.__dict__
+ return NotImplemented
``SimpleNamespace`` may be useful as a replacement for ``class NS: pass``.
However, for a structured record type use :func:`~collections.namedtuple`
diff -Nru python3.8-3.8.6/Doc/library/typing.rst python3.8-3.8.7/Doc/library/typing.rst
--- python3.8-3.8.6/Doc/library/typing.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/typing.rst 2020-12-21 16:25:24.000000000 +0000
@@ -402,10 +402,10 @@
a class ``B`` is expected if and only if ``A`` is a subclass of ``B``.
This requirement previously also applied to abstract base classes, such as
-:class:`Iterable`. The problem with this approach is that a class had
+:class:`~collections.abc.Iterable`. The problem with this approach is that a class had
to be explicitly marked to support them, which is unpythonic and unlike
what one would normally do in idiomatic dynamically typed Python code.
-For example, this conforms to the :pep:`484`::
+For example, this conforms to :pep:`484`::
from typing import Sized, Iterable, Iterator
@@ -570,7 +570,7 @@
:ref:`type variables `, and unions of any of these types.
For example::
- def new_non_team_user(user_class: Type[Union[BaseUser, ProUser]]): ...
+ def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]): ...
``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent
to ``type``, which is the root of Python's metaclass hierarchy.
@@ -1167,7 +1167,7 @@
Such a protocol can be used with :func:`isinstance` and :func:`issubclass`.
This raises :exc:`TypeError` when applied to a non-protocol class. This
allows a simple-minded structural check, very similar to "one trick ponies"
- in :mod:`collections.abc` such as :class:`Iterable`. For example::
+ in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example::
@runtime_checkable
class Closable(Protocol):
diff -Nru python3.8-3.8.6/Doc/library/unittest.rst python3.8-3.8.7/Doc/library/unittest.rst
--- python3.8-3.8.6/Doc/library/unittest.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/unittest.rst 2020-12-21 16:25:24.000000000 +0000
@@ -593,8 +593,9 @@
.. decorator:: expectedFailure
- Mark the test as an expected failure. If the test fails it will be
- considered a success. If the test passes, it will be considered a failure.
+ Mark the test as an expected failure or error. If the test fails or errors
+ it will be considered a success. If the test passes, it will be considered
+ a failure.
.. exception:: SkipTest(reason)
@@ -896,8 +897,7 @@
.. method:: assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)
- Test that *first* and *second* evaluate (or don't evaluate) to the
- same object.
+ Test that *first* and *second* are (or are not) the same object.
.. versionadded:: 3.1
@@ -1088,7 +1088,8 @@
If given, *logger* should be a :class:`logging.Logger` object or a
:class:`str` giving the name of a logger. The default is the root
- logger, which will catch all messages.
+ logger, which will catch all messages that were not blocked by a
+ non-propagating descendent logger.
If given, *level* should be either a numeric logging level or
its string equivalent (for example either ``"ERROR"`` or
@@ -1945,7 +1946,7 @@
A list containing 2-tuples of :class:`TestCase` instances and strings
holding formatted tracebacks. Each tuple represents an expected failure
- of the test case.
+ or error of the test case.
.. attribute:: unexpectedSuccesses
@@ -2071,8 +2072,8 @@
.. method:: addExpectedFailure(test, err)
- Called when the test case *test* fails, but was marked with the
- :func:`expectedFailure` decorator.
+ Called when the test case *test* fails or errors, but was marked with
+ the :func:`expectedFailure` decorator.
The default implementation appends a tuple ``(test, formatted_err)`` to
the instance's :attr:`expectedFailures` attribute, where *formatted_err*
diff -Nru python3.8-3.8.6/Doc/library/xml.etree.elementtree.rst python3.8-3.8.7/Doc/library/xml.etree.elementtree.rst
--- python3.8-3.8.6/Doc/library/xml.etree.elementtree.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/library/xml.etree.elementtree.rst 2020-12-21 16:25:24.000000000 +0000
@@ -249,12 +249,18 @@
remove all countries with a rank higher than 50::
>>> for country in root.findall('country'):
+ ... # using root.findall() to avoid removal during traversal
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
+Note that concurrent modification while iterating can lead to problems,
+just like when iterating and modifying Python lists or dicts.
+Therefore, the example first collects all matching elements with
+``root.findall()``, and only then iterates over the list of matches.
+
Our XML now looks like this:
.. code-block:: xml
diff -Nru python3.8-3.8.6/Doc/reference/compound_stmts.rst python3.8-3.8.7/Doc/reference/compound_stmts.rst
--- python3.8-3.8.6/Doc/reference/compound_stmts.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/reference/compound_stmts.rst 2020-12-21 16:25:24.000000000 +0000
@@ -254,7 +254,8 @@
expression, that expression is evaluated, and the clause matches the exception
if the resulting object is "compatible" with the exception. An object is
compatible with an exception if it is the class or a base class of the exception
-object or a tuple containing an item compatible with the exception.
+object, or a tuple containing an item that is the class or a base class of
+the exception object.
If no except clause matches the exception, the search for an exception handler
continues in the surrounding code and on the invocation stack. [#]_
diff -Nru python3.8-3.8.6/Doc/reference/datamodel.rst python3.8-3.8.7/Doc/reference/datamodel.rst
--- python3.8-3.8.6/Doc/reference/datamodel.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/reference/datamodel.rst 2020-12-21 16:25:24.000000000 +0000
@@ -182,6 +182,24 @@
related to mathematical numbers, but subject to the limitations of numerical
representation in computers.
+ The string representations of the numeric classes, computed by
+ :meth:`__repr__` and :meth:`__str__`, have the following
+ properties:
+
+ * They are valid numeric literals which, when passed to their
+ class constructor, produce an object having the value of the
+ original numeric.
+
+ * The representation is in base 10, when possible.
+
+ * Leading zeros, possibly excepting a single zero before a
+ decimal point, are not shown.
+
+ * Trailing zeros, possibly excepting a single zero after a
+ decimal point, are not shown.
+
+ * A sign is shown only when the number is negative.
+
Python distinguishes between integers, floating point numbers, and complex
numbers:
@@ -1372,12 +1390,14 @@
context (e.g., in the condition of an ``if`` statement), Python will call
:func:`bool` on the value to determine if the result is true or false.
- By default, :meth:`__ne__` delegates to :meth:`__eq__` and
- inverts the result unless it is ``NotImplemented``. There are no other
- implied relationships among the comparison operators, for example,
- the truth of ``(x` ``object.__getattr__`` with arguments
+ ``obj`` and ``name``.
+
.. method:: object.__setattr__(self, name, value)
@@ -1546,12 +1572,24 @@
call the base class method with the same name, for example,
``object.__setattr__(self, name, value)``.
+ .. audit-event:: object.__setattr__ obj,name,value object.__setattr__
+
+ For certain sensitive attribute assignments, raises an
+ :ref:`auditing event ` ``object.__setattr__`` with arguments
+ ``obj``, ``name``, ``value``.
+
.. method:: object.__delattr__(self, name)
Like :meth:`__setattr__` but for attribute deletion instead of assignment. This
should only be implemented if ``del obj.name`` is meaningful for the object.
+ .. audit-event:: object.__delattr__ obj,name object.__delattr__
+
+ For certain sensitive attribute deletions, raises an
+ :ref:`auditing event ` ``object.__delattr__`` with arguments
+ ``obj`` and ``name``.
+
.. method:: object.__dir__(self)
@@ -2125,7 +2163,7 @@
.. index:: pair: call; instance
Called when the instance is "called" as a function; if this method is defined,
- ``x(arg1, arg2, ...)`` is a shorthand for ``x.__call__(arg1, arg2, ...)``.
+ ``x(arg1, arg2, ...)`` roughly translates to ``type(x).__call__(x, arg1, ...)``.
.. _sequence-types:
@@ -2371,10 +2409,11 @@
.. note::
- If the right operand's type is a subclass of the left operand's type and that
- subclass provides the reflected method for the operation, this method will be
- called before the left operand's non-reflected method. This behavior allows
- subclasses to override their ancestors' operations.
+ If the right operand's type is a subclass of the left operand's type and
+ that subclass provides a different implementation of the reflected method
+ for the operation, this method will be called before the left operand's
+ non-reflected method. This behavior allows subclasses to override their
+ ancestors' operations.
.. method:: object.__iadd__(self, other)
@@ -2773,6 +2812,6 @@
method—that will instead have the opposite effect of explicitly
*blocking* such fallback.
-.. [#] For operands of the same type, it is assumed that if the non-reflected method
- (such as :meth:`__add__`) fails the operation is not supported, which is why the
- reflected method is not called.
+.. [#] For operands of the same type, it is assumed that if the non-reflected
+ method -- such as :meth:`__add__` -- fails then the overall operation is not
+ supported, which is why the reflected method is not called.
diff -Nru python3.8-3.8.6/Doc/reference/expressions.rst python3.8-3.8.7/Doc/reference/expressions.rst
--- python3.8-3.8.6/Doc/reference/expressions.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/reference/expressions.rst 2020-12-21 16:25:24.000000000 +0000
@@ -162,6 +162,8 @@
Displays for lists, sets and dictionaries
-----------------------------------------
+.. index:: single: comprehensions
+
For constructing a list, a set or a dictionary Python provides special syntax
called "displays", each of them in two flavors:
@@ -260,6 +262,7 @@
.. index::
pair: set; display
+ pair: set; comprehensions
object: set
single: {} (curly brackets); set expression
single: , (comma); expression list
@@ -287,6 +290,7 @@
.. index::
pair: dictionary; display
+ pair: dictionary; comprehensions
key, datum, key/datum pair
object: dictionary
single: {} (curly brackets); dictionary expression
diff -Nru python3.8-3.8.6/Doc/reference/import.rst python3.8-3.8.7/Doc/reference/import.rst
--- python3.8-3.8.6/Doc/reference/import.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/reference/import.rst 2020-12-21 16:25:24.000000000 +0000
@@ -202,6 +202,8 @@
reinitialise the module contents by rerunning the module's code.
+.. _finders-and-loaders:
+
Finders and loaders
-------------------
@@ -678,7 +680,7 @@
Cached bytecode invalidation
----------------------------
-Before Python loads cached bytecode from ``.pyc`` file, it checks whether the
+Before Python loads cached bytecode from a ``.pyc`` file, it checks whether the
cache is up-to-date with the source ``.py`` file. By default, Python does this
by storing the source's last-modified timestamp and size in the cache file when
writing it. At runtime, the import system then validates the cache file by
@@ -855,9 +857,8 @@
This spec will always have "loader" set (with one exception).
To indicate to the import machinery that the spec represents a namespace
-:term:`portion`, the path entry finder sets "loader" on the spec to
-``None`` and "submodule_search_locations" to a list containing the
-portion.
+:term:`portion`, the path entry finder sets "submodule_search_locations" to
+a list containing the portion.
.. versionchanged:: 3.4
:meth:`~importlib.abc.PathEntryFinder.find_spec` replaced
@@ -873,18 +874,7 @@
:meth:`~importlib.abc.PathEntryFinder.find_loader` takes one argument, the
fully qualified name of the module being imported. ``find_loader()``
returns a 2-tuple where the first item is the loader and the second item
- is a namespace :term:`portion`. When the first item (i.e. the loader) is
- ``None``, this means that while the path entry finder does not have a
- loader for the named module, it knows that the path entry contributes to
- a namespace portion for the named module. This will almost always be the
- case where Python is asked to import a namespace package that has no
- physical presence on the file system. When a path entry finder returns
- ``None`` for the loader, the second item of the 2-tuple return value must
- be a sequence, although it can be empty.
-
- If ``find_loader()`` returns a non-``None`` loader value, the portion is
- ignored and the loader is returned from the path based finder, terminating
- the search through the path entries.
+ is a namespace :term:`portion`.
For backwards compatibility with other implementations of the import
protocol, many path entry finders also support the same,
diff -Nru python3.8-3.8.6/Doc/reference/simple_stmts.rst python3.8-3.8.7/Doc/reference/simple_stmts.rst
--- python3.8-3.8.6/Doc/reference/simple_stmts.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/reference/simple_stmts.rst 2020-12-21 16:25:24.000000000 +0000
@@ -874,8 +874,8 @@
* blank lines, and
* other future statements.
-The only feature in Python 3.7 that requires using the future statement is
-``annotations``.
+The only feature that requires using the future statement is
+``annotations`` (see :pep:`563`).
All historical features enabled by the future statement are still recognized
by Python 3. The list includes ``absolute_import``, ``division``,
diff -Nru python3.8-3.8.6/Doc/tools/extensions/c_annotations.py python3.8-3.8.7/Doc/tools/extensions/c_annotations.py
--- python3.8-3.8.6/Doc/tools/extensions/c_annotations.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tools/extensions/c_annotations.py 2020-12-21 16:25:24.000000000 +0000
@@ -79,9 +79,9 @@
classes=['stableabi']))
if par['objtype'] != 'function':
continue
- if not par[0].has_key('names') or not par[0]['names']:
+ if not par[0].has_key('ids') or not par[0]['ids']:
continue
- name = par[0]['names'][0]
+ name = par[0]['ids'][0]
if name.startswith("c."):
name = name[2:]
entry = self.get(name)
diff -Nru python3.8-3.8.6/Doc/tools/static/switchers.js python3.8-3.8.7/Doc/tools/static/switchers.js
--- python3.8-3.8.6/Doc/tools/static/switchers.js 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tools/static/switchers.js 2020-12-21 16:25:24.000000000 +0000
@@ -15,7 +15,6 @@
'3.8': '3.8',
'3.7': '3.7',
'3.6': '3.6',
- '3.5': '3.5',
'2.7': '2.7',
};
diff -Nru python3.8-3.8.6/Doc/tools/susp-ignored.csv python3.8-3.8.7/Doc/tools/susp-ignored.csv
--- python3.8-3.8.6/Doc/tools/susp-ignored.csv 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tools/susp-ignored.csv 2020-12-21 16:25:24.000000000 +0000
@@ -12,7 +12,6 @@
extending/extending,,:set,"if (PyArg_ParseTuple(args, ""O:set_callback"", &temp)) {"
extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {"
faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr("
-faq/programming,,::,for x in sequence[::-1]:
faq/programming,,:reduce,"print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,"
faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,"
faq/windows,,:d48eceb,"Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32"
diff -Nru python3.8-3.8.6/Doc/tools/templates/indexsidebar.html python3.8-3.8.7/Doc/tools/templates/indexsidebar.html
--- python3.8-3.8.6/Doc/tools/templates/indexsidebar.html 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tools/templates/indexsidebar.html 2020-12-21 16:25:24.000000000 +0000
@@ -7,7 +7,6 @@
diff -Nru python3.8-3.8.6/Doc/tutorial/datastructures.rst python3.8-3.8.7/Doc/tutorial/datastructures.rst
--- python3.8-3.8.6/Doc/tutorial/datastructures.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tutorial/datastructures.rst 2020-12-21 16:25:24.000000000 +0000
@@ -78,7 +78,7 @@
Return the number of times *x* appears in the list.
-.. method:: list.sort(key=None, reverse=False)
+.. method:: list.sort(*, key=None, reverse=False)
:noindex:
Sort the items of the list in place (the arguments can be used for sort
diff -Nru python3.8-3.8.6/Doc/tutorial/inputoutput.rst python3.8-3.8.7/Doc/tutorial/inputoutput.rst
--- python3.8-3.8.6/Doc/tutorial/inputoutput.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/tutorial/inputoutput.rst 2020-12-21 16:25:24.000000000 +0000
@@ -329,11 +329,16 @@
If you're not using the :keyword:`with` keyword, then you should call
``f.close()`` to close the file and immediately free up any system
-resources used by it. If you don't explicitly close a file, Python's
-garbage collector will eventually destroy the object and close the
-open file for you, but the file may stay open for a while. Another
-risk is that different Python implementations will do this clean-up at
-different times.
+resources used by it.
+
+.. warning::
+ Calling ``f.write()`` without using the :keyword:`!with` keyword or calling
+ ``f.close()`` **might** result in the arguments
+ of ``f.write()`` not being completely written to the disk, even if the
+ program exits successfully.
+
+..
+ See also https://bugs.python.org/issue17852
After a file object is closed, either by a :keyword:`with` statement
or by calling ``f.close()``, attempts to use the file object will
diff -Nru python3.8-3.8.6/Doc/using/cmdline.rst python3.8-3.8.7/Doc/using/cmdline.rst
--- python3.8-3.8.6/Doc/using/cmdline.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/using/cmdline.rst 2020-12-21 16:25:24.000000000 +0000
@@ -551,7 +551,7 @@
the interactive session. You can also change the prompts :data:`sys.ps1` and
:data:`sys.ps2` and the hook :data:`sys.__interactivehook__` in this file.
- .. audit-event:: cpython.run_startup filename PYTHONSTARTUP
+ .. audit-event:: cpython.run_startup filename envvar-PYTHONSTARTUP
Raises an :ref:`auditing event ` ``cpython.run_startup`` with
the filename as the argument when called on startup.
diff -Nru python3.8-3.8.6/Doc/using/windows.rst python3.8-3.8.7/Doc/using/windows.rst
--- python3.8-3.8.6/Doc/using/windows.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/using/windows.rst 2020-12-21 16:25:24.000000000 +0000
@@ -103,9 +103,9 @@
In the latest versions of Windows, this limitation can be expanded to
approximately 32,000 characters. Your administrator will need to activate the
-"Enable Win32 long paths" group policy, or set the registry value
-``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled``
-to ``1``.
+"Enable Win32 long paths" group policy, or set ``LongPathsEnabled`` to ``1``
+in the registry key
+``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``.
This allows the :func:`open` function, the :mod:`os` module and most other
path functionality to accept and return paths longer than 260 characters.
@@ -422,6 +422,12 @@
automatically via Windows Update, and can be detected by finding
``ucrtbase.dll`` in the system directory.
+.. note::
+
+ When running on Windows 7, Python 3.8 requires the KB2533623 update to be
+ installed. The embeddable distribution does not detect this update, and may
+ fail at runtime. Later versions of Windows include this update.
+
Third-party packages should be installed by the application installer alongside
the embedded distribution. Using pip to manage dependencies as for a regular
Python installation is not supported with this distribution, though with some
diff -Nru python3.8-3.8.6/Doc/whatsnew/3.8.rst python3.8-3.8.7/Doc/whatsnew/3.8.rst
--- python3.8-3.8.6/Doc/whatsnew/3.8.rst 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Doc/whatsnew/3.8.rst 2020-12-21 16:25:24.000000000 +0000
@@ -872,8 +872,18 @@
(Many people worked on this for eight years but the problem was finally
solved by Serhiy Storchaka in :issue:`13153`.)
+New in 3.8.1:
+
+Add option to toggle cursor blink off. (Contributed by Zackery Spytz
+in :issue:`4603`.)
+
+Escape key now closes IDLE completion windows. (Contributed by Johnny
+Najera in :issue:`38944`.)
+
The changes above have been backported to 3.7 maintenance releases.
+Add keywords to module name completion list. (Contributed by Terry J.
+Reedy in :issue:`37765`.)
inspect
-------
@@ -2105,9 +2115,6 @@
(Contributed by Antoine Pitrou in :issue:`32388`.)
-* The :c:func:`PyCode_New` has a new parameter in the second position (*posonlyargcount*)
- to support :pep:`570`, indicating the number of positional-only arguments.
-
* The functions :c:func:`PyNode_AddChild` and :c:func:`PyParser_AddToken` now accept
two additional ``int`` arguments *end_lineno* and *end_col_offset*.
diff -Nru python3.8-3.8.6/Include/cpython/fileobject.h python3.8-3.8.7/Include/cpython/fileobject.h
--- python3.8-3.8.6/Include/cpython/fileobject.h 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Include/cpython/fileobject.h 2020-12-21 16:25:24.000000000 +0000
@@ -8,14 +8,6 @@
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
-PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
-#endif
-
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
-PyAPI_DATA(int) Py_UTF8Mode;
-#endif
-
/* The std printer acts as a preliminary sys.stderr until the new io
infrastructure is in place. */
PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
diff -Nru python3.8-3.8.6/Include/fileobject.h python3.8-3.8.7/Include/fileobject.h
--- python3.8-3.8.6/Include/fileobject.h 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Include/fileobject.h 2020-12-21 16:25:24.000000000 +0000
@@ -20,8 +20,15 @@
If non-NULL, this is different than the default encoding for strings
*/
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
+#endif
PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
+PyAPI_DATA(int) Py_UTF8Mode;
+#endif
+
/* A routine to check if a file descriptor can be select()-ed. */
#ifdef _MSC_VER
/* On Windows, any socket fd can be select()-ed, no matter how high */
diff -Nru python3.8-3.8.6/Include/internal/pycore_pylifecycle.h python3.8-3.8.7/Include/internal/pycore_pylifecycle.h
--- python3.8-3.8.6/Include/internal/pycore_pylifecycle.h 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Include/internal/pycore_pylifecycle.h 2020-12-21 16:25:24.000000000 +0000
@@ -69,6 +69,8 @@
extern void PySet_Fini(void);
extern void PyBytes_Fini(void);
extern void PyFloat_Fini(void);
+
+extern int _PySignal_Init(int install_signal_handlers);
extern void PyOS_FiniInterrupts(void);
extern void PySlice_Fini(void);
extern void PyAsyncGen_Fini(void);
diff -Nru python3.8-3.8.6/Include/patchlevel.h python3.8-3.8.7/Include/patchlevel.h
--- python3.8-3.8.6/Include/patchlevel.h 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Include/patchlevel.h 2020-12-21 16:25:24.000000000 +0000
@@ -18,12 +18,12 @@
/*--start constants--*/
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 8
-#define PY_MICRO_VERSION 6
+#define PY_MICRO_VERSION 7
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.8.6"
+#define PY_VERSION "3.8.7"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff -Nru python3.8-3.8.6/Lib/ast.py python3.8-3.8.7/Lib/ast.py
--- python3.8-3.8.6/Lib/ast.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/ast.py 2020-12-21 16:25:24.000000000 +0000
@@ -285,7 +285,7 @@
def _pad_whitespace(source):
- """Replace all chars except '\f\t' in a line with spaces."""
+ r"""Replace all chars except '\f\t' in a line with spaces."""
result = ''
for c in source:
if c in '\f\t':
diff -Nru python3.8-3.8.6/Lib/asyncio/base_futures.py python3.8-3.8.7/Lib/asyncio/base_futures.py
--- python3.8-3.8.6/Lib/asyncio/base_futures.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/asyncio/base_futures.py 2020-12-21 16:25:24.000000000 +0000
@@ -1,6 +1,7 @@
__all__ = ()
import reprlib
+from _thread import get_ident
from . import format_helpers
@@ -41,6 +42,16 @@
return f'cb=[{cb}]'
+# bpo-42183: _repr_running is needed for repr protection
+# when a Future or Task result contains itself directly or indirectly.
+# The logic is borrowed from @reprlib.recursive_repr decorator.
+# Unfortunately, the direct decorator usage is impossible because of
+# AttributeError: '_asyncio.Task' object has no attribute '__module__' error.
+#
+# After fixing this thing we can return to the decorator based approach.
+_repr_running = set()
+
+
def _future_repr_info(future):
# (Future) -> str
"""helper function for Future.__repr__"""
@@ -49,9 +60,17 @@
if future._exception is not None:
info.append(f'exception={future._exception!r}')
else:
- # use reprlib to limit the length of the output, especially
- # for very long strings
- result = reprlib.repr(future._result)
+ key = id(future), get_ident()
+ if key in _repr_running:
+ result = '...'
+ else:
+ _repr_running.add(key)
+ try:
+ # use reprlib to limit the length of the output, especially
+ # for very long strings
+ result = reprlib.repr(future._result)
+ finally:
+ _repr_running.discard(key)
info.append(f'result={result}')
if future._callbacks:
info.append(_format_callbacks(future._callbacks))
diff -Nru python3.8-3.8.6/Lib/asyncio/exceptions.py python3.8-3.8.7/Lib/asyncio/exceptions.py
--- python3.8-3.8.6/Lib/asyncio/exceptions.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/asyncio/exceptions.py 2020-12-21 16:25:24.000000000 +0000
@@ -34,8 +34,9 @@
- expected: total number of expected bytes (or None if unknown)
"""
def __init__(self, partial, expected):
+ r_expected = 'undefined' if expected is None else repr(expected)
super().__init__(f'{len(partial)} bytes read on a total of '
- f'{expected!r} expected bytes')
+ f'{r_expected} expected bytes')
self.partial = partial
self.expected = expected
diff -Nru python3.8-3.8.6/Lib/asyncio/tasks.py python3.8-3.8.7/Lib/asyncio/tasks.py
--- python3.8-3.8.6/Lib/asyncio/tasks.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/asyncio/tasks.py 2020-12-21 16:25:24.000000000 +0000
@@ -394,7 +394,7 @@
async def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED):
"""Wait for the Futures and coroutines given by fs to complete.
- The sequence futures must not be empty.
+ The fs iterable must not be empty.
Coroutines will be wrapped in Tasks.
@@ -484,7 +484,10 @@
return fut.result()
else:
fut.remove_done_callback(cb)
- fut.cancel()
+ # We must ensure that the task is not running
+ # after wait_for() returns.
+ # See https://bugs.python.org/issue32751
+ await _cancel_and_wait(fut, loop=loop)
raise
if fut.done():
@@ -580,7 +583,7 @@
Note: The futures 'f' are not necessarily members of fs.
"""
if futures.isfuture(fs) or coroutines.iscoroutine(fs):
- raise TypeError(f"expect a list of futures, not {type(fs).__name__}")
+ raise TypeError(f"expect an iterable of futures, not {type(fs).__name__}")
from .queues import Queue # Import here to avoid circular import problem.
done = Queue(loop=loop)
diff -Nru python3.8-3.8.6/Lib/asyncio/unix_events.py python3.8-3.8.7/Lib/asyncio/unix_events.py
--- python3.8-3.8.6/Lib/asyncio/unix_events.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/asyncio/unix_events.py 2020-12-21 16:25:24.000000000 +0000
@@ -1152,13 +1152,15 @@
def close(self):
self._callbacks.clear()
- if self._saved_sighandler is not None:
- handler = signal.getsignal(signal.SIGCHLD)
- if handler != self._sig_chld:
- logger.warning("SIGCHLD handler was changed by outside code")
- else:
- signal.signal(signal.SIGCHLD, self._saved_sighandler)
- self._saved_sighandler = None
+ if self._saved_sighandler is None:
+ return
+
+ handler = signal.getsignal(signal.SIGCHLD)
+ if handler != self._sig_chld:
+ logger.warning("SIGCHLD handler was changed by outside code")
+ else:
+ signal.signal(signal.SIGCHLD, self._saved_sighandler)
+ self._saved_sighandler = None
def __enter__(self):
return self
@@ -1185,15 +1187,17 @@
# The reason to do it here is that attach_loop() is called from
# unix policy only for the main thread.
# Main thread is required for subscription on SIGCHLD signal
+ if self._saved_sighandler is not None:
+ return
+
+ self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld)
if self._saved_sighandler is None:
- self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld)
- if self._saved_sighandler is None:
- logger.warning("Previous SIGCHLD handler was set by non-Python code, "
- "restore to default handler on watcher close.")
- self._saved_sighandler = signal.SIG_DFL
+ logger.warning("Previous SIGCHLD handler was set by non-Python code, "
+ "restore to default handler on watcher close.")
+ self._saved_sighandler = signal.SIG_DFL
- # Set SA_RESTART to limit EINTR occurrences.
- signal.siginterrupt(signal.SIGCHLD, False)
+ # Set SA_RESTART to limit EINTR occurrences.
+ signal.siginterrupt(signal.SIGCHLD, False)
def _do_waitpid_all(self):
for pid in list(self._callbacks):
diff -Nru python3.8-3.8.6/Lib/binhex.py python3.8-3.8.7/Lib/binhex.py
--- python3.8-3.8.6/Lib/binhex.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/binhex.py 2020-12-21 16:25:24.000000000 +0000
@@ -100,12 +100,12 @@
first = 0
while first <= len(self.hqxdata) - self.linelen:
last = first + self.linelen
- self.ofp.write(self.hqxdata[first:last] + b'\n')
+ self.ofp.write(self.hqxdata[first:last] + b'\r')
self.linelen = LINELEN
first = last
self.hqxdata = self.hqxdata[first:]
if force:
- self.ofp.write(self.hqxdata + b':\n')
+ self.ofp.write(self.hqxdata + b':\r')
def close(self):
if self.data:
diff -Nru python3.8-3.8.6/Lib/cProfile.py python3.8-3.8.7/Lib/cProfile.py
--- python3.8-3.8.6/Lib/cProfile.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/cProfile.py 2020-12-21 16:25:24.000000000 +0000
@@ -168,6 +168,11 @@
(options, args) = parser.parse_args()
sys.argv[:] = args
+ # The script that we're profiling may chdir, so capture the absolute path
+ # to the output file at startup.
+ if options.outfile is not None:
+ options.outfile = os.path.abspath(options.outfile)
+
if len(args) > 0:
if options.module:
code = "run_module(modname, run_name='__main__')"
diff -Nru python3.8-3.8.6/Lib/ctypes/test/test_find.py python3.8-3.8.7/Lib/ctypes/test/test_find.py
--- python3.8-3.8.6/Lib/ctypes/test/test_find.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/ctypes/test/test_find.py 2020-12-21 16:25:24.000000000 +0000
@@ -1,4 +1,5 @@
import unittest
+import unittest.mock
import os.path
import sys
import test.support
@@ -72,7 +73,7 @@
@unittest.skipUnless(sys.platform.startswith('linux'),
'Test only valid for Linux')
-class LibPathFindTest(unittest.TestCase):
+class FindLibraryLinux(unittest.TestCase):
def test_find_on_libpath(self):
import subprocess
import tempfile
@@ -111,6 +112,15 @@
# LD_LIBRARY_PATH)
self.assertEqual(find_library(libname), 'lib%s.so' % libname)
+ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
+ def test_find_library_with_ld(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \
+ unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
if __name__ == "__main__":
unittest.main()
diff -Nru python3.8-3.8.6/Lib/ctypes/test/test_wintypes.py python3.8-3.8.7/Lib/ctypes/test/test_wintypes.py
--- python3.8-3.8.6/Lib/ctypes/test/test_wintypes.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/ctypes/test/test_wintypes.py 2020-12-21 16:25:24.000000000 +0000
@@ -1,12 +1,13 @@
-import sys
import unittest
+# also work on POSIX
+
from ctypes import *
+from ctypes import wintypes
+
-@unittest.skipUnless(sys.platform.startswith('win'), 'Windows-only test')
class WinTypesTest(unittest.TestCase):
def test_variant_bool(self):
- from ctypes import wintypes
# reads 16-bits from memory, anything non-zero is True
for true_value in (1, 32767, 32768, 65535, 65537):
true = POINTER(c_int16)(c_int16(true_value))
@@ -37,5 +38,6 @@
vb.value = []
self.assertIs(vb.value, False)
+
if __name__ == "__main__":
unittest.main()
diff -Nru python3.8-3.8.6/Lib/ctypes/util.py python3.8-3.8.7/Lib/ctypes/util.py
--- python3.8-3.8.6/Lib/ctypes/util.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/ctypes/util.py 2020-12-21 16:25:24.000000000 +0000
@@ -93,6 +93,12 @@
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
import re, tempfile
+ def _is_elf(filename):
+ "Return True if the given file is an ELF file"
+ elf_header = b'\x7fELF'
+ with open(filename, 'br') as thefile:
+ return thefile.read(4) == elf_header
+
def _findLib_gcc(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
@@ -130,10 +136,17 @@
# Raised if the file was already removed, which is the normal
# behaviour of GCC if linking fails
pass
- res = re.search(expr, trace)
+ res = re.findall(expr, trace)
if not res:
return None
- return os.fsdecode(res.group(0))
+
+ for file in res:
+ # Check if the given file is an elf file: gcc can report
+ # some files that are linker scripts and not actual
+ # shared objects. See bpo-41976 for more details
+ if not _is_elf(file):
+ continue
+ return os.fsdecode(file)
if sys.platform == "sunos5":
@@ -299,17 +312,22 @@
stderr=subprocess.PIPE,
universal_newlines=True)
out, _ = p.communicate()
- res = re.search(expr, os.fsdecode(out))
- if res:
- result = res.group(0)
- except Exception as e:
+ res = re.findall(expr, os.fsdecode(out))
+ for file in res:
+ # Check if the given file is an elf file: gcc can report
+ # some files that are linker scripts and not actual
+ # shared objects. See bpo-41976 for more details
+ if not _is_elf(file):
+ continue
+ return os.fsdecode(file)
+ except Exception:
pass # result will be None
return result
def find_library(name):
# See issue #9998
return _findSoname_ldconfig(name) or \
- _get_soname(_findLib_gcc(name) or _findLib_ld(name))
+ _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
################################################################
# test code
diff -Nru python3.8-3.8.6/Lib/datetime.py python3.8-3.8.7/Lib/datetime.py
--- python3.8-3.8.6/Lib/datetime.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/datetime.py 2020-12-21 16:25:24.000000000 +0000
@@ -1418,7 +1418,8 @@
part is omitted if self.microsecond == 0.
The optional argument timespec specifies the number of additional
- terms of the time to include.
+ terms of the time to include. Valid options are 'auto', 'hours',
+ 'minutes', 'seconds', 'milliseconds' and 'microseconds'.
"""
s = _format_time(self._hour, self._minute, self._second,
self._microsecond, timespec)
@@ -1544,7 +1545,7 @@
self._tzinfo = tzinfo
def __reduce_ex__(self, protocol):
- return (time, self._getstate(protocol))
+ return (self.__class__, self._getstate(protocol))
def __reduce__(self):
return self.__reduce_ex__(2)
@@ -1902,7 +1903,8 @@
time, default 'T'.
The optional argument timespec specifies the number of additional
- terms of the time to include.
+ terms of the time to include. Valid options are 'auto', 'hours',
+ 'minutes', 'seconds', 'milliseconds' and 'microseconds'.
"""
s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) +
_format_time(self._hour, self._minute, self._second,
diff -Nru python3.8-3.8.6/Lib/email/generator.py python3.8-3.8.7/Lib/email/generator.py
--- python3.8-3.8.6/Lib/email/generator.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/email/generator.py 2020-12-21 16:25:24.000000000 +0000
@@ -186,7 +186,11 @@
# If we munged the cte, copy the message again and re-fix the CTE.
if munge_cte:
msg = deepcopy(msg)
- msg.replace_header('content-transfer-encoding', munge_cte[0])
+ # Preserve the header order if the CTE header already exists.
+ if msg.get('content-transfer-encoding') is None:
+ msg['Content-Transfer-Encoding'] = munge_cte[0]
+ else:
+ msg.replace_header('content-transfer-encoding', munge_cte[0])
msg.replace_header('content-type', munge_cte[1])
# Write the headers. First we see if the message object wants to
# handle that itself. If not, we'll do it generically.
diff -Nru python3.8-3.8.6/Lib/email/message.py python3.8-3.8.7/Lib/email/message.py
--- python3.8-3.8.6/Lib/email/message.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/email/message.py 2020-12-21 16:25:24.000000000 +0000
@@ -141,7 +141,7 @@
header. For backward compatibility reasons, if maxheaderlen is
not specified it defaults to 0, so you must override it explicitly
if you want a different maxheaderlen. 'policy' is passed to the
- Generator instance used to serialize the mesasge; if it is not
+ Generator instance used to serialize the message; if it is not
specified the policy associated with the message instance is used.
If the message object contains binary data that is not encoded
@@ -958,7 +958,7 @@
header. maxheaderlen is retained for backward compatibility with the
base Message class, but defaults to None, meaning that the policy value
for max_line_length controls the header maximum length. 'policy' is
- passed to the Generator instance used to serialize the mesasge; if it
+ passed to the Generator instance used to serialize the message; if it
is not specified the policy associated with the message instance is
used.
"""
Binary files /tmp/tmpgwkoGW/C7ZJ71KE1Z/python3.8-3.8.6/Lib/ensurepip/_bundled/pip-20.2.1-py2.py3-none-any.whl and /tmp/tmpgwkoGW/uSs3611ZLj/python3.8-3.8.7/Lib/ensurepip/_bundled/pip-20.2.1-py2.py3-none-any.whl differ
Binary files /tmp/tmpgwkoGW/C7ZJ71KE1Z/python3.8-3.8.6/Lib/ensurepip/_bundled/pip-20.2.3-py2.py3-none-any.whl and /tmp/tmpgwkoGW/uSs3611ZLj/python3.8-3.8.7/Lib/ensurepip/_bundled/pip-20.2.3-py2.py3-none-any.whl differ
diff -Nru python3.8-3.8.6/Lib/ensurepip/__init__.py python3.8-3.8.7/Lib/ensurepip/__init__.py
--- python3.8-3.8.6/Lib/ensurepip/__init__.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/ensurepip/__init__.py 2020-12-21 16:25:24.000000000 +0000
@@ -4,6 +4,7 @@
import sys
import runpy
import tempfile
+import subprocess
__all__ = ["version", "bootstrap"]
@@ -11,7 +12,7 @@
_SETUPTOOLS_VERSION = "49.2.1"
-_PIP_VERSION = "20.2.1"
+_PIP_VERSION = "20.2.3"
_PROJECTS = [
("setuptools", _SETUPTOOLS_VERSION, "py3"),
@@ -20,22 +21,18 @@
def _run_pip(args, additional_paths=None):
- # Add our bundled software to the sys.path so we can import it
- if additional_paths is not None:
- sys.path = additional_paths + sys.path
-
- # Invoke pip as if it's the main module, and catch the exit.
- backup_argv = sys.argv[:]
- sys.argv[1:] = args
- try:
- # run_module() alters sys.modules and sys.argv, but restores them at exit
- runpy.run_module("pip", run_name="__main__", alter_sys=True)
- except SystemExit as exc:
- return exc.code
- finally:
- sys.argv[:] = backup_argv
-
- raise SystemError("pip did not exit, this should never happen")
+ # Run the bootstraping in a subprocess to avoid leaking any state that happens
+ # after pip has executed. Particulary, this avoids the case when pip holds onto
+ # the files in *additional_paths*, preventing us to remove them at the end of the
+ # invocation.
+ code = f"""
+import runpy
+import sys
+sys.path = {additional_paths or []} + sys.path
+sys.argv[1:] = {args}
+runpy.run_module("pip", run_name="__main__", alter_sys=True)
+"""
+ return subprocess.run([sys.executable, "-c", code], check=True).returncode
def version():
diff -Nru python3.8-3.8.6/Lib/enum.py python3.8-3.8.7/Lib/enum.py
--- python3.8-3.8.6/Lib/enum.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/enum.py 2020-12-21 16:25:24.000000000 +0000
@@ -10,31 +10,41 @@
def _is_descriptor(obj):
- """Returns True if obj is a descriptor, False otherwise."""
+ """
+ Returns True if obj is a descriptor, False otherwise.
+ """
return (
hasattr(obj, '__get__') or
hasattr(obj, '__set__') or
- hasattr(obj, '__delete__'))
-
+ hasattr(obj, '__delete__')
+ )
def _is_dunder(name):
- """Returns True if a __dunder__ name, False otherwise."""
- return (len(name) > 4 and
+ """
+ Returns True if a __dunder__ name, False otherwise.
+ """
+ return (
+ len(name) > 4 and
name[:2] == name[-2:] == '__' and
name[2] != '_' and
- name[-3] != '_')
-
+ name[-3] != '_'
+ )
def _is_sunder(name):
- """Returns True if a _sunder_ name, False otherwise."""
- return (len(name) > 2 and
+ """
+ Returns True if a _sunder_ name, False otherwise.
+ """
+ return (
+ len(name) > 2 and
name[0] == name[-1] == '_' and
name[1:2] != '_' and
- name[-2:-1] != '_')
-
+ name[-2:-1] != '_'
+ )
def _make_class_unpicklable(cls):
- """Make the given class un-picklable."""
+ """
+ Make the given class un-picklable.
+ """
def _break_on_call_reduce(self, proto):
raise TypeError('%r cannot be pickled' % self)
cls.__reduce_ex__ = _break_on_call_reduce
@@ -49,11 +59,11 @@
class _EnumDict(dict):
- """Track enum member order and ensure member names are not reused.
+ """
+ Track enum member order and ensure member names are not reused.
EnumMeta will use the names found in self._member_names as the
enumeration member names.
-
"""
def __init__(self):
super().__init__()
@@ -63,13 +73,13 @@
self._auto_called = False
def __setitem__(self, key, value):
- """Changes anything not dundered or not a descriptor.
+ """
+ Changes anything not dundered or not a descriptor.
If an enum member name is used twice, an error is raised; duplicate
values are not checked for.
Single underscore (sunder) names are reserved.
-
"""
if _is_sunder(key):
if key not in (
@@ -90,7 +100,10 @@
self._ignore = value
already = set(value) & set(self._member_names)
if already:
- raise ValueError('_ignore_ cannot specify already set names: %r' % (already, ))
+ raise ValueError(
+ '_ignore_ cannot specify already set names: %r'
+ % (already, )
+ )
elif _is_dunder(key):
if key == '__order__':
key = '_order_'
@@ -105,7 +118,12 @@
raise TypeError('%r already defined as: %r' % (key, self[key]))
if isinstance(value, auto):
if value.value == _auto_null:
- value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
+ value.value = self._generate_next_value(
+ key,
+ 1,
+ len(self._member_names),
+ self._last_values[:],
+ )
self._auto_called = True
value = value.value
self._member_names.append(key)
@@ -118,9 +136,10 @@
# This is also why there are checks in EnumMeta like `if Enum is not None`
Enum = None
-
class EnumMeta(type):
- """Metaclass for Enum"""
+ """
+ Metaclass for Enum
+ """
@classmethod
def __prepare__(metacls, cls, bases):
# check that previous enum members do not exist
@@ -130,7 +149,9 @@
# inherit previous flags and _generate_next_value_ function
member_type, first_enum = metacls._get_mixins_(cls, bases)
if first_enum is not None:
- enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
+ enum_dict['_generate_next_value_'] = getattr(
+ first_enum, '_generate_next_value_', None,
+ )
return enum_dict
def __new__(metacls, cls, bases, classdict):
@@ -145,8 +166,9 @@
for key in ignore:
classdict.pop(key, None)
member_type, first_enum = metacls._get_mixins_(cls, bases)
- __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
- first_enum)
+ __new__, save_new, use_args = metacls._find_new_(
+ classdict, member_type, first_enum,
+ )
# save enum items into separate mapping so they don't get baked into
# the new class
@@ -175,9 +197,11 @@
# save DynamicClassAttribute attributes from super classes so we know
# if we can take the shortcut of storing members in the class dict
- dynamic_attributes = {k for c in enum_class.mro()
- for k, v in c.__dict__.items()
- if isinstance(v, DynamicClassAttribute)}
+ dynamic_attributes = {
+ k for c in enum_class.mro()
+ for k, v in c.__dict__.items()
+ if isinstance(v, DynamicClassAttribute)
+ }
# Reverse value->name map for hashable values.
enum_class._value2member_map_ = {}
@@ -287,7 +311,8 @@
return True
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
- """Either returns an existing member, or creates a new enum class.
+ """
+ Either returns an existing member, or creates a new enum class.
This method is used both when an enum class is given a value to match
to an enumeration member (i.e. Color(3)) and for the functional API
@@ -309,12 +334,18 @@
not correct, unpickling will fail in some circumstances.
`type`, if set, will be mixed in as the first base class.
-
"""
if names is None: # simple value lookup
return cls.__new__(cls, value)
# otherwise, functional API: we're creating a new Enum type
- return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
+ return cls._create_(
+ value,
+ names,
+ module=module,
+ qualname=qualname,
+ type=type,
+ start=start,
+ )
def __contains__(cls, member):
if not isinstance(member, Enum):
@@ -327,22 +358,23 @@
# nicer error message when someone tries to delete an attribute
# (see issue19025).
if attr in cls._member_map_:
- raise AttributeError(
- "%s: cannot delete Enum member." % cls.__name__)
+ raise AttributeError("%s: cannot delete Enum member." % cls.__name__)
super().__delattr__(attr)
def __dir__(self):
- return (['__class__', '__doc__', '__members__', '__module__'] +
- self._member_names_)
+ return (
+ ['__class__', '__doc__', '__members__', '__module__']
+ + self._member_names_
+ )
def __getattr__(cls, name):
- """Return the enum member matching `name`
+ """
+ Return the enum member matching `name`
We use __getattr__ instead of descriptors or inserting into the enum
class' __dict__ in order to support `name` and `value` being both
properties for enum members (which live in the class' __dict__) and
enum members themselves.
-
"""
if _is_dunder(name):
raise AttributeError(name)
@@ -355,6 +387,9 @@
return cls._member_map_[name]
def __iter__(cls):
+ """
+ Returns members in definition order.
+ """
return (cls._member_map_[name] for name in cls._member_names_)
def __len__(cls):
@@ -362,11 +397,11 @@
@property
def __members__(cls):
- """Returns a mapping of member name->value.
+ """
+ Returns a mapping of member name->value.
This mapping lists all enum members, including aliases. Note that this
is a read-only view of the internal mapping.
-
"""
return MappingProxyType(cls._member_map_)
@@ -374,15 +409,18 @@
return "" % cls.__name__
def __reversed__(cls):
+ """
+ Returns members in reverse definition order.
+ """
return (cls._member_map_[name] for name in reversed(cls._member_names_))
def __setattr__(cls, name, value):
- """Block attempts to reassign Enum members.
+ """
+ Block attempts to reassign Enum members.
A simple assignment to the class namespace only changes one of the
several possible ways to get an Enum member from the Enum class,
resulting in an inconsistent Enumeration.
-
"""
member_map = cls.__dict__.get('_member_map_', {})
if name in member_map:
@@ -390,7 +428,8 @@
super().__setattr__(name, value)
def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):
- """Convenience method to create a new Enum class.
+ """
+ Convenience method to create a new Enum class.
`names` can be:
@@ -399,7 +438,6 @@
* An iterable of member names. Values are incremented by 1 from `start`.
* An iterable of (member name, value) pairs.
* A mapping of member name -> value pairs.
-
"""
metacls = cls.__class__
bases = (cls, ) if type is None else (type, cls)
@@ -486,15 +524,18 @@
for chain in bases:
for base in chain.__mro__:
if issubclass(base, Enum) and base._member_names_:
- raise TypeError("%s: cannot extend enumeration %r" % (class_name, base.__name__))
+ raise TypeError(
+ "%s: cannot extend enumeration %r"
+ % (class_name, base.__name__)
+ )
@staticmethod
def _get_mixins_(class_name, bases):
- """Returns the type for creating enum members, and the first inherited
+ """
+ Returns the type for creating enum members, and the first inherited
enum class.
bases: the tuple of bases that was given to __new__
-
"""
if not bases:
return object, Enum
@@ -506,12 +547,16 @@
for base in chain.__mro__:
if base is object:
continue
+ elif issubclass(base, Enum):
+ if base._member_type_ is not object:
+ data_types.append(base._member_type_)
+ break
elif '__new__' in base.__dict__:
if issubclass(base, Enum):
continue
data_types.append(candidate or base)
break
- elif not issubclass(base, Enum):
+ else:
candidate = base
if len(data_types) > 1:
raise TypeError('%r: too many data types: %r' % (class_name, data_types))
@@ -533,12 +578,12 @@
@staticmethod
def _find_new_(classdict, member_type, first_enum):
- """Returns the __new__ to be used for creating the enum members.
+ """
+ Returns the __new__ to be used for creating the enum members.
classdict: the class dictionary given to __new__
member_type: the data type whose __new__ will be used by default
first_enum: enumeration to check for an overriding __new__
-
"""
# now find the correct __new__, checking to see of one was defined
# by the user; also check earlier enum classes in case a __new__ was
@@ -578,10 +623,10 @@
class Enum(metaclass=EnumMeta):
- """Generic enumeration.
+ """
+ Generic enumeration.
Derive from this class to define new enumerations.
-
"""
def __new__(cls, value):
# all enum instances are actually created during class construction
@@ -624,6 +669,14 @@
raise exc
def _generate_next_value_(name, start, count, last_values):
+ """
+ Generate the next value when not given.
+
+ name: the name of the member
+ start: the initial start value or None
+ count: the number of existing members
+ last_value: the last value assigned or None
+ """
for last_value in reversed(last_values):
try:
return last_value + 1
@@ -644,21 +697,27 @@
return "%s.%s" % (self.__class__.__name__, self._name_)
def __dir__(self):
+ """
+ Returns all members and all public methods
+ """
added_behavior = [
m
for cls in self.__class__.mro()
for m in cls.__dict__
if m[0] != '_' and m not in self._member_map_
- ]
+ ] + [m for m in self.__dict__ if m[0] != '_']
return (['__class__', '__doc__', '__module__'] + added_behavior)
def __format__(self, format_spec):
+ """
+ Returns format using actual value type unless __str__ has been overridden.
+ """
# mixed-in Enums should use the mixed-in type's __format__, otherwise
# we can get strange results with the Enum name showing up instead of
# the value
# pure Enum branch, or branch with __str__ explicitly overridden
- str_overridden = type(self).__str__ != Enum.__str__
+ str_overridden = type(self).__str__ not in (Enum.__str__, Flag.__str__)
if self._member_type_ is object or str_overridden:
cls = str
val = str(self)
@@ -700,7 +759,9 @@
return self.name
class Flag(Enum):
- """Support for flags"""
+ """
+ Support for flags
+ """
def _generate_next_value_(name, start, count, last_values):
"""
@@ -723,6 +784,9 @@
@classmethod
def _missing_(cls, value):
+ """
+ Returns member (possibly creating it) if one can be found for value.
+ """
original_value = value
if value < 0:
value = ~value
@@ -752,6 +816,9 @@
return pseudo_member
def __contains__(self, other):
+ """
+ Returns True if self has at least the same flags set as other.
+ """
if not isinstance(other, self.__class__):
raise TypeError(
"unsupported operand type(s) for 'in': '%s' and '%s'" % (
@@ -810,10 +877,15 @@
class IntFlag(int, Flag):
- """Support for integer-based Flags"""
+ """
+ Support for integer-based Flags
+ """
@classmethod
def _missing_(cls, value):
+ """
+ Returns member (possibly creating it) if one can be found for value.
+ """
if not isinstance(value, int):
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
new_member = cls._create_pseudo_member_(value)
@@ -821,6 +893,9 @@
@classmethod
def _create_pseudo_member_(cls, value):
+ """
+ Create a composite member iff value contains only members.
+ """
pseudo_member = cls._value2member_map_.get(value, None)
if pseudo_member is None:
need_to_create = [value]
@@ -875,11 +950,15 @@
def _high_bit(value):
- """returns index of highest bit, or -1 if value is zero or negative"""
+ """
+ returns index of highest bit, or -1 if value is zero or negative
+ """
return value.bit_length() - 1
def unique(enumeration):
- """Class decorator for enumerations ensuring unique member values."""
+ """
+ Class decorator for enumerations ensuring unique member values.
+ """
duplicates = []
for name, member in enumeration.__members__.items():
if name != member.name:
@@ -892,7 +971,9 @@
return enumeration
def _decompose(flag, value):
- """Extract all members from the value."""
+ """
+ Extract all members from the value.
+ """
# _decompose is only called if the value is not named
not_covered = value
negative = value < 0
diff -Nru python3.8-3.8.6/Lib/http/client.py python3.8-3.8.7/Lib/http/client.py
--- python3.8-3.8.6/Lib/http/client.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/http/client.py 2020-12-21 16:25:24.000000000 +0000
@@ -846,7 +846,7 @@
the endpoint passed to `set_tunnel`. This done by sending an HTTP
CONNECT request to the proxy server when the connection is established.
- This method must be called before the HTML connection has been
+ This method must be called before the HTTP connection has been
established.
The headers argument should be a mapping of extra HTTP headers to send
diff -Nru python3.8-3.8.6/Lib/idlelib/calltip.py python3.8-3.8.7/Lib/idlelib/calltip.py
--- python3.8-3.8.6/Lib/idlelib/calltip.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/idlelib/calltip.py 2020-12-21 16:25:24.000000000 +0000
@@ -55,18 +55,50 @@
self.open_calltip(False)
def open_calltip(self, evalfuncs):
- self.remove_calltip_window()
+ """Maybe close an existing calltip and maybe open a new calltip.
+ Called from (force_open|try_open|refresh)_calltip_event functions.
+ """
hp = HyperParser(self.editwin, "insert")
sur_paren = hp.get_surrounding_brackets('(')
+
+ # If not inside parentheses, no calltip.
if not sur_paren:
+ self.remove_calltip_window()
return
+
+ # If a calltip is shown for the current parentheses, do
+ # nothing.
+ if self.active_calltip:
+ opener_line, opener_col = map(int, sur_paren[0].split('.'))
+ if (
+ (opener_line, opener_col) ==
+ (self.active_calltip.parenline, self.active_calltip.parencol)
+ ):
+ return
+
hp.set_index(sur_paren[0])
- expression = hp.get_expression()
+ try:
+ expression = hp.get_expression()
+ except ValueError:
+ expression = None
if not expression:
+ # No expression before the opening parenthesis, e.g.
+ # because it's in a string or the opener for a tuple:
+ # Do nothing.
return
+
+ # At this point, the current index is after an opening
+ # parenthesis, in a section of code, preceded by a valid
+ # expression. If there is a calltip shown, it's not for the
+ # same index and should be closed.
+ self.remove_calltip_window()
+
+ # Simple, fast heuristic: If the preceding expression includes
+ # an opening parenthesis, it likely includes a function call.
if not evalfuncs and (expression.find('(') != -1):
return
+
argspec = self.fetch_tip(expression)
if not argspec:
return
@@ -133,6 +165,7 @@
ob_call = ob.__call__
except BaseException: # Buggy user object could raise anything.
return '' # No popup for non-callables.
+ # For Get_argspecTest.test_buggy_getattr_class, CallA() & CallB().
fob = ob_call if isinstance(ob_call, types.MethodType) else ob
# Initialize argspec and wrap it to get lines.
@@ -153,10 +186,7 @@
if len(argspec) > _MAX_COLS else [argspec] if argspec else [])
# Augment lines from docstring, if any, and join to get argspec.
- if isinstance(ob_call, types.MethodType):
- doc = ob_call.__doc__
- else:
- doc = getattr(ob, "__doc__", "")
+ doc = inspect.getdoc(ob)
if doc:
for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]:
line = line.strip()
diff -Nru python3.8-3.8.6/Lib/idlelib/codecontext.py python3.8-3.8.7/Lib/idlelib/codecontext.py
--- python3.8-3.8.6/Lib/idlelib/codecontext.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/idlelib/codecontext.py 2020-12-21 16:25:24.000000000 +0000
@@ -7,11 +7,14 @@
enclosing block. The number of hint lines is determined by the maxlines
variable in the codecontext section of config-extensions.def. Lines which do
not open blocks are not shown in the context hints pane.
+
+For EditorWindows, <> is bound to CodeContext(self).
+toggle_code_context_event.
"""
import re
from sys import maxsize as INFINITY
-import tkinter
+from tkinter import Frame, Text, TclError
from tkinter.constants import NSEW, SUNKEN
from idlelib.config import idleConf
@@ -83,7 +86,7 @@
if self.t1 is not None:
try:
self.text.after_cancel(self.t1)
- except tkinter.TclError: # pragma: no cover
+ except TclError: # pragma: no cover
pass
self.t1 = None
@@ -111,7 +114,7 @@
padx += widget.tk.getint(info['padx'])
padx += widget.tk.getint(widget.cget('padx'))
border += widget.tk.getint(widget.cget('border'))
- context = self.context = tkinter.Text(
+ context = self.context = Text(
self.editwin.text_frame,
height=1,
width=1, # Don't request more than we get.
@@ -127,7 +130,7 @@
line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(),
'linenumber')
- self.cell00 = tkinter.Frame(self.editwin.text_frame,
+ self.cell00 = Frame(self.editwin.text_frame,
bg=line_number_colors['background'])
self.cell00.grid(row=0, column=0, sticky=NSEW)
menu_status = 'Hide'
@@ -221,7 +224,7 @@
"""
try:
self.context.index("sel.first")
- except tkinter.TclError:
+ except TclError:
lines = len(self.info)
if lines == 1: # No context lines are showing.
newtop = 1
diff -Nru python3.8-3.8.6/Lib/idlelib/configdialog.py python3.8-3.8.7/Lib/idlelib/configdialog.py
--- python3.8-3.8.6/Lib/idlelib/configdialog.py 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/idlelib/configdialog.py 2020-12-21 16:25:24.000000000 +0000
@@ -67,7 +67,6 @@
if not _utest:
self.withdraw()
- self.configure(borderwidth=5)
self.title(title or 'IDLE Preferences')
x = parent.winfo_rootx() + 20
y = parent.winfo_rooty() + (30 if not _htest else 150)
@@ -97,6 +96,7 @@
"""Create and place widgets for tabbed dialog.
Widgets Bound to self:
+ frame: encloses all other widgets
note: Notebook
highpage: HighPage
fontpage: FontPage
@@ -109,7 +109,9 @@
load_configs: Load pages except for extensions.
activate_config_changes: Tell editors to reload.
"""
- self.note = note = Notebook(self)
+ self.frame = frame = Frame(self, padding="5px")
+ self.frame.grid(sticky="nwes")
+ self.note = note = Notebook(frame)
self.highpage = HighPage(note)
self.fontpage = FontPage(note, self.highpage)
self.keyspage = KeysPage(note)
@@ -148,7 +150,7 @@
padding_args = {}
else:
padding_args = {'padding': (6, 3)}
- outer = Frame(self, padding=2)
+ outer = Frame(self.frame, padding=2)
buttons_frame = Frame(outer, padding=2)
self.buttons = {}
for txt, cmd in (
@@ -687,7 +689,7 @@
def __init__(self, master):
super().__init__(master)
- self.cd = master.master
+ self.cd = master.winfo_toplevel()
self.style = Style(master)
self.create_page_highlight()
self.load_theme_cfg()
@@ -1346,7 +1348,7 @@
def __init__(self, master):
super().__init__(master)
- self.cd = master.master
+ self.cd = master.winfo_toplevel()
self.create_page_keys()
self.load_key_cfg()
diff -Nru python3.8-3.8.6/Lib/idlelib/help.html python3.8-3.8.7/Lib/idlelib/help.html
--- python3.8-3.8.6/Lib/idlelib/help.html 2020-09-23 12:36:32.000000000 +0000
+++ python3.8-3.8.7/Lib/idlelib/help.html 2020-12-21 16:25:24.000000000 +0000
@@ -1,23 +1,24 @@
-
+
- IDLE — Python 3.10.0a0 documentation
+
+ IDLE — Python 3.10.0a1 documentation
-
-
-
-
-
+
+
+
+
+
-
+
@@ -71,11 +72,12 @@
Backspace deletes to the left; Del deletes to the right
-
C-Backspace delete word left; C-Del delete word to the right
-
Arrow keys and Page Up/Page Down to move around
-
C-LeftArrow and C-RightArrow moves by words
+
C-Backspace delete word left; C-Del delete word to the right
+
Arrow keys and PageUp/PageDown to move around
+
C-LeftArrow and C-RightArrow moves by words
Home/End go to begin/end of line
-
C-Home/C-End go to begin/end of file
+
C-Home/C-End go to begin/end of file
Some useful Emacs bindings are inherited from Tcl/Tk:
-
C-a beginning of line
-
C-e end of line
-
C-k kill line (but doesn’t put it in clipboard)
-
C-l center window around the insertion point
-
C-b go backward one character without deleting (usually you can
+
C-a beginning of line
+
C-e end of line
+
C-k kill line (but doesn’t put it in clipboard)
+
C-l center window around the insertion point
+
C-b go backward one character without deleting (usually you can
also use the cursor key for this)
-
C-f go forward one character without deleting (usually you can
+
C-f go forward one character without deleting (usually you can
also use the cursor key for this)
-
C-p go up one line (usually you can also use the cursor key for
+
C-p go up one line (usually you can also use the cursor key for
this)
-
C-d delete next character
+
C-d delete next character
-
Standard keybindings (like C-c to copy and C-v to paste)
+
Standard keybindings (like C-c to copy and C-v to paste)
may work. Keybindings are selected in the Configure IDLE dialog.
@@ -486,7 +488,7 @@
directory name and a separator.
Instead of waiting, or after a box is closed, open a completion box
immediately with Show Completions on the Edit menu. The default hot
-key is C-space. If one types a prefix for the desired name
+key is C-space. If one types a prefix for the desired name
before opening the box, the first match or near miss is made visible.
The result is the same as if one enters a prefix
after the box is displayed. Show Completions after a quote completes
@@ -559,14 +561,14 @@
The editing features described in previous subsections work when entering
code interactively. IDLE’s Shell window also responds to the following keys.
-
C-c interrupts executing command
-
C-d sends end-of-file; closes window if typed at a >>> prompt
-
Alt-/ (Expand word) is also useful to reduce typing
+
C-c interrupts executing command
+
C-d sends end-of-file; closes window if typed at a >>> prompt
+
Alt-/ (Expand word) is also useful to reduce typing
Command history
-
Alt-p retrieves previous command matching what you have typed. On
-macOS use C-p.
-
Alt-n retrieves next. On macOS use C-n.
+
Alt-p retrieves previous command matching what you have typed. On
+macOS use C-p.
+
Alt-n retrieves next. On macOS use C-n.
Return while on any previous command retrieves that command