From 745186fdeebd7ab7da7d49ba6533c64fa3f0ef40 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Wed, 9 Dec 2020 09:30:49 +0900 Subject: [PATCH] Imported Upstream version 3.8.3 --- Doc/Makefile | 2 +- Doc/c-api/arg.rst | 22 +- Doc/c-api/code.rst | 2 +- Doc/c-api/dict.rst | 9 +- Doc/c-api/exceptions.rst | 5 +- Doc/c-api/init.rst | 54 +- Doc/c-api/init_config.rst | 2 +- Doc/c-api/intro.rst | 33 + Doc/c-api/iter.rst | 2 +- Doc/c-api/long.rst | 2 +- Doc/c-api/mapping.rst | 3 +- Doc/c-api/memory.rst | 4 +- Doc/c-api/module.rst | 2 +- Doc/c-api/object.rst | 5 +- Doc/c-api/typeobj.rst | 14 +- Doc/copyright.rst | 2 +- Doc/data/refcounts.dat | 3 +- Doc/extending/extending.rst | 14 +- Doc/faq/design.rst | 2 + Doc/faq/programming.rst | 6 +- Doc/glossary.rst | 8 +- Doc/howto/functional.rst | 6 +- Doc/howto/pyporting.rst | 10 +- Doc/includes/custom.c | 2 +- Doc/install/index.rst | 2 +- Doc/library/ast.rst | 22 +- Doc/library/asyncio-eventloop.rst | 24 +- Doc/library/code.rst | 2 +- Doc/library/collections.rst | 4 +- Doc/library/csv.rst | 3 +- Doc/library/ctypes.rst | 15 +- Doc/library/dataclasses.rst | 9 +- Doc/library/datetime.rst | 4 +- Doc/library/decimal.rst | 81 +- Doc/library/dis.rst | 28 +- Doc/library/ensurepip.rst | 2 +- Doc/library/enum.rst | 2 +- Doc/library/fcntl.rst | 8 + Doc/library/functions.rst | 8 +- Doc/library/functools.rst | 3 +- Doc/library/gettext.rst | 4 +- Doc/library/http.client.rst | 4 +- Doc/library/idle.rst | 34 +- Doc/library/importlib.rst | 4 + Doc/library/inspect.rst | 6 + Doc/library/io.rst | 9 +- Doc/library/keyword.rst | 11 +- Doc/library/logging.rst | 1 + Doc/library/mailcap.rst | 2 +- Doc/library/msvcrt.rst | 6 + Doc/library/multiprocessing.rst | 15 +- Doc/library/nntplib.rst | 8 +- Doc/library/os.rst | 120 +- Doc/library/pathlib.rst | 6 +- Doc/library/pickle.rst | 10 +- Doc/library/platform.rst | 5 +- Doc/library/pprint.rst | 2 +- Doc/library/pty.rst | 1 + Doc/library/py_compile.rst | 2 +- Doc/library/pyclbr.rst | 9 +- Doc/library/queue.rst | 28 +- Doc/library/random.rst | 58 +- Doc/library/re.rst | 8 +- Doc/library/resource.rst | 5 + Doc/library/shutil.rst | 20 + Doc/library/signal.rst | 108 + Doc/library/site.rst | 9 +- Doc/library/socket.rst | 4 +- Doc/library/socketserver.rst | 2 + Doc/library/sqlite3.rst | 7 +- Doc/library/ssl.rst | 4 +- Doc/library/statistics.rst | 44 +- Doc/library/stdtypes.rst | 24 +- Doc/library/string.rst | 9 +- Doc/library/subprocess.rst | 10 +- Doc/library/sys.rst | 18 +- Doc/library/syslog.rst | 8 + Doc/library/textwrap.rst | 2 +- Doc/library/threading.rst | 1 + Doc/library/time.rst | 1 - Doc/library/timeit.rst | 3 +- Doc/library/token.rst | 2 +- Doc/library/tokenize.rst | 21 +- Doc/library/tracemalloc.rst | 4 +- Doc/library/turtle.rst | 5 + Doc/library/types.rst | 8 +- Doc/library/typing.rst | 18 +- Doc/library/unittest.mock.rst | 1 + Doc/library/unittest.rst | 6 +- Doc/library/weakref.rst | 6 - Doc/library/zipapp.rst | 2 +- Doc/library/zipfile.rst | 6 + Doc/license.rst | 2 +- Doc/make.bat | 6 +- Doc/reference/compound_stmts.rst | 73 +- Doc/reference/datamodel.rst | 23 +- Doc/reference/expressions.rst | 25 +- Doc/reference/import.rst | 2 +- Doc/reference/lexical_analysis.rst | 15 +- Doc/tools/templates/download.html | 2 +- Doc/tools/templates/indexsidebar.html | 2 +- Doc/tutorial/classes.rst | 10 +- Doc/tutorial/controlflow.rst | 2 +- Doc/tutorial/datastructures.rst | 7 +- Doc/tutorial/errors.rst | 36 +- Doc/using/cmdline.rst | 6 +- Doc/using/venv-create.inc | 11 + Doc/using/windows.rst | 44 + Doc/whatsnew/3.0.rst | 2 + Doc/whatsnew/3.7.rst | 5 + Doc/whatsnew/3.8.rst | 42 +- Include/code.h | 26 +- Include/compile.h | 6 + Include/cpython/pystate.h | 1 + Include/object.h | 2 +- Include/patchlevel.h | 4 +- LICENSE | 2 +- Lib/__future__.py | 16 +- Lib/_osx_support.py | 39 +- Lib/_pydecimal.py | 8 +- Lib/argparse.py | 56 +- Lib/ast.py | 15 +- Lib/asyncio/base_events.py | 10 +- Lib/asyncio/base_tasks.py | 13 +- Lib/asyncio/staggered.py | 4 +- Lib/asyncio/unix_events.py | 9 +- Lib/base64.py | 2 +- Lib/bdb.py | 9 +- Lib/code.py | 2 +- Lib/codecs.py | 15 +- Lib/collections/__init__.py | 7 + Lib/compileall.py | 29 +- Lib/copy.py | 3 +- Lib/ctypes/test/test_loading.py | 7 +- Lib/ctypes/test/test_structures.py | 3 +- Lib/distutils/_msvccompiler.py | 60 +- Lib/distutils/command/build_ext.py | 10 +- Lib/distutils/tests/test_build_ext.py | 13 + Lib/distutils/tests/test_config_cmd.py | 3 +- Lib/distutils/tests/test_msvccompiler.py | 51 - Lib/distutils/unixccompiler.py | 2 +- Lib/doctest.py | 9 +- Lib/encodings/punycode.py | 2 +- Lib/ensurepip/__init__.py | 16 +- Lib/fractions.py | 4 +- Lib/functools.py | 3 +- Lib/glob.py | 2 +- Lib/gzip.py | 12 +- Lib/http/client.py | 10 + Lib/http/server.py | 18 +- Lib/idlelib/Icons/README.txt | 9 + Lib/idlelib/Icons/idle.icns | Bin 57435 -> 0 bytes Lib/idlelib/Icons/idle_256.png | Bin 0 -> 42839 bytes Lib/idlelib/NEWS.txt | 34 +- Lib/idlelib/README.txt | 2 +- Lib/idlelib/autocomplete_w.py | 2 +- Lib/idlelib/calltip.py | 22 +- Lib/idlelib/codecontext.py | 44 +- Lib/idlelib/config_key.py | 2 +- Lib/idlelib/configdialog.py | 28 +- Lib/idlelib/editor.py | 77 +- Lib/idlelib/help.html | 46 +- Lib/idlelib/idle_test/test_calltip.py | 24 +- Lib/idlelib/idle_test/test_codecontext.py | 8 + Lib/idlelib/idle_test/test_configdialog.py | 154 +- Lib/idlelib/idle_test/test_editor.py | 99 + Lib/idlelib/idle_test/test_pyparse.py | 43 +- Lib/idlelib/idle_test/test_query.py | 43 + Lib/idlelib/idle_test/test_sidebar.py | 1 - Lib/idlelib/idle_test/test_squeezer.py | 1 - Lib/idlelib/pyparse.py | 7 +- Lib/idlelib/pyshell.py | 35 +- Lib/idlelib/query.py | 23 +- Lib/idlelib/textview.py | 1 - Lib/importlib/metadata.py | 110 +- Lib/inspect.py | 2 +- Lib/json/tool.py | 5 +- Lib/lib2to3/Grammar.txt | 10 +- Lib/lib2to3/fixes/fix_filter.py | 10 +- Lib/lib2to3/pgen2/grammar.py | 1 + Lib/lib2to3/pgen2/token.py | 3 +- Lib/lib2to3/pgen2/tokenize.py | 2 +- Lib/lib2to3/tests/test_fixers.py | 5 + Lib/lib2to3/tests/test_parser.py | 15 + Lib/logging/__init__.py | 15 +- Lib/logging/config.py | 2 +- Lib/mimetypes.py | 6 +- Lib/modulefinder.py | 19 +- Lib/multiprocessing/connection.py | 5 +- Lib/multiprocessing/forkserver.py | 6 +- Lib/multiprocessing/managers.py | 10 +- Lib/multiprocessing/pool.py | 7 +- Lib/multiprocessing/shared_memory.py | 10 +- Lib/multiprocessing/spawn.py | 2 +- Lib/multiprocessing/util.py | 23 + Lib/nntplib.py | 2 +- Lib/os.py | 6 +- Lib/pathlib.py | 39 +- Lib/pickle.py | 6 +- Lib/platform.py | 6 +- Lib/pty.py | 2 + Lib/pydoc.py | 5 +- Lib/pydoc_data/topics.py | 288 +- Lib/re.py | 6 +- Lib/runpy.py | 6 +- Lib/shutil.py | 12 +- Lib/socket.py | 2 +- Lib/sqlite3/test/regression.py | 2 +- Lib/sqlite3/test/types.py | 6 +- Lib/subprocess.py | 4 +- Lib/symtable.py | 2 +- Lib/tarfile.py | 18 +- Lib/tempfile.py | 2 +- Lib/test/_test_multiprocessing.py | 83 +- Lib/test/audit-tests.py | 22 + Lib/test/clinic.test | 105 + Lib/test/libregrtest/cmdline.py | 16 +- Lib/test/libregrtest/main.py | 7 +- Lib/test/libregrtest/runtest.py | 4 +- Lib/test/libregrtest/runtest_mp.py | 42 +- Lib/test/libregrtest/utils.py | 3 +- Lib/test/pickletester.py | 49 +- Lib/test/pythoninfo.py | 3 + Lib/test/sortperf.py | 2 +- Lib/test/support/__init__.py | 71 +- Lib/test/test__osx_support.py | 51 + Lib/test/test__xxsubinterpreters.py | 6 +- Lib/test/test_argparse.py | 37 + Lib/test/test_ast.py | 41 + Lib/test/test_asyncgen.py | 77 + Lib/test/test_asyncio/test_context.py | 1 + Lib/test/test_asyncio/test_events.py | 8 +- Lib/test/test_audit.py | 12 + Lib/test/test_base64.py | 1 + Lib/test/test_buffer.py | 6 + Lib/test/test_builtin.py | 64 +- Lib/test/test_capi.py | 14 + Lib/test/test_cmd_line.py | 11 + Lib/test/test_codecs.py | 21 + Lib/test/test_compileall.py | 41 + Lib/test/test_concurrent_futures.py | 14 +- Lib/test/test_copy.py | 4 +- Lib/test/test_crypt.py | 9 +- Lib/test/test_dataclasses.py | 19 + Lib/test/test_decimal.py | 35 + Lib/test/test_deque.py | 12 + Lib/test/test_dict.py | 12 +- Lib/test/test_doctest.py | 93 +- Lib/test/test_email/test_email.py | 10 +- Lib/test/test_eof.py | 2 +- Lib/test/test_exceptions.py | 14 +- Lib/test/test_fractions.py | 37 + Lib/test/test_future.py | 22 + Lib/test/test_gdb.py | 19 +- Lib/test/test_gzip.py | 20 + Lib/test/test_heapq.py | 31 + Lib/test/test_httplib.py | 13 +- Lib/test/test_importlib/fixtures.py | 23 +- Lib/test/test_importlib/stubs.py | 10 + Lib/test/test_importlib/test_main.py | 32 + Lib/test/test_importlib/util.py | 11 + Lib/test/test_io.py | 5 + Lib/test/test_isinstance.py | 21 + Lib/test/test_json/test_tool.py | 11 + Lib/test/test_list.py | 58 + Lib/test/test_logging.py | 31 + Lib/test/test_math.py | 274 +- Lib/test/test_mimetypes.py | 84 +- Lib/test/test_modulefinder.py | 82 +- Lib/test/test_named_expressions.py | 4 +- Lib/test/test_nntplib.py | 4 +- Lib/test/test_ordered_dict.py | 20 + Lib/test/test_os.py | 43 +- Lib/test/test_pathlib.py | 58 +- Lib/test/test_positional_only_arg.py | 19 + Lib/test/test_pty.py | 6 +- Lib/test/test_pwd.py | 2 +- Lib/test/test_regrtest.py | 54 + Lib/test/test_repl.py | 36 + Lib/test/test_runpy.py | 9 + Lib/test/test_shutil.py | 42 + Lib/test/test_site.py | 19 + Lib/test/test_socket.py | 2 + Lib/test/test_subprocess.py | 12 +- Lib/test/test_support.py | 90 +- Lib/test/test_symtable.py | 6 +- Lib/test/test_syntax.py | 2 +- Lib/test/test_tempfile.py | 6 +- Lib/test/test_tools/test_unparse.py | 14 + Lib/test/test_typing.py | 16 +- Lib/test/test_urllib.py | 58 +- Lib/test/test_urllib2.py | 90 +- Lib/test/test_urlparse.py | 10 +- Lib/test/test_venv.py | 12 + Lib/test/test_warnings/__init__.py | 23 + Lib/test/test_xml_etree_c.py | 15 + Lib/test/test_zipfile.py | 167 +- Lib/test/test_zipimport.py | 16 + Lib/threading.py | 10 +- Lib/timeit.py | 3 +- Lib/tkinter/test/widget_tests.py | 13 +- Lib/tkinter/tix.py | 4 +- Lib/tkinter/ttk.py | 5 +- Lib/trace.py | 6 +- Lib/traceback.py | 2 +- Lib/turtledemo/__main__.py | 2 +- Lib/typing.py | 23 +- Lib/unittest/case.py | 2 +- Lib/unittest/mock.py | 84 +- Lib/unittest/test/test_case.py | 9 + Lib/unittest/test/testmock/testasync.py | 87 +- Lib/unittest/test/testmock/testmock.py | 29 + Lib/urllib/parse.py | 26 +- Lib/urllib/request.py | 99 +- Lib/venv/scripts/common/Activate.ps1 | 20 +- Lib/warnings.py | 30 +- Lib/webbrowser.py | 18 +- Lib/zipfile.py | 126 +- Lib/zipimport.py | 2 +- Mac/BuildScript/build-installer.py | 12 +- Mac/BuildScript/resources/License.rtf | 6 +- Mac/BuildScript/resources/ReadMe.rtf | 16 +- Mac/IDLE/IDLE.app/Contents/Info.plist | 2 +- Mac/PythonLauncher/Info.plist.in | 2 +- Mac/README.rst | 2 +- Mac/Resources/app/Info.plist.in | 2 +- Mac/Tools/pythonw.c | 9 + Makefile.pre.in | 3 + Misc/ACKS | 29 +- Misc/NEWS | 722 ++- Misc/gdbinit | 2 +- Misc/python.man | 40 +- Misc/valgrind-python.supp | 8 + Modules/_asynciomodule.c | 6 + Modules/_collectionsmodule.c | 4 + Modules/_ctypes/_ctypes.c | 20 + Modules/_ctypes/callproc.c | 5 +- Modules/_decimal/_decimal.c | 171 +- Modules/_decimal/libmpdec/mpdecimal.c | 77 +- Modules/_decimal/tests/deccheck.py | 139 +- Modules/_decimal/tests/runall-memorydebugger.sh | 40 +- Modules/_decimal/tests/runall.bat | 100 +- Modules/_elementtree.c | 67 +- Modules/_heapqmodule.c | 35 +- Modules/_io/bufferedio.c | 1 + Modules/_io/textio.c | 4 +- Modules/_pickle.c | 83 +- Modules/_sqlite/cursor.c | 29 +- Modules/_ssl_data.h | 6563 +++++++++++++++++++---- Modules/_struct.c | 3 + Modules/_testcapimodule.c | 56 + Modules/_xxsubinterpretersmodule.c | 6 +- Modules/clinic/_pickle.c.h | 15 +- Modules/clinic/posixmodule.c.h | 6 +- Modules/fcntlmodule.c | 18 + Modules/mathmodule.c | 6 +- Modules/md5module.c | 4 +- Modules/ossaudiodev.c | 6 +- Modules/posixmodule.c | 208 +- Modules/resource.c | 10 + Modules/signalmodule.c | 4 + Modules/socketmodule.c | 7 +- Modules/syslogmodule.c | 14 + Objects/abstract.c | 27 +- Objects/bytes_methods.c | 16 +- Objects/clinic/codeobject.c.h | 4 +- Objects/codeobject.c | 4 +- Objects/complexobject.c | 20 - Objects/descrobject.c | 3 +- Objects/dictobject.c | 2 + Objects/floatobject.c | 37 - Objects/genobject.c | 33 +- Objects/listobject.c | 39 +- Objects/listsort.txt | 16 +- Objects/longobject.c | 11 - Objects/memoryobject.c | 20 +- Objects/methodobject.c | 3 +- Objects/object.c | 5 +- Objects/obmalloc.c | 14 +- Objects/odictobject.c | 2 - Objects/stringlib/asciilib.h | 2 +- Objects/stringlib/codecs.h | 4 +- Objects/stringlib/find_max_char.h | 2 +- Objects/tupleobject.c | 4 +- Objects/unicodeobject.c | 28 +- PC/getpathp.c | 6 +- PC/icons/logo.svg | 1 + PC/icons/logox128.png | Bin 0 -> 1203 bytes PC/layout/main.py | 4 + PC/layout/support/nuspec.py | 10 +- PC/layout/support/props.py | 3 +- PC/msvcrtmodule.c | 12 + PC/pyconfig.h | 4 + PCbuild/build.bat | 4 + PCbuild/find_msbuild.bat | 9 +- PCbuild/get_externals.bat | 6 +- PCbuild/lib.pyproj | 1 + PCbuild/pyproject.props | 39 + PCbuild/python.props | 6 +- PCbuild/python_uwp.vcxproj | 1 + PCbuild/pythoncore.vcxproj | 12 +- PCbuild/pythonw_uwp.vcxproj | 1 + PCbuild/readme.txt | 2 +- Parser/parsetok.c | 1 + Parser/tokenizer.c | 38 +- Python/_warnings.c | 7 +- Python/ast.c | 59 +- Python/ast_opt.c | 1 + Python/ast_unparse.c | 1 + Python/bltinmodule.c | 2 +- Python/ceval.c | 30 +- Python/codecs.c | 2 +- Python/compile.c | 21 +- Python/errors.c | 2 +- Python/getcopyright.c | 2 +- Python/getopt.c | 23 +- Python/hamt.c | 2 +- Python/import.c | 15 +- Python/importlib_zipimport.h | 540 +- Python/initconfig.c | 44 +- Python/marshal.c | 2 +- Python/modsupport.c | 6 +- Python/pathconfig.c | 2 +- Python/pyhash.c | 16 +- Python/pylifecycle.c | 2 +- Python/pystate.c | 15 +- Python/symtable.c | 2 + Python/sysmodule.c | 61 +- Python/thread_nt.h | 6 +- README.rst | 6 +- Tools/clinic/cpp.py | 37 +- Tools/gdb/libpython.py | 18 +- Tools/msi/exe/exe.wixproj | 3 + Tools/msi/exe/exe_files.wxs | 7 +- Tools/nuget/make_pkg.proj | 2 +- Tools/parser/unparse.py | 19 +- Tools/ssl/make_ssl_data.py | 33 +- Tools/ssl/multissltests.py | 2 +- aclocal.m4 | 4 +- configure | 50 +- configure.ac | 21 + m4/ax_c_float_words_bigendian.m4 | 4 +- pyconfig.h.in | 4 + setup.py | 2 +- 444 files changed, 13233 insertions(+), 3468 deletions(-) create mode 100644 Lib/idlelib/Icons/README.txt delete mode 100644 Lib/idlelib/Icons/idle.icns create mode 100644 Lib/idlelib/Icons/idle_256.png create mode 100644 Lib/test/test_importlib/stubs.py create mode 100644 PC/icons/logo.svg create mode 100644 PC/icons/logox128.png diff --git a/Doc/Makefile b/Doc/Makefile index f589b6e..2169f1a 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -143,7 +143,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) $(VENVDIR)/bin/python3 -m pip install -U pip setuptools - $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb python-docs-theme + $(VENVDIR)/bin/python3 -m pip install -U Sphinx==1.8.2 blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" dist: diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index f17c63d..b7baad5 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -105,7 +105,7 @@ which disallows mutable objects such as :class:`bytearray`. Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``. -``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to ``NULL``. @@ -124,7 +124,7 @@ which disallows mutable objects such as :class:`bytearray`. bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (read-only :term:`bytes-like object`) [const char \*, int] +``y#`` (read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. @@ -155,7 +155,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``u#`` (:class:`str`) [const Py_UNICODE \*, int] +``u#`` (:class:`str`) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. This variant allows null code points. @@ -172,7 +172,7 @@ which disallows mutable objects such as :class:`bytearray`. Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using :c:func:`PyUnicode_AsWideCharString`. -``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, int or :c:type:`Py_ssize_t`] Like ``u#``, but the Python object may also be ``None``, in which case the :c:type:`Py_UNICODE` pointer is set to ``NULL``. @@ -213,7 +213,7 @@ which disallows mutable objects such as :class:`bytearray`. recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] This variant on ``s#`` is used for encoding Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -244,7 +244,7 @@ which disallows mutable objects such as :class:`bytearray`. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int or :c:type:`Py_ssize_t` \*buffer_length] Same as ``es#`` except that byte string objects are passed through without recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. @@ -549,7 +549,7 @@ Building values Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, ``None`` is used. - ``s#`` (:class:`str` or ``None``) [const char \*, int] + ``s#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -558,14 +558,14 @@ Building values This converts a C string to a Python :class:`bytes` object. If the C string pointer is ``NULL``, ``None`` is returned. - ``y#`` (:class:`bytes`) [const char \*, int] + ``y#`` (:class:`bytes`) [const char \*, int or :c:type:`Py_ssize_t`] This converts a C string and its lengths to a Python object. If the C string pointer is ``NULL``, ``None`` is returned. ``z`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``z#`` (:class:`str` or ``None``) [const char \*, int] + ``z#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] @@ -573,7 +573,7 @@ Building values data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. - ``u#`` (:class:`str`) [const wchar_t \*, int] + ``u#`` (:class:`str`) [const wchar_t \*, int or :c:type:`Py_ssize_t`] Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, the length is ignored and ``None`` is returned. @@ -581,7 +581,7 @@ Building values ``U`` (:class:`str` or ``None``) [const char \*] Same as ``s``. - ``U#`` (:class:`str` or ``None``) [const char \*, int] + ``U#`` (:class:`str` or ``None``) [const char \*, int or :c:type:`Py_ssize_t`] Same as ``s#``. ``i`` (:class:`int`) [int] diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 45a6b4a..6f8c41c 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -42,7 +42,7 @@ bound into a function. .. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab) - Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positonal-only arguments. + Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positional-only arguments. .. versionadded:: 3.8 diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index e7922dc..e48c11d 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -62,19 +62,20 @@ Dictionary Objects .. c:function:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) - Insert *value* into the dictionary *p* with a key of *key*. *key* must be + Insert *val* into the dictionary *p* with a key of *key*. *key* must be :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return - ``0`` on success or ``-1`` on failure. + ``0`` on success or ``-1`` on failure. This function *does not* steal a + reference to *val*. .. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) .. index:: single: PyUnicode_FromString() - Insert *value* into the dictionary *p* using *key* as a key. *key* should + Insert *val* into the dictionary *p* using *key* as a key. *key* should be a :c:type:`const char\*`. The key object is created using ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on - failure. + failure. This function *does not* steal a reference to *val*. .. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c7ba74c..85a3d94 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -358,7 +358,7 @@ an error value). .. c:function:: int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...) Function similar to :c:func:`PyErr_WarnFormat`, but *category* is - :exc:`ResourceWarning` and pass *source* to :func:`warnings.WarningMessage`. + :exc:`ResourceWarning` and it passes *source* to :func:`warnings.WarningMessage`. .. versionadded:: 3.6 @@ -971,9 +971,6 @@ Notes: This is a base class for other standard exceptions. (2) - This is the same as :exc:`weakref.ReferenceError`. - -(3) Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 155edba..68d892d 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1181,7 +1181,7 @@ It is usually the only Python interpreter in a process. Unlike sub-interpreters the main interpreter has unique process-global responsibilities like signal handling. It is also responsible for execution during runtime initialization and is usually the active interpreter during runtime finalization. The -:c:func:`PyInterpreterState_Main` funtion returns a pointer to its state. +:c:func:`PyInterpreterState_Main` function returns a pointer to its state. You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap` function. You can create and destroy them using the following functions: @@ -1222,15 +1222,31 @@ function. You can create and destroy them using the following functions: single: Py_FinalizeEx() single: Py_Initialize() - Extension modules are shared between (sub-)interpreters as follows: the first - time a particular extension is imported, it is initialized normally, and a - (shallow) copy of its module's dictionary is squirreled away. When the same - extension is imported by another (sub-)interpreter, a new module is initialized - and filled with the contents of this copy; the extension's ``init`` function is - not called. Note that this is different from what happens when an extension is - imported after the interpreter has been completely re-initialized by calling - :c:func:`Py_FinalizeEx` and :c:func:`Py_Initialize`; in that case, the extension's - ``initmodule`` function *is* called again. + Extension modules are shared between (sub-)interpreters as follows: + + * For modules using multi-phase initialization, + e.g. :c:func:`PyModule_FromDefAndSpec`, a separate module object is + created and initialized for each interpreter. + Only C-level static and global variables are shared between these + module objects. + + * For modules using single-phase initialization, + e.g. :c:func:`PyModule_Create`, the first time a particular extension + is imported, it is initialized normally, and a (shallow) copy of its + module's dictionary is squirreled away. + When the same extension is imported by another (sub-)interpreter, a new + module is initialized and filled with the contents of this copy; the + extension's ``init`` function is not called. + Objects in the module's dictionary thus end up shared across + (sub-)interpreters, which might cause unwanted behavior (see + `Bugs and caveats`_ below). + + Note that this is different from what happens when an extension is + imported after the interpreter has been completely re-initialized by + calling :c:func:`Py_FinalizeEx` and :c:func:`Py_Initialize`; in that + case, the extension's ``initmodule`` function *is* called again. + As with multi-phase initialization, this means that only C-level static + and global variables are shared between these modules. .. index:: single: close() (in module os) @@ -1256,14 +1272,16 @@ process, the insulation between them isn't perfect --- for example, using low-level file operations like :func:`os.close` they can (accidentally or maliciously) affect each other's open files. Because of the way extensions are shared between (sub-)interpreters, some extensions may not -work properly; this is especially likely when the extension makes use of -(static) global variables, or when the extension manipulates its module's -dictionary after its initialization. It is possible to insert objects created -in one sub-interpreter into a namespace of another sub-interpreter; this should -be done with great care to avoid sharing user-defined functions, methods, -instances or classes between sub-interpreters, since import operations executed -by such objects may affect the wrong (sub-)interpreter's dictionary of loaded -modules. +work properly; this is especially likely when using single-phase initialization +or (static) global variables. +It is possible to insert objects created in one sub-interpreter into +a namespace of another (sub-)interpreter; this should be avoided if possible. + +Special care should be taken to avoid sharing user-defined functions, +methods, instances or classes between sub-interpreters, since import +operations executed by such objects may affect the wrong (sub-)interpreter's +dictionary of loaded modules. It is equally important to avoid sharing +objects from which the above are reachable. Also note that combining this functionality with :c:func:`PyGILState_\*` APIs is delicate, because these APIs assume a bijection between Python thread states diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 6b16b5b..79a8815 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -757,7 +757,7 @@ configuration, and then override some parameters:: PyConfig config; PyConfig_InitPythonConfig(&config); - /* Set the program name before reading the configuraton + /* Set the program name before reading the configuration (decode byte string from the locale encoding). Implicitly preinitialize Python. */ diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index d08d4f9..718f40e 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -174,6 +174,39 @@ complete listing. .. versionchanged:: 3.8 MSVC support was added. +.. c:macro:: PyDoc_STRVAR(name, str) + + Creates a variable with name ``name`` that can be used in docstrings. + If Python is built without docstrings, the value will be empty. + + Use :c:macro:`PyDoc_STRVAR` for docstrings to support building + Python without docstrings, as specified in :pep:`7`. + + Example:: + + PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element."); + + static PyMethodDef deque_methods[] = { + // ... + {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc}, + // ... + } + +.. c:macro:: PyDoc_STR(str) + + Creates a docstring for the given input string or an empty string + if docstrings are disabled. + + Use :c:macro:`PyDoc_STR` in specifying docstrings to support + building Python without docstrings, as specified in :pep:`7`. + + Example:: + + static PyMethodDef pysqlite_row_methods[] = { + {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, + PyDoc_STR("Returns the keys of the row.")}, + {NULL, NULL} + }; .. _api-objects: diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 0224d37..a2992b3 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -29,7 +29,7 @@ something like this:: /* propagate error */ } - while (item = PyIter_Next(iterator)) { + while ((item = PyIter_Next(iterator))) { /* do something with item */ ... /* release reference when done */ diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 33f6b3b..f41d419 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -179,7 +179,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. :c:type:`PyLongObject`. Raise :exc:`OverflowError` if the value of *obj* is out of range for a - :c:type:`long`. + :c:type:`long long`. Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 6a80b03..682160d 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -37,7 +37,8 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Map the string *key* to the value *v* in object *o*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``o[key] = v``. - See also :c:func:`PyObject_SetItem`. + See also :c:func:`PyObject_SetItem`. This function *does not* steal a + reference to *v*. .. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index ba7bd3b..8a8542f 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -533,7 +533,7 @@ tracemalloc C API .. versionadded:: 3.7 -.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) +.. c:function:: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size) Track an allocated memory block in the :mod:`tracemalloc` module. @@ -542,7 +542,7 @@ tracemalloc C API If memory block is already tracked, update the existing trace. -.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +.. c:function:: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) Untrack an allocated memory block in the :mod:`tracemalloc` module. Do nothing if the block was not tracked. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 57902a9..d2b8f4c 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -153,7 +153,7 @@ or request "multi-phase initialization" by returning the definition struct itsel .. c:member:: const char *m_doc Docstring for the module; usually a docstring variable created with - :c:func:`PyDoc_STRVAR` is used. + :c:macro:`PyDoc_STRVAR` is used. .. c:member:: Py_ssize_t m_size diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 404a98f..3bdc0f5 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -128,7 +128,7 @@ Object Protocol .. versionadded:: 3.3 -.. c:function:: int PyObject_GenericSetDict(PyObject *o, void *context) +.. c:function:: int PyObject_GenericSetDict(PyObject *o, PyObject *value, void *context) A generic implementation for the setter of a ``__dict__`` descriptor. This implementation does not allow the dictionary to be deleted. @@ -503,7 +503,8 @@ Object Protocol Map the object *key* to the value *v*. Raise an exception and return ``-1`` on failure; return ``0`` on success. This is the - equivalent of the Python statement ``o[key] = v``. + equivalent of the Python statement ``o[key] = v``. This function *does + not* steal a reference to *v*. .. c:function:: int PyObject_DelItem(PyObject *o, PyObject *key) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index bff5abf..163f599 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1218,7 +1218,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The :c:member:`~PyTypeObject.tp_traverse` pointer is used by the garbage collector to detect reference cycles. A typical implementation of a :c:member:`~PyTypeObject.tp_traverse` function simply calls :c:func:`Py_VISIT` on each of the instance's members that are Python - objects. For example, this is function :c:func:`local_traverse` from the + objects that the instance owns. For example, this is function :c:func:`local_traverse` from the :mod:`_thread` extension module:: static int @@ -1238,6 +1238,18 @@ and :c:type:`PyType_Type` effectively act as defaults.) debugging aid you may want to visit it anyway just so the :mod:`gc` module's :func:`~gc.get_referents` function will include it. + .. warning:: + When implementing :c:member:`~PyTypeObject.tp_traverse`, only the members + that the instance *owns* (by having strong references to them) must be + visited. For instance, if an object supports weak references via the + :c:member:`~PyTypeObject.tp_weaklist` slot, the pointer supporting + the linked list (what *tp_weaklist* points to) must **not** be + visited as the instance does not directly own the weak references to itself + (the weakreference list is there to support the weak reference machinery, + but the instance has no strong reference to the elements inside it, as they + are allowed to be removed even if the instance is still alive). + + Note that :c:func:`Py_VISIT` requires the *visit* and *arg* parameters to :c:func:`local_traverse` to have these specific names; don't name them just anything. diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 393a1f0..1b90d9f 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright © 2001-2019 Python Software Foundation. All rights reserved. +Copyright © 2001-2020 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index cfed1bd..3ccc20b 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1673,7 +1673,8 @@ PyObject_GenericSetAttr:PyObject*:name:0: PyObject_GenericSetAttr:PyObject*:value:+1: PyObject_GenericSetDict:int::: -PyObject_GenericSetDict:PyObject*:o:+1: +PyObject_GenericSetDict:PyObject*:o:0: +PyObject_GenericSetDict:PyObject*:value:+1: PyObject_GenericSetDict:void*:context:: PyObject_GetAttr:PyObject*::+1: diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 5b32a2c..25dc293 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -395,18 +395,26 @@ optionally followed by an import of the module:: } /* Add a built-in module, before Py_Initialize */ - PyImport_AppendInittab("spam", PyInit_spam); + if (PyImport_AppendInittab("spam", PyInit_spam) == -1) { + fprintf(stderr, "Error: could not extend in-built modules table\n"); + exit(1); + } /* Pass argv[0] to the Python interpreter */ Py_SetProgramName(program); - /* Initialize the Python interpreter. Required. */ + /* Initialize the Python interpreter. Required. + If this step fails, it will be a fatal error. */ Py_Initialize(); /* Optionally import the module; alternatively, import can be deferred until the embedded script imports it. */ - PyImport_ImportModule("spam"); + pmodule = PyImport_ImportModule("spam"); + if (!pmodule) { + PyErr_Print(); + fprintf(stderr, "Error: could not import module 'spam'\n"); + } ... diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 81c0f47..e7921ba 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -146,6 +146,8 @@ variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use. +.. _why-can-t-i-use-an-assignment-in-an-expression: + Why can't I use an assignment in an expression? ----------------------------------------------- diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 9d45765..6cc1b52 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1019,7 +1019,7 @@ That's a tough one, in general. First, here are a list of things to remember before diving further: * Performance characteristics vary across Python implementations. This FAQ - focusses on :term:`CPython`. + focuses on :term:`CPython`. * Behaviour can vary across operating systems, especially when talking about I/O or multi-threading. * You should always find the hot spots in your program *before* attempting to @@ -1494,8 +1494,8 @@ to uppercase:: Here the ``UpperOut`` class redefines the ``write()`` method to convert the argument string to uppercase before calling the underlying -``self.__outfile.write()`` method. All other methods are delegated to the -underlying ``self.__outfile`` object. The delegation is accomplished via the +``self._outfile.write()`` method. All other methods are delegated to the +underlying ``self._outfile`` object. The delegation is accomplished via the ``__getattr__`` method; consult :ref:`the language reference ` for more information about controlling attribute access. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 9ce0357..6189cb0 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -824,9 +824,11 @@ Glossary .. _positional-only_parameter: * :dfn:`positional-only`: specifies an argument that can be supplied only - by position. Python has no syntax for defining positional-only - parameters. However, some built-in functions have positional-only - parameters (e.g. :func:`abs`). + by position. Positional-only parameters can be defined by including a + ``/`` character in the parameter list of the function definition after + them, for example *posonly1* and *posonly2* in the following:: + + def func(posonly1, posonly2, /, positional_or_keyword): ... .. _keyword-only_parameter: diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index f8f2aac..74e8614 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1229,9 +1229,9 @@ Text Processing". Mertz also wrote a 3-part series of articles on functional programming for IBM's DeveloperWorks site; see -`part 1 `__, -`part 2 `__, and -`part 3 `__, +`part 1 `__, +`part 2 `__, and +`part 3 `__, Python documentation diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index 3be6bb3..8608162 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -119,7 +119,7 @@ Once you have your code well-tested you are ready to begin porting your code to Python 3! But to fully understand how your code is going to change and what you want to look out for while you code, you will want to learn what changes Python 3 makes in terms of Python 2. Typically the two best ways of doing that -is reading the `"What's New"`_ doc for each release of Python 3 and the +is reading the :ref:`"What's New" ` doc for each release of Python 3 and the `Porting to Python 3`_ book (which is free online). There is also a handy `cheat sheet`_ from the Python-Future project. @@ -302,10 +302,10 @@ If for some reason that doesn't work then you should make the version check be against Python 2 and not Python 3. To help explain this, let's look at an example. -Let's pretend that you need access to a feature of importlib_ that +Let's pretend that you need access to a feature of :mod:`importlib` that is available in Python's standard library since Python 3.3 and available for Python 2 through importlib2_ on PyPI. You might be tempted to write code to -access e.g. the ``importlib.abc`` module by doing the following:: +access e.g. the :mod:`importlib.abc` module by doing the following:: import sys @@ -426,12 +426,10 @@ can also explicitly state whether your APIs use textual or binary data, helping to make sure everything functions as expected in both versions of Python. -.. _2to3: https://docs.python.org/3/library/2to3.html .. _caniusepython3: https://pypi.org/project/caniusepython3 .. _cheat sheet: http://python-future.org/compatible_idioms.html .. _coverage.py: https://pypi.org/project/coverage .. _Futurize: http://python-future.org/automatic_conversion.html -.. _importlib: https://docs.python.org/3/library/importlib.html#module-importlib .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ .. _mypy: http://mypy-lang.org/ @@ -447,6 +445,4 @@ to make sure everything functions as expected in both versions of Python. .. _tox: https://pypi.org/project/tox .. _trove classifier: https://pypi.org/classifiers -.. _"What's New": https://docs.python.org/3/whatsnew/index.html - .. _Why Python 3 exists: https://snarky.ca/why-python-3-exists diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c index bda32e2..f361baf 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/custom.c @@ -37,7 +37,7 @@ PyInit_custom(void) Py_INCREF(&CustomType); if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(&CustomType); - PY_DECREF(m); + Py_DECREF(m); return NULL; } diff --git a/Doc/install/index.rst b/Doc/install/index.rst index a91606c..e6d5a3e 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -532,7 +532,7 @@ scripts will wind up in :file:`/usr/local/python/bin`. If you want them in python setup.py install --install-scripts=/usr/local/bin -(This performs an installation using the "prefix scheme," where the prefix is +(This performs an installation using the "prefix scheme", where the prefix is whatever your Python interpreter was installed with--- :file:`/usr/local/python` in this case.) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 92bf891..6ca2760 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -101,12 +101,16 @@ Node classes node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0) +.. versionchanged:: 3.8 + + Class :class:`ast.Constant` is now used for all constants. + .. deprecated:: 3.8 - Class :class:`ast.Constant` is now used for all constants. Old classes - :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, + Old classes :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`, :class:`ast.NameConstant` and :class:`ast.Ellipsis` are still available, - but they will be removed in future Python releases. + but they will be removed in future Python releases. In the meanwhile, + instantiating them will return an instance of a different class. .. _abstract-grammar: @@ -300,11 +304,11 @@ and classes for traversing abstract syntax trees: class RewriteName(NodeTransformer): def visit_Name(self, node): - return copy_location(Subscript( + return Subscript( value=Name(id='data', ctx=Load()), slice=Index(value=Constant(value=node.id)), ctx=node.ctx - ), node) + ) Keep in mind that if the node you're operating on has child nodes you must either transform the child nodes yourself or call the :meth:`generic_visit` @@ -314,6 +318,14 @@ and classes for traversing abstract syntax trees: statement nodes), the visitor may also return a list of nodes rather than just a single node. + If :class:`NodeTransformer` introduces new nodes (that weren't part of + original tree) without giving them location information (such as + :attr:`lineno`), :func:`fix_missing_locations` should be called with + the new sub-tree to recalculate the location information:: + + tree = ast.parse('foo', mode='eval') + new_tree = fix_missing_locations(RewriteName().visit(tree)) + Usually you use the transformer like this:: node = YourTransformer().visit(node) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index ecd69fd..9022993 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -38,8 +38,10 @@ an event loop: .. function:: get_event_loop() - Get the current event loop. If there is no current event loop set - in the current OS thread and :func:`set_event_loop` has not yet + Get the current event loop. + + If there is no current event loop set in the current OS thread, + the OS thread is main, and :func:`set_event_loop` has not yet been called, asyncio will create a new event loop and set it as the current one. @@ -345,7 +347,8 @@ Opening network connections host=None, port=None, \*, ssl=None, \ family=0, proto=0, flags=0, sock=None, \ local_addr=None, server_hostname=None, \ - ssl_handshake_timeout=None) + ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Open a streaming transport connection to a given address specified by *host* and *port*. @@ -434,7 +437,18 @@ Opening network connections .. versionadded:: 3.8 - The *happy_eyeballs_delay* and *interleave* parameters. + Added the *happy_eyeballs_delay* and *interleave* parameters. + + Happy Eyeballs Algorithm: Success with Dual-Stack Hosts. + When a server's IPv4 path and protocol are working, but the server's + IPv6 path and protocol are not working, a dual-stack client + application experiences significant connection delay compared to an + IPv4-only client. This is undesirable because it causes the dual- + stack client to have a worse user experience. This document + specifies requirements for algorithms that reduce this user-visible + delay and provides an algorithm. + + For more information: https://tools.ietf.org/html/rfc6555 .. versionadded:: 3.7 @@ -467,7 +481,7 @@ Opening network connections UDP. Explicitly passing ``reuse_address=True`` will raise an exception. When multiple processes with differing UIDs assign sockets to an - indentical UDP socket address with ``SO_REUSEADDR``, incoming packets can + identical UDP socket address with ``SO_REUSEADDR``, incoming packets can become randomly distributed among the sockets. For supported platforms, *reuse_port* can be used as a replacement for diff --git a/Doc/library/code.rst b/Doc/library/code.rst index e2c47ba..6708079 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -76,7 +76,7 @@ Interactive Interpreter Objects Compile and run some source in the interpreter. Arguments are the same as for :func:`compile_command`; the default for *filename* is ``''``, and for - *symbol* is ``'single'``. One several things can happen: + *symbol* is ``'single'``. One of several things can happen: * The input is incorrect; :func:`compile_command` raised an exception (:exc:`SyntaxError` or :exc:`OverflowError`). A syntax traceback will be diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index a5e8d04..8dcf945 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -33,10 +33,10 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`, :class:`UserString` wrapper around string objects for easier string subclassing ===================== ==================================================================== -.. deprecated-removed:: 3.3 3.9 +.. deprecated-removed:: 3.3 3.10 Moved :ref:`collections-abstract-base-classes` to the :mod:`collections.abc` module. For backwards compatibility, they continue to be visible in this module through - Python 3.8. + Python 3.9. :class:`ChainMap` objects diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 49e22fa..61d3982 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -161,7 +161,8 @@ The :mod:`csv` module defines the following classes: If a row has more fields than fieldnames, the remaining data is put in a list and stored with the fieldname specified by *restkey* (which defaults to ``None``). If a non-blank row has fewer fields than fieldnames, the - missing values are filled-in with ``None``. + missing values are filled-in with the value of *restval* (which defaults + to ``None``). All other optional or keyword arguments are passed to the underlying :class:`reader` instance. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index e0bc28f..2d6c6d0 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -161,13 +161,6 @@ as the ``NULL`` pointer):: 0x1d000000 >>> -.. note:: - - :mod:`ctypes` may raise a :exc:`ValueError` after calling the function, if - it detects that an invalid number of arguments were passed. This behavior - should not be relied upon. It is deprecated in 3.6.2, and will be removed - in 3.7. - :exc:`ValueError` is raised when you call an ``stdcall`` function with the ``cdecl`` calling convention, or vice versa:: @@ -624,7 +617,7 @@ Structure/union alignment and byte order ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default, Structure and Union fields are aligned in the same way the C -compiler does it. It is possible to override this behavior be specifying a +compiler does it. It is possible to override this behavior by specifying a :attr:`_pack_` class attribute in the subclass definition. This must be set to a positive integer and specifies the maximum alignment for the fields. This is what ``#pragma pack(n)`` also does in MSVC. @@ -922,7 +915,7 @@ attribute later, after the class statement:: ... ("next", POINTER(cell))] >>> -Lets try it. We create two instances of ``cell``, and let them point to each +Let's try it. We create two instances of ``cell``, and let them point to each other, and finally follow the pointer chain a few times:: >>> c1 = cell() @@ -1125,8 +1118,8 @@ hit the ``NULL`` entry:: >>> The fact that standard Python has a frozen module and a frozen package -(indicated by the negative size member) is not well known, it is only used for -testing. Try it out with ``import __hello__`` for example. +(indicated by the negative ``size`` member) is not well known, it is only used +for testing. Try it out with ``import __hello__`` for example. .. _ctypes-surprises: diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 9aa4a19..10edcac 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -19,6 +19,8 @@ in :pep:`557`. The member variables to use in these generated methods are defined using :pep:`526` type annotations. For example this code:: + from dataclasses import dataclass + @dataclass class InventoryItem: '''Class for keeping track of an item in inventory.''' @@ -60,8 +62,9 @@ Module-level decorators, classes, and functions The :func:`dataclass` decorator will add various "dunder" methods to the class, described below. If any of the added methods already - exist on the class, a :exc:`TypeError` will be raised. The decorator - returns the same class that is called on: no new class is created. + exist on the class, the behavior depends on the parameter, as documented + below. The decorator returns the same class that is called on; no new + class is created. If :func:`dataclass` is used just as a simple decorator with no parameters, it acts as if it has the default values documented in this @@ -115,7 +118,7 @@ Module-level decorators, classes, and functions If the class already defines any of :meth:`__lt__`, :meth:`__le__`, :meth:`__gt__`, or :meth:`__ge__`, then - :exc:`ValueError` is raised. + :exc:`TypeError` is raised. - ``unsafe_hash``: If ``False`` (the default), a :meth:`__hash__` method is generated according to how ``eq`` and ``frozen`` are set. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index b49eab4..29c6b5a 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -997,8 +997,6 @@ Other constructors, all class methods: as the inverse operation of :meth:`datetime.isoformat`. A more full-featured ISO 8601 parser, ``dateutil.parser.isoparse`` is available in the third-party package `dateutil `__. - This does not support parsing arbitrary ISO 8601 strings - it is only intended - as the inverse operation of :meth:`datetime.isoformat`. Examples:: @@ -2514,7 +2512,7 @@ Notes: :meth:`utcoffset` is transformed into a string of the form ``±HHMM[SS[.ffffff]]``, where ``HH`` is a 2-digit string giving the number of UTC offset hours, ``MM`` is a 2-digit string giving the number of UTC - offset minutes, SS is a 2-digit string giving the number of UTC offset + offset minutes, ``SS`` is a 2-digit string giving the number of UTC offset seconds and ``ffffff`` is a 6-digit string giving the number of UTC offset microseconds. The ``ffffff`` part is omitted when the offset is a whole number of seconds and both the ``ffffff`` and the ``SS`` part is diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index bcae55e..3dda35f 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -1475,9 +1475,18 @@ are also included in the pure Python version for compatibility. .. data:: HAVE_THREADS - The default value is ``True``. If Python is compiled without threads, the - C version automatically disables the expensive thread local context - machinery. In this case, the value is ``False``. + The value is ``True``. Deprecated, because Python now always has threads. + +.. deprecated:: 3.9 + +.. data:: HAVE_CONTEXTVAR + + The default value is ``True``. If Python is compiled ``--without-decimal-contextvar``, + the C version uses a thread-local rather than a coroutine-local context and the value + is ``False``. This is slightly faster in some nested context scenarios. + +.. versionadded:: 3.9 backported to 3.7 and 3.8 + Rounding modes -------------- @@ -2121,17 +2130,67 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic. +arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. However, to realize this performance gain, the -context needs to be set for unrounded calculations. +for very large numbers. + +The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` +and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` +should always be 0 (the default). Setting :attr:`prec` requires some care. + +The easiest approach for trying out bignum arithmetic is to use the maximum +value for :attr:`prec` as well [#]_:: + + >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) + >>> x = Decimal(2) ** 256 + >>> x / 128 + Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') + + +For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and +the available memory will be insufficient:: + + >>> Decimal(1) / 3 + Traceback (most recent call last): + File "", line 1, in + MemoryError + +On systems with overallocation (e.g. Linux), a more sophisticated approach is to +adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of +RAM and expect 10 simultaneous operands using a maximum of 500MB each:: + + >>> import sys + >>> + >>> # Maximum number of digits for a single operand using 500MB in 8-byte words + >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): + >>> maxdigits = 19 * ((500 * 1024**2) // 8) + >>> + >>> # Check that this works: + >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) + >>> c.traps[Inexact] = True + >>> setcontext(c) + >>> + >>> # Fill the available precision with nines: + >>> x = Decimal(0).logical_invert() * 9 + >>> sys.getsizeof(x) + 524288112 + >>> x + 2 + Traceback (most recent call last): + File "", line 1, in + decimal.Inexact: [] + +In general (and especially on systems without overallocation), it is recommended +to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations +are expected to be exact. + - >>> c = getcontext() - >>> c.prec = MAX_PREC - >>> c.Emax = MAX_EMAX - >>> c.Emin = MIN_EMIN +.. [#] + .. versionadded:: 3.3 -.. versionadded:: 3.3 \ No newline at end of file +.. [#] + .. versionchanged:: 3.9 + This approach now works for all exact results except for non-integer powers. + Also backported to 3.7 and 3.8. diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 39a3e13..5b34e68 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -244,7 +244,7 @@ operation is being performed, so the intermediate analysis object isn't useful: .. function:: findlabels(code) - Detect all offsets in the code object *code* which are jump targets, and + Detect all offsets in the raw compiled bytecode string *code* which are jump targets, and return a list of these offsets. @@ -894,9 +894,9 @@ All of the following opcodes use their arguments. .. opcode:: BUILD_CONST_KEY_MAP (count) - The version of :opcode:`BUILD_MAP` specialized for constant keys. *count* - values are consumed from the stack. The top element on the stack contains - a tuple of keys. + The version of :opcode:`BUILD_MAP` specialized for constant keys. Pops the + top element on the stack which contains a tuple of keys, then starting from + ``TOS1``, pops *count* values to form values in the built dictionary. .. versionadded:: 3.6 @@ -1176,27 +1176,29 @@ All of the following opcodes use their arguments. .. opcode:: LOAD_METHOD (namei) - Loads a method named ``co_names[namei]`` from TOS object. TOS is popped and - method and TOS are pushed when interpreter can call unbound method directly. - TOS will be used as the first argument (``self``) by :opcode:`CALL_METHOD`. - Otherwise, ``NULL`` and method is pushed (method is bound method or - something else). + Loads a method named ``co_names[namei]`` from the TOS object. TOS is popped. + This bytecode distinguishes two cases: if TOS has a method with the correct + name, the bytecode pushes the unbound method and TOS. TOS will be used as + the first argument (``self``) by :opcode:`CALL_METHOD` when calling the + unbound method. Otherwise, ``NULL`` and the object return by the attribute + lookup are pushed. .. versionadded:: 3.7 .. opcode:: CALL_METHOD (argc) - Calls a method. *argc* is number of positional arguments. + Calls a method. *argc* is the number of positional arguments. Keyword arguments are not supported. This opcode is designed to be used with :opcode:`LOAD_METHOD`. Positional arguments are on top of the stack. - Below them, two items described in :opcode:`LOAD_METHOD` on the stack. - All of them are popped and return value is pushed. + Below them, the two items described in :opcode:`LOAD_METHOD` are on the + stack (either ``self`` and an unbound method object or ``NULL`` and an + arbitrary callable). All of them are popped and the return value is pushed. .. versionadded:: 3.7 -.. opcode:: MAKE_FUNCTION (argc) +.. opcode:: MAKE_FUNCTION (flags) Pushes a new function object on the stack. From bottom to top, the consumed stack must consist of values if the argument carries a specified flag value diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index a2bb045..a522125 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -74,7 +74,7 @@ options: script will *not* be installed. * ``--default-pip``: if a "default pip" installation is requested, the - ``pip`` script will be installed in addition to the two regular scripts. + ``pip`` script will be installed in addition to the two regular scripts. Providing both of the script selection options will trigger an exception. diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 19277d7..7538084 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -55,7 +55,7 @@ helper, :class:`auto`. .. class:: auto - Instances are replaced with an appropriate value for Enum members. + Instances are replaced with an appropriate value for Enum members. Initial value starts at 1. .. versionadded:: 3.6 ``Flag``, ``IntFlag``, ``auto`` diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index a739015..69484b6 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -57,6 +57,8 @@ The module defines the following functions: If the :c:func:`fcntl` fails, an :exc:`OSError` is raised. + .. audit-event:: fcntl.fcntl fd,cmd,arg fcntl.fcntl + .. function:: ioctl(fd, request, arg=0, mutate_flag=True) @@ -106,6 +108,8 @@ The module defines the following functions: >>> buf array('h', [13341]) + .. audit-event:: fcntl.ioctl fd,request,arg fcntl.ioctl + .. function:: flock(fd, operation) @@ -116,6 +120,8 @@ The module defines the following functions: If the :c:func:`flock` fails, an :exc:`OSError` exception is raised. + .. audit-event:: fcntl.flock fd,operation fcntl.flock + .. function:: lockf(fd, cmd, len=0, start=0, whence=0) @@ -149,6 +155,8 @@ The module defines the following functions: The default for *len* is 0 which means to lock to the end of the file. The default for *whence* is also 0. + .. audit-event:: fcntl.lockf fd,cmd,len,start,whence fcntl.lockf + Examples (all on a SVR4 compliant system):: import struct, fcntl, os diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7968eef..0f7df0e 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -950,7 +950,7 @@ are always available. They are listed here in alphabetical order. .. _func-memoryview: -.. function:: memoryview(obj) +.. class:: memoryview(obj) :noindex: Return a "memory view" object created from the given argument. See @@ -1304,7 +1304,7 @@ are always available. They are listed here in alphabetical order. the second argument to be negative, permitting computation of modular inverses. - .. versionchanged:: 3.9 + .. versionchanged:: 3.8 Allow keyword arguments. Formerly, only positional arguments were supported. @@ -1412,7 +1412,7 @@ are always available. They are listed here in alphabetical order. .. _func-range: -.. function:: range(stop) +.. class:: range(stop) range(start, stop[, step]) :noindex: @@ -1659,7 +1659,7 @@ are always available. They are listed here in alphabetical order. .. _func-tuple: -.. function:: tuple([iterable]) +.. class:: tuple([iterable]) :noindex: Rather than being a function, :class:`tuple` is actually an immutable diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 3a0b554..0fb8d90 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -101,8 +101,7 @@ The :mod:`functools` module defines the following functions: return sum(sentence.count(vowel) for vowel in 'aeiou') If *maxsize* is set to ``None``, the LRU feature is disabled and the cache can - grow without bound. The LRU feature performs best when *maxsize* is a - power-of-two. + grow without bound. If *typed* is set to true, function arguments of different types will be cached separately. For example, ``f(3)`` and ``f(3.0)`` will be treated diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 937330b..ec2c128 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -724,8 +724,8 @@ implementations, and valuable experience to the creation of this module: .. [#] The default locale directory is system dependent; for example, on RedHat Linux it is :file:`/usr/share/locale`, but on Solaris it is :file:`/usr/lib/locale`. The :mod:`gettext` module does not try to support these system dependent - defaults; instead its default is :file:`{sys.prefix}/share/locale` (see - :data:`sys.prefix`). For this reason, it is always best to call + defaults; instead its default is :file:`{sys.base_prefix}/share/locale` (see + :data:`sys.base_prefix`). For this reason, it is always best to call :func:`bindtextdomain` with an explicit absolute path at the start of your application. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 9cdabc2..be31c3c 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -563,8 +563,8 @@ Here is an example session that shows how to ``POST`` requests:: Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The difference lies only the server side where HTTP server will allow resources to be created via ``PUT`` request. It should be noted that custom HTTP methods -+are also handled in :class:`urllib.request.Request` by sending the appropriate -+method attribute.Here is an example session that shows how to do ``PUT`` +are also handled in :class:`urllib.request.Request` by setting the appropriate +method attribute. Here is an example session that shows how to send a ``PUT`` request using http.client:: >>> # This creates an HTTP message diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 273b583..b1192e7 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -142,7 +142,9 @@ Replace... Open a search-and-replace dialog. Go to Line - Move cursor to the line number requested and make that line visible. + Move the cursor to the beginning of the line requested and make that + line visible. A request past the end of the file goes to the end. + Clear any selection and update the line and column status. Show Completions Open a scrollable list allowing selection of keywords and attributes. See @@ -370,7 +372,8 @@ Paste Editor windows also have breakpoint functions. Lines with a breakpoint set are specially marked. Breakpoints only have an effect when running under the -debugger. Breakpoints for a file are saved in the user's .idlerc directory. +debugger. Breakpoints for a file are saved in the user's ``.idlerc`` +directory. Set Breakpoint Set a breakpoint on the current line. @@ -680,19 +683,22 @@ clash, or cannot or does not want to run as admin, it might be easiest to completely remove Python and start over. A zombie pythonw.exe process could be a problem. On Windows, use Task -Manager to detect and stop one. Sometimes a restart initiated by a program -crash or Keyboard Interrupt (control-C) may fail to connect. Dismissing -the error box or Restart Shell on the Shell menu may fix a temporary problem. +Manager to check for one and stop it if there is. Sometimes a restart +initiated by a program crash or Keyboard Interrupt (control-C) may fail +to connect. Dismissing the error box or using Restart Shell on the Shell +menu may fix a temporary problem. When IDLE first starts, it attempts to read user configuration files in -~/.idlerc/ (~ is one's home directory). If there is a problem, an error +``~/.idlerc/`` (~ is one's home directory). If there is a problem, an error message should be displayed. Leaving aside random disk glitches, this can -be prevented by never editing the files by hand, using the configuration -dialog, under Options, instead Options. Once it happens, the solution may -be to delete one or more of the configuration files. +be prevented by never editing the files by hand. Instead, use the +configuration dialog, under Options. Once there is an error in a user +configuration file, the best solution may be to delete it and start over +with the settings dialog. If IDLE quits with no message, and it was not started from a console, try -starting from a console (``python -m idlelib)`` and see if a message appears. +starting it from a console or terminal (``python -m idlelib``) and see if +this results in an error message. Running user code ^^^^^^^^^^^^^^^^^ @@ -863,13 +869,13 @@ Or click the TOC (Table of Contents) button and select a section header in the opened box. Help menu entry "Python Docs" opens the extensive sources of help, -including tutorials, available at docs.python.org/x.y, where 'x.y' +including tutorials, available at ``docs.python.org/x.y``, where 'x.y' is the currently running Python version. If your system has an off-line copy of the docs (this may be an installation option), that will be opened instead. Selected URLs can be added or removed from the help menu at any time using the -General tab of the Configure IDLE dialog . +General tab of the Configure IDLE dialog. .. _preferences: @@ -878,9 +884,9 @@ Setting preferences The font preferences, highlighting, keys, and general preferences can be changed via Configure IDLE on the Option menu. -Non-default user settings are saved in a .idlerc directory in the user's +Non-default user settings are saved in a ``.idlerc`` directory in the user's home directory. Problems caused by bad user configuration files are solved -by editing or deleting one or more of the files in .idlerc. +by editing or deleting one or more of the files in ``.idlerc``. On the Font tab, see the text sample for the effect of font face and size on multiple characters in multiple languages. Edit the sample to add diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index aa22a5b..2de1043 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1029,6 +1029,10 @@ find and load modules. Only class methods are defined by this class to alleviate the need for instantiation. + .. versionchanged:: 3.4 + Gained :meth:`~Loader.create_module` and :meth:`~Loader.exec_module` + methods. + .. class:: WindowsRegistryFinder diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 10f347d..bab2c41 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -70,6 +70,9 @@ attributes: | | | method is bound, or | | | | ``None`` | +-----------+-------------------+---------------------------+ +| | __module__ | name of module in which | +| | | this method was defined | ++-----------+-------------------+---------------------------+ | function | __doc__ | documentation string | +-----------+-------------------+---------------------------+ | | __name__ | name with which this | @@ -98,6 +101,9 @@ attributes: | | | reserved for return | | | | annotations. | +-----------+-------------------+---------------------------+ +| | __module__ | name of module in which | +| | | this function was defined | ++-----------+-------------------+---------------------------+ | traceback | tb_frame | frame object at this | | | | level | +-----------+-------------------+---------------------------+ diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 70e0115..32151a0 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -132,12 +132,13 @@ High-level Module Interface Opens the provided file with mode ``'rb'``. This function should be used when the intent is to treat the contents as executable code. - ``path`` should be an absolute path. + ``path`` should be a :class:`str` and an absolute path. The behavior of this function may be overridden by an earlier call to the - :c:func:`PyFile_SetOpenCodeHook`, however, it should always be considered - interchangeable with ``open(path, 'rb')``. Overriding the behavior is - intended for additional validation or preprocessing of the file. + :c:func:`PyFile_SetOpenCodeHook`. However, assuming that ``path`` is a + :class:`str` and an absolute path, ``open_code(path)`` should always behave + the same as ``open(path, 'rb')``. Overriding the behavior is intended for + additional validation or preprocessing of the file. .. versionadded:: 3.8 diff --git a/Doc/library/keyword.rst b/Doc/library/keyword.rst index 3768df9..acec45c 100644 --- a/Doc/library/keyword.rst +++ b/Doc/library/keyword.rst @@ -8,16 +8,17 @@ -------------- -This module allows a Python program to determine if a string is a keyword. +This module allows a Python program to determine if a string is a +:ref:`keyword `. .. function:: iskeyword(s) - Return ``True`` if *s* is a Python keyword. + Return ``True`` if *s* is a Python :ref:`keyword `. .. data:: kwlist - Sequence containing all the keywords defined for the interpreter. If any - keywords are defined to only be active when particular :mod:`__future__` - statements are in effect, these will be included as well. + Sequence containing all the :ref:`keywords ` defined for the + interpreter. If any keywords are defined to only be active when particular + :mod:`__future__` statements are in effect, these will be included as well. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 4da5778..14e7190 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -159,6 +159,7 @@ is the module's name in the Python package namespace. message format string, and the *args* are the arguments which are merged into *msg* using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) + No % formatting operation is performed on *msg* when no *args* are supplied. There are four keyword arguments in *kwargs* which are inspected: *exc_info*, *stack_info*, *stacklevel* and *extra*. diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst index 896afd1..bf9639b 100644 --- a/Doc/library/mailcap.rst +++ b/Doc/library/mailcap.rst @@ -18,7 +18,7 @@ belonging to a temporary file) and the :program:`xmpeg` program can be automatically started to view the file. The mailcap format is documented in :rfc:`1524`, "A User Agent Configuration -Mechanism For Multimedia Mail Format Information," but is not an Internet +Mechanism For Multimedia Mail Format Information", but is not an Internet standard. However, mailcap files are supported on most Unix systems. diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 14ad2cd..42fffee 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -42,6 +42,8 @@ File Operations regions in a file may be locked at the same time, but may not overlap. Adjacent regions are not merged; they must be unlocked individually. + .. audit-event:: msvcrt.locking fd,mode,nbytes msvcrt.locking + .. data:: LK_LOCK LK_RLCK @@ -77,12 +79,16 @@ File Operations and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter to :func:`os.fdopen` to create a file object. + .. audit-event:: msvcrt.open_osfhandle handle,flags msvcrt.open_osfhandle + .. function:: get_osfhandle(fd) Return the file handle for the file descriptor *fd*. Raises :exc:`OSError` if *fd* is not recognized. + .. audit-event:: msvcrt.get_osfhandle fd msvcrt.get_osfhandle + .. _msvcrt-console: diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 3c7b5cc..ec9521f 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -439,7 +439,8 @@ process which created it. >>> def f(x): ... return x*x ... - >>> p.map(f, [1,2,3]) + >>> with p: + ... p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: Process PoolWorker-3: @@ -2127,6 +2128,16 @@ with the :class:`Pool` class. Note that the methods of the pool object should only be called by the process which created the pool. + .. warning:: + :class:`multiprocessing.pool` objects have internal resources that need to be + properly managed (like any other resource) by using the pool as a context manager + or by calling :meth:`close` and :meth:`terminate` manually. Failure to do this + can lead to the process hanging on finalization. + + Note that is **not correct** to rely on the garbage colletor to destroy the pool + as CPython does not assure that the finalizer of the pool will be called + (see :meth:`object.__del__` for more information). + .. versionadded:: 3.2 *maxtasksperchild* @@ -2279,7 +2290,7 @@ with the :class:`Pool` class. .. method:: successful() Return whether the call completed without raising an exception. Will - raise :exc:`AssertionError` if the result is not ready. + raise :exc:`ValueError` if the result is not ready. .. versionchanged:: 3.7 If the result is not ready, :exc:`ValueError` is raised instead of diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index 46f1c07..e8480b5 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -20,7 +20,7 @@ as well as the older :rfc:`977` and :rfc:`2980`. Here are two small examples of how it can be used. To list some statistics about a newsgroup and print the subjects of the last 10 articles:: - >>> s = nntplib.NNTP('news.gmane.org') + >>> s = nntplib.NNTP('news.gmane.io') >>> resp, count, first, last, name = s.group('gmane.comp.python.committers') >>> print('Group', name, 'has', count, 'articles, range', first, 'to', last) Group gmane.comp.python.committers has 1096 articles, range 1 to 1096 @@ -44,7 +44,7 @@ about a newsgroup and print the subjects of the last 10 articles:: To post an article from a binary file (this assumes that the article has valid headers, and that you have right to post on the particular newsgroup):: - >>> s = nntplib.NNTP('news.gmane.org') + >>> s = nntplib.NNTP('news.gmane.io') >>> f = open('article.txt', 'rb') >>> s.post(f) '240 Article posted successfully.' @@ -73,7 +73,7 @@ The module itself defines the following classes: connection when done, e.g.: >>> from nntplib import NNTP - >>> with NNTP('news.gmane.org') as n: + >>> with NNTP('news.gmane.io') as n: ... n.group('gmane.comp.python.committers') ... # doctest: +SKIP ('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers') @@ -225,7 +225,7 @@ tuples or objects that the method normally returns will be empty. of values. On legacy servers which don't understand the ``CAPABILITIES`` command, an empty dictionary is returned instead. - >>> s = NNTP('news.gmane.org') + >>> s = NNTP('news.gmane.io') >>> 'POST' in s.getcapabilities() True diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 9d2e8b2..77bbf99 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -451,6 +451,8 @@ process and user. calls to :func:`putenv` don't update ``os.environ``, so it is actually preferable to assign to items of ``os.environ``. + .. audit-event:: os.putenv key,value os.putenv + .. function:: setegid(egid) @@ -643,7 +645,9 @@ process and user. calls to :func:`unsetenv` don't update ``os.environ``, so it is actually preferable to delete items of ``os.environ``. - .. availability:: most flavors of Unix, Windows. + .. audit-event:: os.unsetenv key os.unsetenv + + .. availability:: most flavors of Unix. .. _os-newstreams: @@ -768,6 +772,8 @@ as internal buffering of data. docs for :func:`chmod` for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(fd, mode)``. + .. audit-event:: os.chmod path,mode,dir_fd os.fchmod + .. availability:: Unix. @@ -778,6 +784,8 @@ as internal buffering of data. :func:`chown`. As of Python 3.3, this is equivalent to ``os.chown(fd, uid, gid)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.fchown + .. availability:: Unix. @@ -885,6 +893,8 @@ as internal buffering of data. :data:`F_ULOCK` or :data:`F_TEST`. *len* specifies the section of the file to lock. + .. audit-event:: os.lockf fd,cmd,len os.lockf + .. availability:: Unix. .. versionadded:: 3.3 @@ -1602,6 +1612,8 @@ features: This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. audit-event:: os.chdir path os.chdir + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. @@ -1630,6 +1642,8 @@ features: This function can support :ref:`not following symlinks `. + .. audit-event:: os.chflags path,flags os.chflags + .. availability:: Unix. .. versionadded:: 3.3 @@ -1675,6 +1689,8 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1695,6 +1711,8 @@ features: See :func:`shutil.chown` for a higher-level function that accepts names in addition to numeric ids. + .. audit-event:: os.chown path,uid,gid,dir_fd os.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -1721,6 +1739,8 @@ features: descriptor *fd*. The descriptor must refer to an opened directory, not an open file. As of Python 3.3, this is equivalent to ``os.chdir(fd)``. + .. audit-event:: os.chdir path os.fchdir + .. availability:: Unix. @@ -1745,6 +1765,8 @@ features: not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chflags(path, flags, follow_symlinks=False)``. + .. audit-event:: os.chflags path,flags os.lchflags + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1758,6 +1780,8 @@ features: for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(path, mode, follow_symlinks=False)``. + .. audit-event:: os.chmod path,mode,dir_fd os.lchmod + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1769,6 +1793,8 @@ features: function will not follow symbolic links. As of Python 3.3, this is equivalent to ``os.chown(path, uid, gid, follow_symlinks=False)``. + .. audit-event:: os.chown path,uid,gid,dir_fd os.lchown + .. availability:: Unix. .. versionchanged:: 3.6 @@ -1783,6 +1809,8 @@ features: supply :ref:`paths relative to directory descriptors `, and :ref:`not following symlinks `. + .. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -1885,6 +1913,8 @@ features: It is also possible to create temporary directories; see the :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. + .. audit-event:: os.mkdir path,mode,dir_fd os.mkdir + .. versionadded:: 3.3 The *dir_fd* argument. @@ -1917,6 +1947,8 @@ features: This function handles UNC paths correctly. + .. audit-event:: os.mkdir path,mode,dir_fd os.makedirs + .. versionadded:: 3.2 The *exist_ok* parameter. @@ -2082,6 +2114,8 @@ features: This function is semantically identical to :func:`unlink`. + .. audit-event:: os.remove path,dir_fd os.remove + .. versionadded:: 3.3 The *dir_fd* argument. @@ -2102,6 +2136,8 @@ features: they are empty. Raises :exc:`OSError` if the leaf directory could not be successfully removed. + .. audit-event:: os.remove path,dir_fd os.removedirs + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2127,6 +2163,8 @@ features: If you want cross-platform overwriting of the destination, use :func:`replace`. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.rename + .. versionadded:: 3.3 The *src_dir_fd* and *dst_dir_fd* arguments. @@ -2146,6 +2184,8 @@ features: This function can fail with the new directory structure made if you lack permissions needed to remove the leaf directory or file. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.renames + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *old* and *new*. @@ -2161,6 +2201,8 @@ features: This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to supply :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rename src,dst,src_dir_fd,dst_dir_fd os.replace + .. versionadded:: 3.3 .. versionchanged:: 3.6 @@ -2177,6 +2219,8 @@ features: This function can support :ref:`paths relative to directory descriptors `. + .. audit-event:: os.rmdir path,dir_fd os.rmdir + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2820,6 +2864,8 @@ features: :exc:`OSError` is raised when the function is called by an unprivileged user. + .. audit-event:: os.symlink src,dst,dir_fd os.symlink + .. availability:: Unix, Windows. .. versionchanged:: 3.2 @@ -2872,6 +2918,8 @@ features: traditional Unix name. Please see the documentation for :func:`remove` for further information. + .. audit-event:: os.remove path,dir_fd os.unlink + .. versionadded:: 3.3 The *dir_fd* parameter. @@ -2909,6 +2957,8 @@ features: :ref:`paths relative to directory descriptors ` and :ref:`not following symlinks `. + .. audit-event:: os.utime path,times,ns,dir_fd os.utime + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd*, *follow_symlinks*, and *ns* parameters. @@ -3134,6 +3184,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.getxattr path,attribute os.getxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3148,6 +3200,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.listxattr path os.listxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -3162,6 +3216,8 @@ These functions are all available on Linux only. This function can support :ref:`specifying a file descriptor ` and :ref:`not following symlinks `. + .. audit-event:: os.removexattr path,attribute os.removexattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3185,6 +3241,8 @@ These functions are all available on Linux only. A bug in Linux kernel versions less than 2.6.39 caused the flags argument to be ignored on some filesystems. + .. audit-event:: os.setxattr path,attribute,value,flags os.setxattr + .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *path* and *attribute*. @@ -3247,6 +3305,8 @@ to be ignored. `_ for more information about how DLLs are loaded. + .. audit-event:: os.add_dll_directory path os.add_dll_directory + .. availability:: Windows. .. versionadded:: 3.8 @@ -3313,6 +3373,8 @@ to be ignored. you can check whether or not it is available using :data:`os.supports_fd`. If it is unavailable, using it will raise a :exc:`NotImplementedError`. + .. audit-event:: os.exec path,args,env os.execl + .. availability:: Unix, Windows. .. versionadded:: 3.3 @@ -3477,6 +3539,8 @@ written in Python, such as a mail server's external command delivery program. Note that some platforms including FreeBSD <= 6.3 and Cygwin have known issues when using ``fork()`` from a thread. + .. audit-event:: os.fork "" os.fork + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3496,6 +3560,8 @@ written in Python, such as a mail server's external command delivery program. master end of the pseudo-terminal. For a more portable approach, use the :mod:`pty` module. If an error occurs :exc:`OSError` is raised. + .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3522,6 +3588,8 @@ written in Python, such as a mail server's external command delivery program. See also :func:`signal.pthread_kill`. + .. audit-event:: os.kill pid,sig os.kill + .. versionadded:: 3.2 Windows support. @@ -3534,6 +3602,8 @@ written in Python, such as a mail server's external command delivery program. Send the signal *sig* to the process group *pgid*. + .. audit-event:: os.killpg pgid,sig os.killpg + .. availability:: Unix. @@ -3656,6 +3726,8 @@ written in Python, such as a mail server's external command delivery program. :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` flags. + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawn + .. versionadded:: 3.8 .. availability:: Unix. @@ -3670,6 +3742,8 @@ written in Python, such as a mail server's external command delivery program. for the *executable* file in the list of directories specified by the :envvar:`PATH` environment variable (in the same way as for ``execvp(3)``). + .. audit-event:: os.posix_spawn path,argv,env os.posix_spawnp + .. versionadded:: 3.8 .. availability:: See :func:`posix_spawn` documentation. @@ -3770,6 +3844,8 @@ written in Python, such as a mail server's external command delivery program. L = ['cp', 'index.html', '/dev/null'] os.spawnvpe(os.P_WAIT, 'cp', L, os.environ) + .. audit-event:: os.spawn mode,path,args,env os.spawnl + .. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and :func:`spawnve` are not thread-safe on Windows; we advise you to use the @@ -3839,6 +3915,8 @@ written in Python, such as a mail server's external command delivery program. function is not resolved until this function is first called. If the function cannot be resolved, :exc:`NotImplementedError` will be raised. + .. audit-event:: os.startfile path,operation os.startfile + .. availability:: Windows. @@ -3888,10 +3966,8 @@ written in Python, such as a mail server's external command delivery program. See the Unix manual page :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN - ` - _ on Windows. - On Windows, only :attr:`user` and :attr:`system` are known; the other - attributes are zero. + `_ + on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. .. availability:: Unix, Windows. @@ -4052,28 +4128,36 @@ used to determine the disposition of a process. Return ``True`` if a core dump was generated for the process, otherwise return ``False``. + This function should be employed only if :func:`WIFSIGNALED` is true. + .. availability:: Unix. .. function:: WIFCONTINUED(status) - Return ``True`` if the process has been continued from a job control stop, - otherwise return ``False``. + Return ``True`` if a stopped child has been resumed by delivery of + :data:`~signal.SIGCONT` (if the process has been continued from a job + control stop), otherwise return ``False``. + + See :data:`WCONTINUED` option. .. availability:: Unix. .. function:: WIFSTOPPED(status) - Return ``True`` if the process has been stopped, otherwise return - ``False``. + Return ``True`` if the process was stopped by delivery of a signal, + otherwise return ``False``. - .. availability:: Unix. + :func:`WIFSTOPPED` only returns ``True`` if the :func:`waitpid` call was + done using :data:`WUNTRACED` option or when the process is being traced (see + :manpage:`ptrace(2)`). + .. availability:: Unix. .. function:: WIFSIGNALED(status) - Return ``True`` if the process exited due to a signal, otherwise return + Return ``True`` if the process was terminated by a signal, otherwise return ``False``. .. availability:: Unix. @@ -4081,7 +4165,8 @@ used to determine the disposition of a process. .. function:: WIFEXITED(status) - Return ``True`` if the process exited using the :manpage:`exit(2)` system call, + Return ``True`` if the process exited terminated normally, that is, + by calling ``exit()`` or ``_exit()``, or by returning from ``main()``; otherwise return ``False``. .. availability:: Unix. @@ -4089,8 +4174,9 @@ used to determine the disposition of a process. .. function:: WEXITSTATUS(status) - If ``WIFEXITED(status)`` is true, return the integer parameter to the - :manpage:`exit(2)` system call. Otherwise, the return value is meaningless. + Return the process exit status. + + This function should be employed only if :func:`WIFEXITED` is true. .. availability:: Unix. @@ -4099,12 +4185,16 @@ used to determine the disposition of a process. Return the signal which caused the process to stop. + This function should be employed only if :func:`WIFSTOPPED` is true. + .. availability:: Unix. .. function:: WTERMSIG(status) - Return the signal which caused the process to exit. + Return the number of the signal that caused the process to terminate. + + This function should be employed only if :func:`WIFSIGNALED` is true. .. availability:: Unix. diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 326bb2e..b900d09 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -515,8 +515,10 @@ Pure paths provide the following methods and properties: >>> PurePath('a/b.py').match('/*.py') False - As with other methods, case-sensitivity is observed:: + As with other methods, case-sensitivity follows platform defaults:: + >>> PurePosixPath('b.py').match('*.PY') + False >>> PureWindowsPath('b.py').match('*.PY') True @@ -672,7 +674,7 @@ call fails (for example because the path doesn't exist). .. method:: Path.stat() - Return information about this path (similarly to :func:`os.stat`). + Return a :class:`os.stat_result` object containing information about this path, like :func:`os.stat`. The result is looked up at each call to this method. :: diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 779b60e..d92e947 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -252,10 +252,10 @@ process more convenient: .. versionchanged:: 3.8 The *buffers* argument was added. -.. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None) +.. function:: loads(data, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None) Return the reconstituted object hierarchy of the pickled representation - *bytes_object* of an object. + *data* of an object. *data* must be a :term:`bytes-like object`. The protocol version of the pickle is detected automatically, so no protocol argument is needed. Bytes past the pickled representation @@ -639,9 +639,9 @@ the methods :meth:`__getstate__` and :meth:`__setstate__`. At unpickling time, some methods like :meth:`__getattr__`, :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the instance. In case those methods rely on some internal invariant being - true, the type should implement :meth:`__getnewargs__` or - :meth:`__getnewargs_ex__` to establish such an invariant; otherwise, - neither :meth:`__new__` nor :meth:`__init__` will be called. + true, the type should implement :meth:`__new__` to establish such an + invariant, as :meth:`__init__` is not called when unpickling an + instance. .. index:: pair: copy; protocol diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 1d33afc..8e8e377 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -145,8 +145,8 @@ Cross Platform .. function:: system() - Returns the system/OS name, e.g. ``'Linux'``, ``'Windows'``, or ``'Java'``. An - empty string is returned if the value cannot be determined. + Returns the system/OS name, such as ``'Linux'``, ``'Darwin'``, ``'Java'``, + ``'Windows'``. An empty string is returned if the value cannot be determined. .. function:: system_alias(system, release, version) @@ -260,4 +260,3 @@ Unix Platforms using :program:`gcc`. The file is read and scanned in chunks of *chunksize* bytes. - diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 9abf286..b8b7f42 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -144,7 +144,7 @@ The :mod:`pprint` module also provides several shortcut functions: .. index:: builtin: eval - Determine if the formatted representation of *object* is "readable," or can be + Determine if the formatted representation of *object* is "readable", or can be used to reconstruct the value using :func:`eval`. This always returns ``False`` for recursive objects. diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 1226843..e85d2e2 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -69,6 +69,7 @@ The :mod:`pty` module defines the following functions: *select* throws an error on your platform when passed three empty lists. This is a bug, documented in `issue 26228 `_. + .. audit-event:: pty.spawn argv pty.spawn .. versionchanged:: 3.4 :func:`spawn` now returns the status value from :func:`os.waitpid` diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 3824353..a12a5bb 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -27,7 +27,7 @@ byte-code cache files in the directory containing the source code. Exception raised when an error occurs while attempting to compile the file. -.. function:: compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, invalidation_mode=PycInvalidationMode.TIMESTAMP) +.. function:: compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, invalidation_mode=PycInvalidationMode.TIMESTAMP, quiet=0) Compile a source file to byte-code and write out the byte-code cache file. The source code is loaded from the file named *file*. The byte-code is diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index b80a2fa..36e83e8 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -1,8 +1,8 @@ -:mod:`pyclbr` --- Python class browser support -============================================== +:mod:`pyclbr` --- Python module browser support +=============================================== .. module:: pyclbr - :synopsis: Supports information extraction for a Python class browser. + :synopsis: Supports information extraction for a Python module browser. .. sectionauthor:: Fred L. Drake, Jr. @@ -29,6 +29,9 @@ modules. *path* is a sequence of directory paths prepended to ``sys.path``, which is used to locate the module source code. + This function is the original interface and is only kept for back + compatibility. It returns a filtered version of the following. + .. function:: readmodule_ex(module, path=None) diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 2eeab5e..0ec5900 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -190,32 +190,28 @@ fully processed by daemon consumer threads. Example of how to wait for enqueued tasks to be completed:: + import threading, queue + + q = queue.Queue() + def worker(): while True: item = q.get() - if item is None: - break - do_work(item) + print(f'Working on {item}') + print(f'Finished {item}') q.task_done() - q = queue.Queue() - threads = [] - for i in range(num_worker_threads): - t = threading.Thread(target=worker) - t.start() - threads.append(t) + # turn-on the worker thread + threading.Thread(target=worker, daemon=True).start() - for item in source(): + # send thirty task requests to the worker + for item in range(30): q.put(item) + print('All task requests sent\n', end='') # block until all tasks are done q.join() - - # stop workers - for i in range(num_worker_threads): - q.put(None) - for t in threads: - t.join() + print('All work completed') SimpleQueue Objects diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 90b8624..2149e80 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -102,7 +102,7 @@ Bookkeeping functions .. function:: getrandbits(k) Returns a Python integer with *k* random bits. This method is supplied with - the MersenneTwister generator and some other generators may also provide it + the Mersenne Twister generator and some other generators may also provide it as an optional part of the API. When available, :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large ranges. @@ -394,29 +394,28 @@ Simulations:: >>> def trial(): ... return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5 ... - >>> sum(trial() for i in range(10000)) / 10000 + >>> sum(trial() for i in range(10_000)) / 10_000 0.4169 >>> # Probability of the median of 5 samples being in middle two quartiles >>> def trial(): - ... return 2500 <= sorted(choices(range(10000), k=5))[2] < 7500 + ... return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500 ... - >>> sum(trial() for i in range(10000)) / 10000 + >>> sum(trial() for i in range(10_000)) / 10_000 0.7958 Example of `statistical bootstrapping `_ using resampling -with replacement to estimate a confidence interval for the mean of a sample of -size five:: +with replacement to estimate a confidence interval for the mean of a sample:: # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm from statistics import fmean as mean from random import choices - data = 1, 2, 4, 4, 10 - means = sorted(mean(choices(data, k=5)) for i in range(20)) + data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95] + means = sorted(mean(choices(data, k=len(data))) for i in range(100)) print(f'The sample mean of {mean(data):.1f} has a 90% confidence ' - f'interval from {means[1]:.1f} to {means[-2]:.1f}') + f'interval from {means[5]:.1f} to {means[94]:.1f}') Example of a `resampling permutation test `_ @@ -432,7 +431,7 @@ between the effects of a drug versus a placebo:: placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46] observed_diff = mean(drug) - mean(placebo) - n = 10000 + n = 10_000 count = 0 combined = drug + placebo for i in range(n): @@ -445,32 +444,29 @@ between the effects of a drug versus a placebo:: print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null') print(f'hypothesis that there is no difference between the drug and the placebo.') -Simulation of arrival times and service deliveries in a single server queue:: +Simulation of arrival times and service deliveries for a multiserver queue:: + from heapq import heappush, heappop from random import expovariate, gauss from statistics import mean, median, stdev average_arrival_interval = 5.6 - average_service_time = 5.0 - stdev_service_time = 0.5 - - num_waiting = 0 - arrivals = [] - starts = [] - arrival = service_end = 0.0 - for i in range(20000): - if arrival <= service_end: - num_waiting += 1 - arrival += expovariate(1.0 / average_arrival_interval) - arrivals.append(arrival) - else: - num_waiting -= 1 - service_start = service_end if num_waiting else arrival - service_time = gauss(average_service_time, stdev_service_time) - service_end = service_start + service_time - starts.append(service_start) - - waits = [start - arrival for arrival, start in zip(arrivals, starts)] + average_service_time = 15.0 + stdev_service_time = 3.5 + num_servers = 3 + + waits = [] + arrival_time = 0.0 + servers = [0.0] * num_servers # time when each server becomes available + for i in range(100_000): + arrival_time += expovariate(1.0 / average_arrival_interval) + next_server_available = heappop(servers) + wait = max(0.0, next_server_available - arrival_time) + waits.append(wait) + service_duration = gauss(average_service_time, stdev_service_time) + service_completed = arrival_time + wait + service_duration + heappush(servers, service_completed) + print(f'Mean wait: {mean(waits):.1f}. Stdev wait: {stdev(waits):.1f}.') print(f'Median wait: {median(waits):.1f}. Max wait: {max(waits):.1f}.') diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 7c950bf..9abbd8b 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -1617,10 +1617,14 @@ The text categories are specified with regular expressions. The technique is to combine those into a single master regular expression and to loop over successive matches:: - import collections + from typing import NamedTuple import re - Token = collections.namedtuple('Token', ['type', 'value', 'line', 'column']) + class Token(NamedTuple): + type: str + value: str + line: int + column: int def tokenize(code): keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'} diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 3573da7..e4eac43 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -78,6 +78,9 @@ this module for those platforms. VxWorks only supports setting :data:`RLIMIT_NOFILE`. + .. audit-event:: resource.setrlimit resource,limits resource.setrlimit + + .. function:: prlimit(pid, resource[, limits]) Combines :func:`setrlimit` and :func:`getrlimit` in one function and @@ -94,6 +97,8 @@ this module for those platforms. :exc:`PermissionError` when the user doesn't have ``CAP_SYS_RESOURCE`` for the process. + .. audit-event:: resource.prlimit pid,resource,limits resource.prlimit + .. availability:: Linux 2.6.36 or later with glibc 2.13 or later. .. versionadded:: 3.4 diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 174b7e8..bd24de7 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -67,6 +67,8 @@ Directory and files operations a new symbolic link will be created instead of copying the file *src* points to. + .. audit-event:: shutil.copyfile src,dst shutil.copyfile + .. versionchanged:: 3.3 :exc:`IOError` used to be raised instead of :exc:`OSError`. Added *follow_symlinks* argument. @@ -101,6 +103,8 @@ Directory and files operations :func:`copymode` cannot modify symbolic links on the local platform, and it is asked to do so, it will do nothing and return. + .. audit-event:: shutil.copymode src,dst shutil.copymode + .. versionchanged:: 3.3 Added *follow_symlinks* argument. @@ -146,6 +150,8 @@ Directory and files operations Please see :data:`os.supports_follow_symlinks` for more information. + .. audit-event:: shutil.copystat src,dst shutil.copystat + .. versionchanged:: 3.3 Added *follow_symlinks* argument and support for Linux extended attributes. @@ -167,6 +173,10 @@ Directory and files operations To preserve all file metadata from the original, use :func:`~shutil.copy2` instead. + .. audit-event:: shutil.copyfile src,dst shutil.copy + + .. audit-event:: shutil.copymode src,dst shutil.copy + .. versionchanged:: 3.3 Added *follow_symlinks* argument. Now returns path to the newly created file. @@ -194,6 +204,10 @@ Directory and files operations Please see :func:`copystat` for more information about platform support for modifying symbolic link metadata. + .. audit-event:: shutil.copyfile src,dst shutil.copy2 + + .. audit-event:: shutil.copystat src,dst shutil.copy2 + .. versionchanged:: 3.3 Added *follow_symlinks* argument, try to copy extended file system attributes too (currently Linux only). @@ -342,6 +356,8 @@ Directory and files operations *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. + .. audit-event:: shutil.move src,dst shutil.move + .. versionchanged:: 3.3 Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's :program:`mv`. @@ -378,6 +394,8 @@ Directory and files operations See also :func:`os.chown`, the underlying function. + .. audit-event:: shutil.chown path,user,group shutil.chown + .. availability:: Unix. .. versionadded:: 3.3 @@ -629,6 +647,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. registered for that extension. In case none is found, a :exc:`ValueError` is raised. + .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive + .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 8fecc2b..5488f4a 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -91,6 +91,110 @@ The variables defined in the :mod:`signal` module are: signal. +.. data:: SIGABRT + + Abort signal from :manpage:`abort(3)`. + +.. data:: SIGALRM + + Timer signal from :manpage:`alarm(2)`. + + .. availability:: Unix. + +.. data:: SIGBREAK + + Interrupt from keyboard (CTRL + BREAK). + + .. availability:: Windows. + +.. data:: SIGBUS + + Bus error (bad memory access). + + .. availability:: Unix. + +.. data:: SIGCHLD + + Child process stopped or terminated. + + .. availability:: Windows. + +.. data:: SIGCLD + + Alias to :data:`SIGCHLD`. + +.. data:: SIGCONT + + Continue the process if it is currently stopped + + .. availability:: Unix. + +.. data:: SIGFPE + + Floating-point exception. For example, division by zero. + + .. seealso:: + :exc:`ZeroDivisionError` is raised when the second argument of a division + or modulo operation is zero. + +.. data:: SIGHUP + + Hangup detected on controlling terminal or death of controlling process. + + .. availability:: Unix. + +.. data:: SIGILL + + Illegal instruction. + +.. data:: SIGINT + + Interrupt from keyboard (CTRL + C). + + Default action is to raise :exc:`KeyboardInterrupt`. + +.. data:: SIGKILL + + Kill signal. + + It cannot be caught, blocked, or ignored. + + .. availability:: Unix. + +.. data:: SIGPIPE + + Broken pipe: write to pipe with no readers. + + Default action is to ignore the signal. + + .. availability:: Unix. + +.. data:: SIGSEGV + + Segmentation fault: invalid memory reference. + +.. data:: SIGTERM + + Termination signal. + +.. data:: SIGUSR1 + + User-defined signal 1. + + .. availability:: Unix. + +.. data:: SIGUSR2 + + User-defined signal 2. + + .. availability:: Unix. + +.. data:: SIGWINCH + + Window resize signal. + + .. availability:: Unix. + .. data:: SIG* All the signal numbers are defined symbolically. For example, the hangup signal @@ -264,6 +368,8 @@ The :mod:`signal` module defines the following functions: If *signalnum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if the target thread is still running. + .. audit-event:: signal.pthread_kill thread_id,signalnum signal.pthread_kill + .. availability:: Unix. See the man page :manpage:`pthread_kill(3)` for further information. @@ -295,6 +401,8 @@ The :mod:`signal` module defines the following functions: For example, ``signal.pthread_sigmask(signal.SIG_BLOCK, [])`` reads the signal mask of the calling thread. + :data:`SIGKILL` and :data:`SIGSTOP` cannot be blocked. + .. availability:: Unix. See the man page :manpage:`sigprocmask(3)` and :manpage:`pthread_sigmask(3)` for further information. diff --git a/Doc/library/site.rst b/Doc/library/site.rst index e1ca160..b424e1b 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -236,6 +236,13 @@ Module contents .. versionadded:: 3.2 +.. _site-commandline: + +Command Line Interface +---------------------- + +.. program:: site + The :mod:`site` module also provides a way to get the user directories from the command line: @@ -244,8 +251,6 @@ command line: $ python3 -m site --user-site /home/user/.local/lib/python3.3/site-packages -.. program:: site - If it is called without arguments, it will print the contents of :data:`sys.path` on the standard output, followed by the value of :data:`USER_BASE` and whether the directory exists, then the same thing for diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index ae82e43..c72f22b 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -548,7 +548,9 @@ The following functions all create :ref:`socket objects `. When :const:`SOCK_NONBLOCK` or :const:`SOCK_CLOEXEC` bit flags are applied to *type* they are cleared, and :attr:`socket.type` will not reflect them. They are still passed - to the underlying system `socket()` call. Therefore:: + to the underlying system `socket()` call. Therefore, + + :: sock = socket.socket( socket.AF_INET, diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 7c8c8d5..232c061 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -237,6 +237,8 @@ Server Objects .. method:: shutdown() Tell the :meth:`serve_forever` loop to stop and wait until it does. + :meth:`shutdown` must be called while :meth:`serve_forever` is running in a + different thread otherwise it will deadlock. .. method:: server_close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 67ea2b1..314d3a5 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -165,9 +165,10 @@ Module functions and constants that 'mytype' is the type of the column. It will try to find an entry of 'mytype' in the converters dictionary and then use the converter function found there to return the value. The column name found in :attr:`Cursor.description` - is only the first word of the column name, i. e. if you use something like - ``'as "x [datetime]"'`` in your SQL, then we will parse out everything until the - first blank for the column name: the column name would simply be "x". + does not include the type, i. e. if you use something like + ``'as "Expiration date [datetime]"'`` in your SQL, then we will parse out + everything until the first ``'['`` for the column name and strip + the preceeding space: the column name would simply be "Expiration date". .. function:: connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri]) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index bbb4c41..4142e41 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -42,7 +42,7 @@ This module provides a class, :class:`ssl.SSLSocket`, which is derived from the :class:`socket.socket` type, and provides a socket-like wrapper that also encrypts and decrypts the data going over the socket with SSL. It supports additional methods such as :meth:`getpeercert`, which retrieves the -certificate of the other side of the connection, and :meth:`cipher`,which +certificate of the other side of the connection, and :meth:`cipher`, which retrieves the cipher being used for the secure connection. For more sophisticated applications, the :class:`ssl.SSLContext` class @@ -2271,7 +2271,7 @@ Visual inspection shows that the certificate does identify the desired service (('postalCode', '03894-4801'),), (('countryName', 'US'),), (('stateOrProvinceName', 'NH'),), - (('localityName', 'Wolfeboro,'),), + (('localityName', 'Wolfeboro'),), (('organizationName', 'Python Software Foundation'),), (('commonName', 'www.python.org'),)), 'subjectAltName': (('DNS', 'www.python.org'), diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 4c7239c..026f4aa 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -734,10 +734,10 @@ of applications in statistics. :class:`NormalDist` readily solves classic probability problems. For example, given `historical data for SAT exams -`_ showing that scores -are normally distributed with a mean of 1060 and a standard deviation of 192, -determine the percentage of students with test scores between 1100 and -1200, after rounding to the nearest whole number: +`_ showing +that scores are normally distributed with a mean of 1060 and a standard +deviation of 195, determine the percentage of students with test scores +between 1100 and 1200, after rounding to the nearest whole number: .. doctest:: @@ -772,6 +772,42 @@ Carlo simulation `_: >>> quantiles(map(model, X, Y, Z)) # doctest: +SKIP [1.4591308524824727, 1.8035946855390597, 2.175091447274739] +Normal distributions can be used to approximate `Binomial +distributions `_ +when the sample size is large and when the probability of a successful +trial is near 50%. + +For example, an open source conference has 750 attendees and two rooms with a +500 person capacity. There is a talk about Python and another about Ruby. +In previous conferences, 65% of the attendees preferred to listen to Python +talks. Assuming the population preferences haven't changed, what is the +probability that the Python room will stay within its capacity limits? + +.. doctest:: + + >>> n = 750 # Sample size + >>> p = 0.65 # Preference for Python + >>> q = 1.0 - p # Preference for Ruby + >>> k = 500 # Room capacity + + >>> # Approximation using the cumulative normal distribution + >>> from math import sqrt + >>> round(NormalDist(mu=n*p, sigma=sqrt(n*p*q)).cdf(k + 0.5), 4) + 0.8402 + + >>> # Solution using the cumulative binomial distribution + >>> from math import comb, fsum + >>> round(fsum(comb(n, r) * p**r * q**(n-r) for r in range(k+1)), 4) + 0.8402 + + >>> # Approximation using a simulation + >>> from random import seed, choices + >>> seed(8675309) + >>> def trial(): + ... return choices(('Python', 'Ruby'), (p, q), k=n).count('Python') + >>> mean(trial() <= k for i in range(10_000)) + 0.8398 + Normal distributions commonly arise in machine learning problems. Wikipedia has a `nice example of a Naive Bayesian Classifier diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index be72695..8cc57c3 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -261,8 +261,10 @@ and imaginary parts. Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating point, -which is narrower than complex. Comparisons between numbers of mixed type use -the same rule. [2]_ The constructors :func:`int`, :func:`float`, and +which is narrower than complex. A comparison between numbers of different types +behaves as though the exact values of those numbers were being compared. [2]_ + +The constructors :func:`int`, :func:`float`, and :func:`complex` can be used to produce numbers of a specific type. All numeric types (except complex) support the following operations (for priorities of @@ -2399,7 +2401,7 @@ data and are closely related to string objects in a variety of other ways. A reverse conversion function exists to transform a bytes object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2493,7 +2495,7 @@ objects. A reverse conversion function exists to transform a bytearray object into its hexadecimal representation. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the instance. @@ -2503,6 +2505,11 @@ objects. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`bytearray.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + Since bytearray objects are sequences of integers (akin to a list), for a bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytearray object of length 1. (This contrasts with text strings, where @@ -3649,7 +3656,7 @@ copying. in-memory Fortran order is preserved. For non-contiguous views, the data is converted to C first. *order=None* is the same as *order='C'*. - .. method:: hex() + .. method:: hex([sep[, bytes_per_sep]]) Return a string object containing two hexadecimal digits for each byte in the buffer. :: @@ -3660,6 +3667,11 @@ copying. .. versionadded:: 3.5 + .. versionchanged:: 3.8 + Similar to :meth:`bytes.hex`, :meth:`memoryview.hex` now supports + optional *sep* and *bytes_per_sep* parameters to insert separators + between bytes in the hex output. + .. method:: tolist() Return the data in the buffer as a list of elements. :: @@ -4326,6 +4338,8 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: Return a reverse iterator over the keys of the dictionary. This is a shortcut for ``reversed(d.keys())``. + .. versionadded:: 3.8 + .. method:: setdefault(key[, default]) If *key* is in the dictionary, return its value. If not, insert *key* diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e2983db..fa906f7 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -302,9 +302,9 @@ specification is to be interpreted. Most built-in types implement the following options for format specifications, although some of the formatting options are only supported by the numeric types. -A general convention is that an empty format string (``""``) produces +A general convention is that an empty format specification produces the same result as if you had called :func:`str` on the value. A -non-empty format string typically modifies the result. +non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: @@ -415,8 +415,9 @@ error. .. versionchanged:: 3.6 Added the ``'_'`` option (see also :pep:`515`). -*width* is a decimal integer defining the minimum field width. If not -specified, then the field width will be determined by the content. +*width* is a decimal integer defining the minimum total field width, +including any prefixes, separators, and other formatting characters. +If not specified, then the field width will be determined by the content. When no explicit alignment is given, preceding the *width* field by a zero (``'0'``) character enables diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ea12cd1..cce7da1 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -355,14 +355,20 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. + An example of passing some arguments to an external program + as a sequence is:: + + Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."]) + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. .. note:: - :meth:`shlex.split` can be useful when determining the correct - tokenization for *args*, especially in complex cases:: + It may not be obvious how to break a shell command into a sequence of arguments, + especially in complex cases. :meth:`shlex.split` can illustrate how to + determine the correct tokenization for *args*:: >>> import shlex, subprocess >>> command_line = input() diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 1cf19b8..d3473de 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -343,6 +343,8 @@ always available. .. versionadded:: 3.7 __breakpointhook__ + .. versionadded:: 3.8 + __unraisablehook__ .. function:: exc_info() @@ -479,8 +481,8 @@ always available. +---------------------+----------------+--------------------------------------------------+ | attribute | float.h macro | explanation | +=====================+================+==================================================+ - | :const:`epsilon` | DBL_EPSILON | difference between 1 and the least value greater | - | | | than 1 that is representable as a float | + | :const:`epsilon` | DBL_EPSILON | difference between 1.0 and the least value | + | | | greater than 1.0 that is representable as a float| +---------------------+----------------+--------------------------------------------------+ | :const:`dig` | DBL_DIG | maximum number of decimal digits that can be | | | | faithfully represented in a float; see below | @@ -488,20 +490,20 @@ always available. | :const:`mant_dig` | DBL_MANT_DIG | float precision: the number of base-``radix`` | | | | digits in the significand of a float | +---------------------+----------------+--------------------------------------------------+ - | :const:`max` | DBL_MAX | maximum representable finite float | + | :const:`max` | DBL_MAX | maximum representable positive finite float | +---------------------+----------------+--------------------------------------------------+ - | :const:`max_exp` | DBL_MAX_EXP | maximum integer e such that ``radix**(e-1)`` is | + | :const:`max_exp` | DBL_MAX_EXP | maximum integer *e* such that ``radix**(e-1)`` is| | | | a representable finite float | +---------------------+----------------+--------------------------------------------------+ - | :const:`max_10_exp` | DBL_MAX_10_EXP | maximum integer e such that ``10**e`` is in the | + | :const:`max_10_exp` | DBL_MAX_10_EXP | maximum integer *e* such that ``10**e`` is in the| | | | range of representable finite floats | +---------------------+----------------+--------------------------------------------------+ - | :const:`min` | DBL_MIN | minimum positive normalized float | + | :const:`min` | DBL_MIN | minimum representable positive *normalized* float| +---------------------+----------------+--------------------------------------------------+ - | :const:`min_exp` | DBL_MIN_EXP | minimum integer e such that ``radix**(e-1)`` is | + | :const:`min_exp` | DBL_MIN_EXP | minimum integer *e* such that ``radix**(e-1)`` is| | | | a normalized float | +---------------------+----------------+--------------------------------------------------+ - | :const:`min_10_exp` | DBL_MIN_10_EXP | minimum integer e such that ``10**e`` is a | + | :const:`min_10_exp` | DBL_MIN_10_EXP | minimum integer *e* such that ``10**e`` is a | | | | normalized float | +---------------------+----------------+--------------------------------------------------+ | :const:`radix` | FLT_RADIX | radix of exponent representation | diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 7151527..d264a33 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -31,6 +31,8 @@ The module defines the following functions: If :func:`openlog` has not been called prior to the call to :func:`syslog`, ``openlog()`` will be called with no arguments. + .. audit-event:: syslog.syslog priority,message syslog.syslog + .. function:: openlog([ident[, logoption[, facility]]]) @@ -45,6 +47,8 @@ The module defines the following functions: keyword argument (default is :const:`LOG_USER`) sets the default facility for messages which do not have a facility explicitly encoded. + .. audit-event:: syslog.openlog ident,logoption,facility syslog.openlog + .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was required. The default for *ident* was dependent on the system libraries, @@ -60,6 +64,8 @@ The module defines the following functions: :func:`openlog` hasn't already been called), and *ident* and other :func:`openlog` parameters are reset to defaults. + .. audit-event:: syslog.closelog "" syslog.closelog + .. function:: setlogmask(maskpri) @@ -70,6 +76,8 @@ The module defines the following functions: ``LOG_UPTO(pri)`` calculates the mask for all priorities up to and including *pri*. + .. audit-event:: syslog.setlogmask maskpri syslog.setlogmask + The module defines the following constants: Priority levels (high to low): diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 0f11ef4..1683710 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -239,7 +239,7 @@ hyphenated words; only then will long words be broken if necessary, unless :attr:`fix_sentence_endings` is false by default. Since the sentence detection algorithm relies on ``string.lowercase`` for - the definition of "lowercase letter," and a convention of using two spaces + the definition of "lowercase letter", and a convention of using two spaces after a period to separate sentences on the same line, it is specific to English-language texts. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 93ea4bd..f4b58d3 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -489,6 +489,7 @@ All methods are executed atomically. There is no return value. .. method:: locked() + Return true if the lock is acquired. diff --git a/Doc/library/time.rst b/Doc/library/time.rst index e628ac4..6842e90 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -218,7 +218,6 @@ Functions Supported clock names and the corresponding functions to read their value are: - * ``'clock'``: :func:`time.clock` * ``'monotonic'``: :func:`time.monotonic` * ``'perf_counter'``: :func:`time.perf_counter` * ``'process_time'``: :func:`time.process_time` diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index ef7a4e4..46fa62c 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -251,7 +251,8 @@ quotes and using leading spaces. Multiple :option:`-s` options are treated similarly. If :option:`-n` is not given, a suitable number of loops is calculated by trying -successive powers of 10 until the total time is at least 0.2 seconds. +increasing numbers from the sequence 1, 2, 5, 10, 20, 50, ... until the total +time is at least 0.2 seconds. :func:`default_timer` measurements can be affected by other programs running on the same machine, so the best thing to do when accurate timing is necessary is diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 1777929..dab8f0f 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -87,7 +87,7 @@ the :mod:`tokenize` module. now tokenized as :data:`NAME` tokens. .. versionchanged:: 3.8 - Added :data:`TYPE_COMMENT`. + Added :data:`TYPE_COMMENT`, :data:`TYPE_IGNORE`, :data:`COLONEQUAL`. Added :data:`AWAIT` and :data:`ASYNC` tokens back (they're needed to support parsing older Python versions for :func:`ast.parse` with ``feature_version`` set to 6 or lower). diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index b208ba4..11f569d 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -13,7 +13,7 @@ The :mod:`tokenize` module provides a lexical scanner for Python source code, implemented in Python. The scanner in this module returns comments as tokens -as well, making it useful for implementing "pretty-printers," including +as well, making it useful for implementing "pretty-printers", including colorizers for on-screen displays. To simplify token stream handling, all :ref:`operator ` and @@ -278,3 +278,22 @@ The exact token type names can be displayed using the :option:`-e` option: 4,10-4,11: RPAR ')' 4,11-4,12: NEWLINE '\n' 5,0-5,0: ENDMARKER '' + +Example of tokenizing a file programmatically, reading unicode +strings instead of bytes with :func:`generate_tokens`:: + + import tokenize + + with tokenize.open('hello.py') as f: + tokens = tokenize.generate_tokens(f.readline) + for token in tokens: + print(token) + +Or reading bytes directly with :func:`.tokenize`:: + + import tokenize + + with open('hello.py', 'rb') as f: + tokens = tokenize.tokenize(f.readline) + for token in tokens: + print(token) diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index 2d327c0..000c0ee 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -202,10 +202,8 @@ ignoring ```` and ```` files:: print("Top %s lines" % limit) for index, stat in enumerate(top_stats[:limit], 1): frame = stat.traceback[0] - # replace "/path/to/module/file.py" with "module/file.py" - filename = os.sep.join(frame.filename.split(os.sep)[-2:]) print("#%s: %s:%s: %.1f KiB" - % (index, filename, frame.lineno, stat.size / 1024)) + % (index, frame.filename, frame.lineno, stat.size / 1024)) line = linecache.getline(frame.filename, frame.lineno).strip() if line: print(' %s' % line) diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 7f9f0c3..fed8504 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1051,6 +1051,11 @@ Filling Fill the shape drawn after the last call to :func:`begin_fill`. + Whether or not overlap regions for self-intersecting polygons + or multiple shapes are filled depends on the operating system graphics, + type of overlap, and number of overlaps. For example, the Turtle star + above may be either all yellow or have some white regions. + .. doctest:: :skipif: _tkinter is None diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 9393f9e..3529c2b 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -132,7 +132,7 @@ Standard names are defined for the following types: .. versionadded:: 3.6 -.. data:: CodeType +.. class:: CodeType(**kwargs) .. index:: builtin: compile @@ -143,6 +143,12 @@ Standard names are defined for the following types: Note that the audited arguments may not match the names or positions required by the initializer. + .. method:: CodeType.replace(**kwargs) + + Return a copy of the code object with new values for the specified fields. + + .. versionadded:: 3.8 + .. data:: CellType The type for cell objects: such objects are used as containers for diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 323dac2..7269e18 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -959,7 +959,7 @@ The module defines the following classes, functions and decorators: .. versionchanged:: 3.6.1 Added support for default values, methods, and docstrings. - .. versionchanged:: 3.8 + .. deprecated-removed:: 3.8 3.9 Deprecated the ``_field_types`` attribute in favor of the more standard ``__annotations__`` attribute which has the same information. @@ -996,8 +996,20 @@ The module defines the following classes, functions and decorators: Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) - See :pep:`589` for more examples and detailed rules of using ``TypedDict`` - with type checkers. + By default, all keys must be present in a TypedDict. It is possible + to override this by specifying totality. + Usage:: + + class point2D(TypedDict, total=False): + x: int + y: int + + This means that a point2D TypedDict can have any of the keys omitted. A type + checker is only expected to support a literal False or True as the value of + the total argument. True is the default, and makes all items defined in the + class body be required. + + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index ebfaf7d..e92f554 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -915,6 +915,7 @@ object:: >>> mock.async_foo + .. versionadded:: 3.8 .. method:: assert_awaited() diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index a559d09..d9f080a 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -910,10 +910,10 @@ Test cases .. versionadded:: 3.1 - .. method:: assertIn(first, second, msg=None) - assertNotIn(first, second, msg=None) + .. method:: assertIn(member, container, msg=None) + assertNotIn(member, container, msg=None) - Test that *first* is (or is not) in *second*. + Test that *member* is (or is not) in *container*. .. versionadded:: 3.1 diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index b3c8e35..2dbe5e3 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -327,12 +327,6 @@ objects. types. -.. exception:: ReferenceError - - Exception raised when a proxy object is used but the underlying object has been - collected. This is the same as the standard :exc:`ReferenceError` exception. - - .. seealso:: :pep:`205` - Weak References diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index 7283152..fb40a2b 100644 --- a/Doc/library/zipapp.rst +++ b/Doc/library/zipapp.rst @@ -198,7 +198,7 @@ Pack up a directory into an archive, and run it. The same can be done using the :func:`create_archive` function:: >>> import zipapp - >>> zipapp.create_archive('myapp.pyz', 'myapp') + >>> zipapp.create_archive('myapp', 'myapp.pyz') To make the application directly executable on POSIX, specify an interpreter to use. diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index e8a2530..97da6ca 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -494,6 +494,12 @@ Path objects are traversable using the ``/`` operator. Invoke :meth:`ZipFile.open` on the current path. Accepts the same arguments as :meth:`ZipFile.open`. + .. caution:: + + The signature on this function changes in an incompatible way + in Python 3.9. For a future-compatible version, consider using + the third-party zipp.Path package (3.0 or later). + .. method:: Path.iterdir() Enumerate the children of the current directory. diff --git a/Doc/license.rst b/Doc/license.rst index 810d2e6..472a5cf 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2019 Python Software Foundation; All Rights + copyright, i.e., "Copyright © 2001-2020 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/Doc/make.bat b/Doc/make.bat index 9687d0f..a2f64ff 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -54,9 +54,9 @@ if not exist "%HTMLHELP%" ( ) :skiphhcsearch -if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v +if not defined DISTVERSION for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v -if "%BUILDDIR%" EQU "" set BUILDDIR=build +if not defined BUILDDIR set BUILDDIR=build rem Targets that don't require sphinx-build if "%1" EQU "" goto help @@ -131,7 +131,7 @@ if exist ..\Misc\NEWS ( ) ) -if NOT "%PAPER%" == "" ( +if defined PAPER ( set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% ) if "%1" EQU "htmlhelp" ( diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 988eec6..feaf310 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -90,8 +90,8 @@ The :keyword:`!if` statement The :keyword:`if` statement is used for conditional execution: .. productionlist:: - if_stmt: "if" `expression` ":" `suite` - : ("elif" `expression` ":" `suite`)* + if_stmt: "if" `assignment_expression` ":" `suite` + : ("elif" `assignment_expression` ":" `suite`)* : ["else" ":" `suite`] It selects exactly one of the suites by evaluating the expressions one by one @@ -116,7 +116,7 @@ The :keyword:`while` statement is used for repeated execution as long as an expression is true: .. productionlist:: - while_stmt: "while" `expression` ":" `suite` + while_stmt: "while" `assignment_expression` ":" `suite` : ["else" ":" `suite`] This repeatedly tests the expression and, if it is true, executes the first @@ -399,6 +399,8 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo #. The context expression (the expression given in the :token:`with_item`) is evaluated to obtain a context manager. +#. The context manager's :meth:`__enter__` is loaded for later use. + #. The context manager's :meth:`__exit__` is loaded for later use. #. The context manager's :meth:`__enter__` method is invoked. @@ -430,17 +432,41 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo value from :meth:`__exit__` is ignored, and execution proceeds at the normal location for the kind of exit that was taken. +The following code:: + + with EXPRESSION as TARGET: + SUITE + +is semantically equivalent to:: + + manager = (EXPRESSION) + enter = type(manager).__enter__ + exit = type(manager).__exit__ + value = enter(manager) + hit_except = False + + try: + TARGET = value + SUITE + except: + hit_except = True + if not exit(manager, *sys.exc_info()): + raise + finally: + if not hit_except: + exit(manager, None, None, None) + With more than one item, the context managers are processed as if multiple :keyword:`with` statements were nested:: with A() as a, B() as b: - suite + SUITE -is equivalent to :: +is semantically equivalent to:: with A() as a: with B() as b: - suite + SUITE .. versionchanged:: 3.1 Support for multiple context expressions. @@ -772,24 +798,25 @@ iterators. The following code:: async for TARGET in ITER: - BLOCK + SUITE else: - BLOCK2 + SUITE2 Is semantically equivalent to:: iter = (ITER) iter = type(iter).__aiter__(iter) running = True + while running: try: TARGET = await type(iter).__anext__(iter) except StopAsyncIteration: running = False else: - BLOCK + SUITE else: - BLOCK2 + SUITE2 See also :meth:`__aiter__` and :meth:`__anext__` for details. @@ -811,23 +838,27 @@ able to suspend execution in its *enter* and *exit* methods. The following code:: - async with EXPR as VAR: - BLOCK + async with EXPRESSION as TARGET: + SUITE -Is semantically equivalent to:: +is semantically equivalent to:: - mgr = (EXPR) - aexit = type(mgr).__aexit__ - aenter = type(mgr).__aenter__(mgr) + manager = (EXPRESSION) + aexit = type(manager).__aexit__ + aenter = type(manager).__aenter__ + value = await aenter(manager) + hit_except = False - VAR = await aenter try: - BLOCK + TARGET = value + SUITE except: - if not await aexit(mgr, *sys.exc_info()): + hit_except = True + if not await aexit(manager, *sys.exc_info()): raise - else: - await aexit(mgr, None, None, None) + finally: + if not hit_except: + await aexit(manager, None, None, None) See also :meth:`__aenter__` and :meth:`__aexit__` for details. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 46d50ad..d364e61 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -17,7 +17,7 @@ Objects, values and types :dfn:`Objects` are Python's abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in -conformance to Von Neumann's model of a "stored program computer," code is also +conformance to Von Neumann's model of a "stored program computer", code is also represented by objects.) .. index:: @@ -420,6 +420,11 @@ Mappings equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index the same dictionary entry. + Dictionaries preserve insertion order, meaning that keys will be produced + in the same order they were added sequentially over the dictionary. + Replacing an existing key does not change the order, however removing a key + and re-inserting it will add it to the end instead of keeping its old place. + Dictionaries are mutable; they can be created by the ``{...}`` notation (see section :ref:`dict`). @@ -431,6 +436,11 @@ Mappings additional examples of mapping types, as does the :mod:`collections` module. + .. versionchanged:: 3.7 + Dictionaries did not preserve insertion order in versions of Python before 3.6. + In CPython 3.6, insertion order was preserved, but it was considered + an implementation detail at that time rather than a language guarantee. + Callable types .. index:: object: callable @@ -925,8 +935,8 @@ Internal types the first line number of the function; :attr:`co_lnotab` is a string encoding the mapping from bytecode offsets to line numbers (for details see the source code of the interpreter); :attr:`co_stacksize` is the - required stack size (including local variables); :attr:`co_flags` is an - integer encoding a number of flags for the interpreter. + required stack size; :attr:`co_flags` is an integer encoding a number + of flags for the interpreter. .. index:: object: generator @@ -1945,7 +1955,10 @@ Preparing the class namespace Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the -additional keyword arguments, if any, come from the class definition). +additional keyword arguments, if any, come from the class definition). The +``__prepare__`` method should be implemented as a :func:`classmethod`. The +namespace returned by ``__prepare__`` is passed in to ``__new__``, but when +the final class object is created the namespace is copied into a new ``dict``. If the metaclass has no ``__prepare__`` attribute, then the class namespace is initialised as an empty ordered mapping. @@ -2331,7 +2344,7 @@ left undefined. object.__rfloordiv__(self, other) object.__rmod__(self, other) object.__rdivmod__(self, other) - object.__rpow__(self, other) + object.__rpow__(self, other[, modulo]) object.__rlshift__(self, other) object.__rrshift__(self, other) object.__rand__(self, other) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index d9db33a..8036a49 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -28,7 +28,7 @@ Arithmetic conversions .. index:: pair: arithmetic; conversion When a description of an arithmetic operator below uses the phrase "the numeric -arguments are converted to a common type," this means that the operator +arguments are converted to a common type", this means that the operator implementation for built-in types works as follows: * If either argument is a complex number, the other is converted to complex; @@ -178,7 +178,7 @@ called "displays", each of them in two flavors: Common syntax elements for comprehensions are: .. productionlist:: - comprehension: `expression` `comp_for` + comprehension: `assignment_expression` `comp_for` comp_for: ["async"] "for" `target_list` "in" `or_test` [`comp_iter`] comp_iter: `comp_for` | `comp_if` comp_if: "if" `expression_nocond` [`comp_iter`] @@ -911,7 +911,8 @@ series of :term:`arguments `: : ["," `keywords_arguments`] : | `starred_and_keywords` ["," `keywords_arguments`] : | `keywords_arguments` - positional_arguments: ["*"] `expression` ("," ["*"] `expression`)* + positional_arguments: positional_item ("," positional_item)* + positional_item: `assignment_expression` | "*" `expression` starred_and_keywords: ("*" `expression` | `keyword_item`) : ("," "*" `expression` | "," `keyword_item`)* keywords_arguments: (`keyword_item` | "**" `expression`) @@ -1421,8 +1422,9 @@ built-in types. The not-a-number values ``float('NaN')`` and ``decimal.Decimal('NaN')`` are special. Any ordered comparison of a number to a not-a-number value is false. A counter-intuitive implication is that not-a-number values are not equal to - themselves. For example, if ``x = float('NaN')``, ``3 < x``, ``x < 3``, ``x - == x``, ``x != x`` are all false. This behavior is compliant with IEEE 754. + themselves. For example, if ``x = float('NaN')``, ``3 < x``, ``x < 3`` and + ``x == x`` are all false, while ``x != x`` is true. This behavior is + compliant with IEEE 754. * ``None`` and ``NotImplemented`` are singletons. :PEP:`8` advises that comparisons for singletons should always be done with ``is`` or ``is not``, @@ -1642,6 +1644,17 @@ returns a boolean value regardless of the type of its argument (for example, ``not 'foo'`` produces ``False`` rather than ``''``.) +Assignment expressions +====================== + +.. productionlist:: + assignment_expression: [`identifier` ":="] `expression` + +.. TODO: BPO-39868 + +See :pep:`572` for more details about assignment expressions. + + .. _if_expr: Conditional expressions @@ -1711,7 +1724,7 @@ Expression lists expression_list: `expression` ("," `expression`)* [","] starred_list: `starred_item` ("," `starred_item`)* [","] starred_expression: `expression` | (`starred_item` ",")* [`starred_item`] - starred_item: `expression` | "*" `or_expr` + starred_item: `assignment_expression` | "*" `or_expr` .. index:: object: tuple diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index c6f6d03..1c98aab 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -855,7 +855,7 @@ module. ``find_spec()`` returns a fully populated spec for the module. 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 +:term:`portion`, the path entry finder sets "loader" on the spec to ``None`` and "submodule_search_locations" to a list containing the portion. diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index c0e13b5..844bd7c 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -376,11 +376,11 @@ characters: information on this convention. ``__*__`` - System-defined names. These names are defined by the interpreter and its - implementation (including the standard library). Current system names are - discussed in the :ref:`specialnames` section and elsewhere. More will likely - be defined in future versions of Python. *Any* use of ``__*__`` names, in - any context, that does not follow explicitly documented use, is subject to + System-defined names, informally known as "dunder" names. These names are + defined by the interpreter and its implementation (including the standard library). + Current system names are discussed in the :ref:`specialnames` section and elsewhere. + More will likely be defined in future versions of Python. *Any* use of ``__*__`` names, + in any context, that does not follow explicitly documented use, is subject to breakage without warning. ``__*`` @@ -685,6 +685,11 @@ strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. +.. versionchanged:: 3.7 + Prior to Python 3.7, an :keyword:`await` expression and comprehensions + containing an :keyword:`async for` clause were illegal in the expressions + in formatted string literals due to a problem with the implementation. + If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index d9364d6..987c63a 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -40,7 +40,7 @@ Python in one of various formats, follow one of links in this table.

These archives contain all the content in the documentation.

-

HTML Help (.chm) files are made available in the "Windows" section +

HTML Help (.chm) files are made available in the "Windows" section on the Python download page.

diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index c51dcc7..4730a5f 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -7,7 +7,7 @@
  • {% trans %}Python 3.7 (stable){% endtrans %}
  • {% trans %}Python 3.6 (security-fixes){% endtrans %}
  • {% trans %}Python 3.5 (security-fixes){% endtrans %}
  • -
  • {% trans %}Python 2.7 (stable){% endtrans %}
  • +
  • {% trans %}Python 2.7 (EOL){% endtrans %}
  • {% trans %}All versions{% endtrans %}
  • diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 0c0dca9..06bdd0d 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -143,10 +143,10 @@ language definition is evolving towards static name resolution, at "compile" time, so don't rely on dynamic name resolution! (In fact, local variables are already determined statically.) -A special quirk of Python is that -- if no :keyword:`global` statement is in -effect -- assignments to names always go into the innermost scope. Assignments -do not copy data --- they just bind names to objects. The same is true for -deletions: the statement ``del x`` removes the binding of ``x`` from the +A special quirk of Python is that -- if no :keyword:`global` or :keyword:`nonlocal` +statement is in effect -- assignments to names always go into the innermost scope. +Assignments do not copy data --- they just bind names to objects. The same is true +for deletions: the statement ``del x`` removes the binding of ``x`` from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, :keyword:`import` statements and function definitions bind the module or function name in the local scope. @@ -323,7 +323,7 @@ Instance Objects Now what can we do with instance objects? The only operations understood by instance objects are attribute references. There are two kinds of valid -attribute names, data attributes and methods. +attribute names: data attributes and methods. *data attributes* correspond to "instance variables" in Smalltalk, and to "data members" in C++. Data attributes need not be declared; like local variables, diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 7dfd33a..f05f5ed 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -142,7 +142,7 @@ the list, thus saving space. We say such an object is :term:`iterable`, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that -the :keyword:`for` statement is such a construct, while an example of function +the :keyword:`for` statement is such a construct, while an example of a function that takes an iterable is :func:`sum`:: >>> sum(range(4)) # 0 + 1 + 2 + 3 diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 2f7afb0..0edb73a 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -676,9 +676,10 @@ to a variable. For example, :: 'Trondheim' Note that in Python, unlike C, assignment inside expressions must be done -explicitly with the walrus operator ``:=``. This avoids a common class of -problems encountered in C programs: typing ``=`` in an expression when ``==`` -was intended. +explicitly with the +:ref:`walrus operator ` ``:=``. +This avoids a common class of problems encountered in C programs: typing ``=`` +in an expression when ``==`` was intended. .. _tut-comparing: diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 4bc7184..27c67c6 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -341,15 +341,33 @@ example:: File "", line 2, in KeyboardInterrupt -If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs: - -* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed. - -* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution. - -* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause. +If a :keyword:`finally` clause is present, the :keyword:`!finally` +clause will execute as the last task before the :keyword:`try` +statement completes. The :keyword:`!finally` clause runs whether or +not the :keyword:`!try` statement produces an exception. The following +points discuss more complex cases when an exception occurs: + +* If an exception occurs during execution of the :keyword:`!try` + clause, the exception may be handled by an :keyword:`except` + clause. If the exception is not handled by an :keyword:`!except` + clause, the exception is re-raised after the :keyword:`!finally` + clause has been executed. + +* An exception could occur during execution of an :keyword:`!except` + or :keyword:`!else` clause. Again, the exception is re-raised after + the :keyword:`!finally` clause has been executed. + +* If the :keyword:`!try` statement reaches a :keyword:`break`, + :keyword:`continue` or :keyword:`return` statement, the + :keyword:`!finally` clause will execute just prior to the + :keyword:`!break`, :keyword:`!continue` or :keyword:`!return` + statement's execution. + +* If a :keyword:`!finally` clause includes a :keyword:`!return` + statement, the returned value will be the one from the + :keyword:`!finally` clause's :keyword:`!return` statement, not the + value from the :keyword:`!try` clause's :keyword:`!return` + statement. For example:: diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index c30f6fc..d3f0400 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -109,8 +109,8 @@ source. Many standard library modules contain code that is invoked on their execution as a script. An example is the :mod:`timeit` module:: - python -mtimeit -s 'setup here' 'benchmarked code here' - python -mtimeit -h # for details + python -m timeit -s 'setup here' 'benchmarked code here' + python -m timeit -h # for details .. audit-event:: cpython.run_module module-name cmdoption-m @@ -936,8 +936,6 @@ conflict. Also available as the :option:`-X` ``utf8`` option. - .. availability:: \*nix. - .. versionadded:: 3.7 See :pep:`540` for more details. diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 1b24721..99b2a19 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -78,6 +78,17 @@ The command, if run with ``-h``, will show the available options:: particular note is that double-clicking ``python.exe`` in File Explorer will resolve the symlink eagerly and ignore the virtual environment. +.. note:: + On Microsoft Windows, it may be required to enable the ``Activate.ps1`` + script by setting the execution policy for the user. You can do this by + issuing the following PowerShell command: + + PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + + See `About Execution Policies + `_ + for more information. + The created ``pyvenv.cfg`` file also includes the ``include-system-site-packages`` key, set to ``true`` if ``venv`` is run with the ``--system-site-packages`` option, ``false`` otherwise. diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 9dc3e79..636f48d 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -602,6 +602,50 @@ existed):: C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.8 +.. _win-utf8-mode: + +UTF-8 mode +========== + +.. versionadded:: 3.7 + +Windows still uses legacy encodings for the system encoding (the ANSI Code +Page). Python uses it for the default encoding of text files (e.g. +:func:`locale.getpreferredencoding`). + +This may cause issues because UTF-8 is widely used on the internet +and most Unix systems, including WSL (Windows Subsystem for Linux). + +You can use UTF-8 mode to change the default text encoding to UTF-8. +You can enable UTF-8 mode via the ``-X utf8`` command line option, or +the ``PYTHONUTF8=1`` environment variable. See :envvar:`PYTHONUTF8` for +enabling UTF-8 mode, and :ref:`setting-envvars` for how to modify +environment variables. + +When UTF-8 mode is enabled: + +* :func:`locale.getpreferredencoding` returns ``'UTF-8'`` instead of + the system encoding. This function is used for the default text + encoding in many places, including :func:`open`, :class:`Popen`, + :meth:`Path.read_text`, etc. +* :data:`sys.stdin`, :data:`sys.stdout`, and :data:`sys.stderr` + all use UTF-8 as their text encoding. +* You can still use the system encoding via the "mbcs" codec. + +Note that adding ``PYTHONUTF8=1`` to the default environment variables +will affect all Python 3.7+ applications on your system. +If you have any Python 3.7+ applications which rely on the legacy +system encoding, it is recommended to set the environment variable +temporarily or use the ``-X utf8`` command line option. + +.. note:: + Even when UTF-8 mode is disabled, Python uses UTF-8 by default + on Windows for: + + * Console I/O including standard I/O (see :pep:`528` for details). + * The filesystem encoding (see :pep:`529` for details). + + .. _launcher: Python Launcher for Windows diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 880958d..6b8bd88 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -2,6 +2,8 @@ What's New In Python 3.0 **************************** +TEST CHANGE TO BE UNDONE + .. XXX Add trademark info for Apple, Microsoft. :Author: Guido van Rossum diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 8a70fe2..b9b5021 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -493,6 +493,11 @@ of this mode. Other Language Changes ====================== +* An :keyword:`await` expression and comprehensions containing an + :keyword:`async for` clause were illegal in the expressions in + :ref:`formatted string literals ` due to a problem with the + implementation. In Python 3.7 this restriction was lifted. + * More than 255 arguments can now be passed to a function, and a function can now have more than 255 parameters. (Contributed by Serhiy Storchaka in :issue:`12844` and :issue:`18896`.) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 546fa2d..d2db5bf 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -144,12 +144,11 @@ However, these are invalid calls:: One use case for this notation is that it allows pure Python functions to fully emulate behaviors of existing C coded functions. For example, -the built-in :func:`pow` function does not accept keyword arguments:: +the built-in :func:`divmod` function does not accept keyword arguments:: - def pow(x, y, z=None, /): - "Emulate the built in pow() function" - r = x ** y - return r if z is None else r%z + def divmod(a, b, /): + "Emulate the built in divmod() function" + return (a // b, a % b) Another use case is to preclude keyword arguments when the parameter name is not helpful. For example, the builtin :func:`len` function has @@ -727,7 +726,7 @@ csv The :class:`csv.DictReader` now returns instances of :class:`dict` instead of a :class:`collections.OrderedDict`. The tool is now faster and uses less memory while still preserving the field order. -(Contributed by Michael Seek in :issue:`34003`.) +(Contributed by Michael Selik in :issue:`34003`.) curses @@ -1942,6 +1941,12 @@ Changes in the Python API :exc:`dbm.gnu.error` or :exc:`dbm.ndbm.error`) instead of :exc:`KeyError`. (Contributed by Xiang Zhang in :issue:`33106`.) +* Simplified AST for literals. All constants will be represented as + :class:`ast.Constant` instances. Instantiating old classes ``Num``, + ``Str``, ``Bytes``, ``NameConstant`` and ``Ellipsis`` will return + an instance of ``Constant``. + (Contributed by Serhiy Storchaka in :issue:`32892`.) + * :func:`~os.path.expanduser` on Windows now prefers the :envvar:`USERPROFILE` environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. @@ -2111,7 +2116,7 @@ Changes in the C API .. code-block:: shell - gendef python38.dll > tmp.def + gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a The location of an installed :file:`pythonXY.dll` will depend on the @@ -2205,7 +2210,13 @@ Here's a summary of performance improvements since Python 3.3: Timing loop: loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3 - (Measured from the macOS 64-bit builds found at python.org) +The benchmarks were measured on an +`Intel® Core™ i7-4960HQ processor +`_ +running the macOS 64-bit builds found at +`python.org `_. +The benchmark script displays timings in nanoseconds. + Notable changes in Python 3.8.1 =============================== @@ -2216,3 +2227,18 @@ because of the behavior of the socket option ``SO_REUSEADDR`` in UDP. For more details, see the documentation for ``loop.create_datagram_endpoint()``. (Contributed by Kyle Stanley, Antoine Pitrou, and Yury Selivanov in :issue:`37228`.) + +Notable changes in Python 3.8.2 +=============================== + +Fixed a regression with the ``ignore`` callback of :func:`shutil.copytree`. +The argument types are now str and List[str] again. +(Contributed by Manuel Barkhau and Giampaolo Rodola in :issue:`39390`.) + +Notable changes in Python 3.8.3 +=============================== + +The constant values of future flags in the :mod:`__future__` module +are updated in order to prevent collision with compiler flags. Previously +``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``. +(Contributed by Batuhan Taskaya in :issue:`39562`) diff --git a/Include/code.h b/Include/code.h index 3afddd2..a1cd58f 100644 --- a/Include/code.h +++ b/Include/code.h @@ -88,19 +88,19 @@ typedef struct { #define CO_ITERABLE_COROUTINE 0x0100 #define CO_ASYNC_GENERATOR 0x0200 -/* These are no longer used. */ -#if 0 -#define CO_GENERATOR_ALLOWED 0x1000 -#endif -#define CO_FUTURE_DIVISION 0x2000 -#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */ -#define CO_FUTURE_WITH_STATEMENT 0x8000 -#define CO_FUTURE_PRINT_FUNCTION 0x10000 -#define CO_FUTURE_UNICODE_LITERALS 0x20000 - -#define CO_FUTURE_BARRY_AS_BDFL 0x40000 -#define CO_FUTURE_GENERATOR_STOP 0x80000 -#define CO_FUTURE_ANNOTATIONS 0x100000 +/* bpo-39562: These constant values are changed in Python 3.9 + to prevent collision with compiler flags. CO_FUTURE_ and PyCF_ + constants must be kept unique. PyCF_ constants can use bits from + 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */ +#define CO_FUTURE_DIVISION 0x20000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x80000 +#define CO_FUTURE_PRINT_FUNCTION 0x100000 +#define CO_FUTURE_UNICODE_LITERALS 0x200000 + +#define CO_FUTURE_BARRY_AS_BDFL 0x400000 +#define CO_FUTURE_GENERATOR_STOP 0x800000 +#define CO_FUTURE_ANNOTATIONS 0x1000000 /* This value is found in the co_cell2arg array when the associated cell variable does not correspond to an argument. */ diff --git a/Include/compile.h b/Include/compile.h index 1cda955..015584d 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -18,12 +18,18 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) #define PyCF_MASK_OBSOLETE (CO_NESTED) + +/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. + PyCF_ constants can use bits from 0x0100 to 0x10000. + CO_FUTURE_ constants use bits starting at 0x20000. */ #define PyCF_SOURCE_IS_UTF8 0x0100 #define PyCF_DONT_IMPLY_DEDENT 0x0200 #define PyCF_ONLY_AST 0x0400 #define PyCF_IGNORE_COOKIE 0x0800 #define PyCF_TYPE_COMMENTS 0x1000 #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) #ifndef Py_LIMITED_API typedef struct { diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 94b0809..e22b053 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -55,6 +55,7 @@ struct _ts { struct _ts *next; PyInterpreterState *interp; + /* Borrowed reference to the current frame (it can be NULL) */ struct _frame *frame; int recursion_depth; char overflowed; /* The stack has overflowed. Allow 50 more calls diff --git a/Include/object.h b/Include/object.h index cc98d8a..5558f65 100644 --- a/Include/object.h +++ b/Include/object.h @@ -29,7 +29,7 @@ of data it contains. An object's type is fixed when it is created. Types themselves are represented as objects; an object contains a pointer to the corresponding type object. The type itself has a type pointer pointing to the object representing the type 'type', which -contains a pointer to itself!). +contains a pointer to itself!. Objects do not float around in memory; once allocated an object keeps the same size and address. Objects that must hold variable-size data diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 6936a3f..2f6a68f 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 8 -#define PY_MICRO_VERSION 1 +#define PY_MICRO_VERSION 3 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.8.1" +#define PY_VERSION "3.8.3" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/LICENSE b/LICENSE index 9dc010d..66a3ac8 100644 --- a/LICENSE +++ b/LICENSE @@ -73,7 +73,7 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation; +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. diff --git a/Lib/__future__.py b/Lib/__future__.py index e113568..d7cb8ac 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -68,14 +68,14 @@ __all__ = ["all_feature_names"] + all_feature_names # this module. CO_NESTED = 0x0010 # nested_scopes CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000) -CO_FUTURE_DIVISION = 0x2000 # division -CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 # perform absolute imports by default -CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement -CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function -CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals -CO_FUTURE_BARRY_AS_BDFL = 0x40000 -CO_FUTURE_GENERATOR_STOP = 0x80000 # StopIteration becomes RuntimeError in generators -CO_FUTURE_ANNOTATIONS = 0x100000 # annotations become strings at runtime +CO_FUTURE_DIVISION = 0x20000 # division +CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 # perform absolute imports by default +CO_FUTURE_WITH_STATEMENT = 0x80000 # with statement +CO_FUTURE_PRINT_FUNCTION = 0x100000 # print function +CO_FUTURE_UNICODE_LITERALS = 0x200000 # unicode string literals +CO_FUTURE_BARRY_AS_BDFL = 0x400000 +CO_FUTURE_GENERATOR_STOP = 0x800000 # StopIteration becomes RuntimeError in generators +CO_FUTURE_ANNOTATIONS = 0x1000000 # annotations become strings at runtime class _Feature: def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index db6674e..e9efce7 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -211,7 +211,7 @@ def _remove_universal_flags(_config_vars): if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII) - flags = re.sub('-isysroot [^ \t]*', ' ', flags) + flags = re.sub(r'-isysroot\s*\S+', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars @@ -287,7 +287,7 @@ def _check_for_unavailable_sdk(_config_vars): # to /usr and /System/Library by either a standalone CLT # package or the CLT component within Xcode. cflags = _config_vars.get('CFLAGS', '') - m = re.search(r'-isysroot\s+(\S+)', cflags) + m = re.search(r'-isysroot\s*(\S+)', cflags) if m is not None: sdk = m.group(1) if not os.path.exists(sdk): @@ -295,7 +295,7 @@ def _check_for_unavailable_sdk(_config_vars): # Do not alter a config var explicitly overridden by env var if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] - flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags) + flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars @@ -320,7 +320,7 @@ def compiler_fixup(compiler_so, cc_args): stripArch = stripSysroot = True else: stripArch = '-arch' in cc_args - stripSysroot = '-isysroot' in cc_args + stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot')) if stripArch or 'ARCHFLAGS' in os.environ: while True: @@ -338,23 +338,34 @@ def compiler_fixup(compiler_so, cc_args): if stripSysroot: while True: - try: - index = compiler_so.index('-isysroot') + indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] + if not indices: + break + index = indices[0] + if compiler_so[index] == '-isysroot': # Strip this argument and the next one: del compiler_so[index:index+2] - except ValueError: - break + else: + # It's '-isysroot/some/path' in one arg + del compiler_so[index:index+1] # Check if the SDK that is used during compilation actually exists, # the universal build requires the usage of a universal SDK and not all # users have that installed by default. sysroot = None - if '-isysroot' in cc_args: - idx = cc_args.index('-isysroot') - sysroot = cc_args[idx+1] - elif '-isysroot' in compiler_so: - idx = compiler_so.index('-isysroot') - sysroot = compiler_so[idx+1] + argvar = cc_args + indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')] + if not indices: + argvar = compiler_so + indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] + + for idx in indices: + if argvar[idx] == '-isysroot': + sysroot = argvar[idx+1] + break + else: + sysroot = argvar[idx][len('-isysroot'):] + break if sysroot and not os.path.isdir(sysroot): from distutils import log diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index c14d8ca..ab989e5 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -140,8 +140,11 @@ __all__ = [ # Limits for the C version for compatibility 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' + # C version: compile time choice that enables the thread local context (deprecated, now always true) + 'HAVE_THREADS', + + # C version: compile time choice that enables the coroutine local context + 'HAVE_CONTEXTVAR' ] __xname__ = __name__ # sys.modules lookup (--without-threads) @@ -172,6 +175,7 @@ ROUND_05UP = 'ROUND_05UP' # Compatibility with the C version HAVE_THREADS = True +HAVE_CONTEXTVAR = True if sys.maxsize == 2**63-1: MAX_PREC = 999999999999999999 MAX_EMAX = 999999999999999999 diff --git a/Lib/argparse.py b/Lib/argparse.py index fd61bc7..2dad5f1 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2144,24 +2144,23 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - if self.allow_abbrev or not arg_string.startswith('--'): - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} - msg = _('ambiguous option: %(option)s could match %(matches)s') - self.error(msg % args) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple # if it was not found as an option, but it looks like a negative # number, it was meant to be positional @@ -2185,16 +2184,17 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # split at the '=' chars = self.prefix_chars if option_string[0] in chars and option_string[1] in chars: - if '=' in option_string: - option_prefix, explicit_arg = option_string.split('=', 1) - else: - option_prefix = option_string - explicit_arg = None - for option_string in self._option_string_actions: - if option_string.startswith(option_prefix): - action = self._option_string_actions[option_string] - tup = action, option_string, explicit_arg - result.append(tup) + if self.allow_abbrev: + if '=' in option_string: + option_prefix, explicit_arg = option_string.split('=', 1) + else: + option_prefix = option_string + explicit_arg = None + for option_string in self._option_string_actions: + if option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) # single character options can be concatenated with their arguments # but multiple character options always have to have their argument diff --git a/Lib/ast.py b/Lib/ast.py index b45f1e4..0c88bcf 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -59,11 +59,12 @@ def literal_eval(node_or_string): node_or_string = parse(node_or_string, mode='eval') if isinstance(node_or_string, Expression): node_or_string = node_or_string.body + def _raise_malformed_node(node): + raise ValueError(f'malformed node or string: {node!r}') def _convert_num(node): - if isinstance(node, Constant): - if type(node.value) in (int, float, complex): - return node.value - raise ValueError('malformed node or string: ' + repr(node)) + if not isinstance(node, Constant) or type(node.value) not in (int, float, complex): + _raise_malformed_node(node) + return node.value def _convert_signed_num(node): if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)): operand = _convert_num(node.operand) @@ -82,6 +83,8 @@ def literal_eval(node_or_string): elif isinstance(node, Set): return set(map(_convert, node.elts)) elif isinstance(node, Dict): + if len(node.keys) != len(node.values): + _raise_malformed_node(node) return dict(zip(map(_convert, node.keys), map(_convert, node.values))) elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)): @@ -408,11 +411,11 @@ class NodeTransformer(NodeVisitor): class RewriteName(NodeTransformer): def visit_Name(self, node): - return copy_location(Subscript( + return Subscript( value=Name(id='data', ctx=Load()), slice=Index(value=Str(s=node.id)), ctx=node.ctx - ), node) + ) Keep in mind that if the node you're operating on has child nodes you must either transform the child nodes yourself or call the :meth:`generic_visit` diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index bfd4011..799013d 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -547,14 +547,17 @@ class BaseEventLoop(events.AbstractEventLoop): 'asyncgen': agen }) - def run_forever(self): - """Run until stop() is called.""" - self._check_closed() + def _check_running(self): if self.is_running(): raise RuntimeError('This event loop is already running') if events._get_running_loop() is not None: raise RuntimeError( 'Cannot run the event loop while another loop is running') + + def run_forever(self): + """Run until stop() is called.""" + self._check_closed() + self._check_running() self._set_coroutine_origin_tracking(self._debug) self._thread_id = threading.get_ident() @@ -586,6 +589,7 @@ class BaseEventLoop(events.AbstractEventLoop): Return the Future's result, or raise its exception. """ self._check_closed() + self._check_running() new_task = not futures.isfuture(future) future = tasks.ensure_future(future, loop=self) diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py index e2da462..09bb171 100644 --- a/Lib/asyncio/base_tasks.py +++ b/Lib/asyncio/base_tasks.py @@ -24,11 +24,18 @@ def _task_repr_info(task): def _task_get_stack(task, limit): frames = [] - try: - # 'async def' coroutines + if hasattr(task._coro, 'cr_frame'): + # case 1: 'async def' coroutines f = task._coro.cr_frame - except AttributeError: + elif hasattr(task._coro, 'gi_frame'): + # case 2: legacy coroutines f = task._coro.gi_frame + elif hasattr(task._coro, 'ag_frame'): + # case 3: async generators + f = task._coro.ag_frame + else: + # case 4: unknown objects + f = None if f is not None: while f is not None: if limit is not None: diff --git a/Lib/asyncio/staggered.py b/Lib/asyncio/staggered.py index 27c665a..451a53a 100644 --- a/Lib/asyncio/staggered.py +++ b/Lib/asyncio/staggered.py @@ -6,7 +6,7 @@ import contextlib import typing from . import events -from . import futures +from . import exceptions as exceptions_mod from . import locks from . import tasks @@ -83,7 +83,7 @@ async def staggered_race( previous_failed: typing.Optional[locks.Event]) -> None: # Wait for the previous task to finish, or for delay seconds if previous_failed is not None: - with contextlib.suppress(futures.TimeoutError): + with contextlib.suppress(exceptions_mod.TimeoutError): # Use asyncio.wait_for() instead of asyncio.wait() here, so # that if we get cancelled at this point, Event.wait() is also # cancelled, otherwise there will be a "Task destroyed but it is diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index d8f6530..8c0a574 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1266,7 +1266,14 @@ class ThreadedChildWatcher(AbstractChildWatcher): return True def close(self): - pass + self._join_threads() + + def _join_threads(self): + """Internal: Join all non-daemon threads""" + threads = [thread for thread in list(self._threads.values()) + if thread.is_alive() and not thread.daemon] + for thread in threads: + thread.join() def __enter__(self): return self diff --git a/Lib/base64.py b/Lib/base64.py index 2be9c39..2e70223 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -82,7 +82,7 @@ def b64decode(s, altchars=None, validate=False): altchars = _bytes_from_decode_data(altchars) assert len(altchars) == 2, repr(altchars) s = s.translate(bytes.maketrans(altchars, b'+/')) - if validate and not re.match(b'^[A-Za-z0-9+/]*={0,2}$', s): + if validate and not re.fullmatch(b'[A-Za-z0-9+/]*={0,2}', s): raise binascii.Error('Non-base64 digit found') return binascii.a2b_base64(s) diff --git a/Lib/bdb.py b/Lib/bdb.py index 50d9eec..18491da 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -548,14 +548,7 @@ class Bdb: s += frame.f_code.co_name else: s += "" - if '__args__' in frame.f_locals: - args = frame.f_locals['__args__'] - else: - args = None - if args: - s += reprlib.repr(args) - else: - s += '()' + s += '()' if '__return__' in frame.f_locals: rv = frame.f_locals['__return__'] s += '->' diff --git a/Lib/code.py b/Lib/code.py index d8106ae..76000f8 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -40,7 +40,7 @@ class InteractiveInterpreter: Arguments are as for compile_command(). - One several things can happen: + One of several things can happen: 1) The input is incorrect; compile_command() raised an exception (SyntaxError or OverflowError). A syntax traceback diff --git a/Lib/codecs.py b/Lib/codecs.py index 21c45a7..7f23e97 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -905,11 +905,16 @@ def open(filename, mode='r', encoding=None, errors='strict', buffering=-1): file = builtins.open(filename, mode, buffering) if encoding is None: return file - info = lookup(encoding) - srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors) - # Add attributes to simplify introspection - srw.encoding = encoding - return srw + + try: + info = lookup(encoding) + srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors) + # Add attributes to simplify introspection + srw.encoding = encoding + return srw + except: + file.close() + raise def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index cadf1c7..a78a47c 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -695,6 +695,13 @@ class Counter(dict): # # To strip negative and zero counts, add-in an empty counter: # c += Counter() + # + # Rich comparison operators for multiset subset and superset tests + # are deliberately omitted due to semantic conflicts with the + # existing inherited dict equality method. Subset and superset + # semantics ignore zero counts and require that p≤q ∧ p≥q → p=q; + # however, that would not be the case for p=Counter(a=1, b=0) + # and q=Counter(a=1) where the dictionaries are not equal. def __add__(self, other): '''Add counts from two counters. diff --git a/Lib/compileall.py b/Lib/compileall.py index 49306d9..bfac8ef 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -41,7 +41,7 @@ def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0): else: dfile = None if not os.path.isdir(fullname): - yield fullname + yield fullname, ddir elif (maxlevels > 0 and name != os.curdir and name != os.pardir and os.path.isdir(fullname) and not os.path.islink(fullname)): yield from _walk_dir(fullname, ddir=dfile, @@ -76,28 +76,33 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, from concurrent.futures import ProcessPoolExecutor except ImportError: workers = 1 - files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels, - ddir=ddir) + files_and_ddirs = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels, + ddir=ddir) success = True if workers != 1 and ProcessPoolExecutor is not None: # If workers == 0, let ProcessPoolExecutor choose workers = workers or None with ProcessPoolExecutor(max_workers=workers) as executor: - results = executor.map(partial(compile_file, - ddir=ddir, force=force, - rx=rx, quiet=quiet, - legacy=legacy, - optimize=optimize, - invalidation_mode=invalidation_mode), - files) + results = executor.map( + partial(_compile_file_tuple, + force=force, rx=rx, quiet=quiet, + legacy=legacy, optimize=optimize, + invalidation_mode=invalidation_mode, + ), + files_and_ddirs) success = min(results, default=True) else: - for file in files: - if not compile_file(file, ddir, force, rx, quiet, + for file, dfile in files_and_ddirs: + if not compile_file(file, dfile, force, rx, quiet, legacy, optimize, invalidation_mode): success = False return success +def _compile_file_tuple(file_and_dfile, **kwargs): + """Needs to be toplevel for ProcessPoolExecutor.""" + file, dfile = file_and_dfile + return compile_file(file, dfile, **kwargs) + def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None): diff --git a/Lib/copy.py b/Lib/copy.py index f53cd8c..41873f2 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -107,7 +107,7 @@ _copy_dispatch = d = {} def _copy_immutable(x): return x for t in (type(None), int, float, bool, complex, str, tuple, - bytes, frozenset, type, range, slice, + bytes, frozenset, type, range, slice, property, types.BuiltinFunctionType, type(Ellipsis), type(NotImplemented), types.FunctionType, weakref.ref): d[t] = _copy_immutable @@ -195,6 +195,7 @@ d[type] = _deepcopy_atomic d[types.BuiltinFunctionType] = _deepcopy_atomic d[types.FunctionType] = _deepcopy_atomic d[weakref.ref] = _deepcopy_atomic +d[property] = _deepcopy_atomic def _deepcopy_list(x, memo, deepcopy=deepcopy): y = [] diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 9b97d80..a62044e 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -158,8 +158,11 @@ class LoaderTest(unittest.TestCase): # Relative path (but not just filename) should succeed should_pass("WinDLL('./_sqlite3.dll')") - # Insecure load flags should succeed - should_pass("WinDLL('_sqlite3.dll', winmode=0)") + # XXX: This test has started failing on Azure Pipelines CI. See + # bpo-40214 for more information. + if 0: + # Insecure load flags should succeed + should_pass("WinDLL('_sqlite3.dll', winmode=0)") # Full path load without DLL_LOAD_DIR shouldn't find dependency should_fail("WinDLL(nt._getfullpathname('_sqlite3.dll'), " + diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 19c4430..cdbaa7f 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -571,6 +571,7 @@ class StructureTestCase(unittest.TestCase): self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab, 0x3210, 0x7654, 0xba98, 0xfedc]) + @unittest.skipIf(True, 'Test disabled for now - see bpo-16575/bpo-16576') def test_union_by_value(self): # See bpo-16575 @@ -651,7 +652,7 @@ class StructureTestCase(unittest.TestCase): self.assertEqual(test5.nested.an_int, 0) self.assertEqual(test5.another_int, 0) - #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390') + @unittest.skipIf(True, 'Test disabled for now - see bpo-16575/bpo-16576') def test_bitfield_by_value(self): # See bpo-16576 diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index e8e4b71..03a5986 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -97,28 +97,11 @@ PLAT_SPEC_TO_RUNTIME = { } def _find_vcvarsall(plat_spec): + # bpo-38597: Removed vcruntime return value _, best_dir = _find_vc2017() - vcruntime = None - - if plat_spec in PLAT_SPEC_TO_RUNTIME: - vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec] - else: - vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' - - if best_dir: - vcredist = os.path.join(best_dir, "..", "..", "redist", "MSVC", "**", - vcruntime_plat, "Microsoft.VC14*.CRT", "vcruntime140.dll") - try: - import glob - vcruntime = glob.glob(vcredist, recursive=True)[-1] - except (ImportError, OSError, LookupError): - vcruntime = None if not best_dir: best_version, best_dir = _find_vc2015() - if best_version: - vcruntime = os.path.join(best_dir, 'redist', vcruntime_plat, - "Microsoft.VC140.CRT", "vcruntime140.dll") if not best_dir: log.debug("No suitable Visual C++ version found") @@ -129,11 +112,7 @@ def _find_vcvarsall(plat_spec): log.debug("%s cannot be found", vcvarsall) return None, None - if not vcruntime or not os.path.isfile(vcruntime): - log.debug("%s cannot be found", vcruntime) - vcruntime = None - - return vcvarsall, vcruntime + return vcvarsall, None def _get_vc_env(plat_spec): if os.getenv("DISTUTILS_USE_SDK"): @@ -142,7 +121,7 @@ def _get_vc_env(plat_spec): for key, value in os.environ.items() } - vcvarsall, vcruntime = _find_vcvarsall(plat_spec) + vcvarsall, _ = _find_vcvarsall(plat_spec) if not vcvarsall: raise DistutilsPlatformError("Unable to find vcvarsall.bat") @@ -163,8 +142,6 @@ def _get_vc_env(plat_spec): if key and value } - if vcruntime: - env['py_vcruntime_redist'] = vcruntime return env def _find_exe(exe, paths=None): @@ -194,12 +171,6 @@ PLAT_TO_VCVARS = { 'win-arm64' : 'x86_arm64' } -# A set containing the DLLs that are guaranteed to be available for -# all micro versions of this Python version. Known extension -# dependencies that are not in this set will be copied to the output -# path. -_BUNDLED_DLLS = frozenset(['vcruntime140.dll']) - class MSVCCompiler(CCompiler) : """Concrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.""" @@ -263,7 +234,6 @@ class MSVCCompiler(CCompiler) : self.rc = _find_exe("rc.exe", paths) # resource compiler self.mc = _find_exe("mc.exe", paths) # message compiler self.mt = _find_exe("mt.exe", paths) # message compiler - self._vcruntime_redist = vc_env.get('py_vcruntime_redist', '') for dir in vc_env.get('include', '').split(os.pathsep): if dir: @@ -274,13 +244,12 @@ class MSVCCompiler(CCompiler) : self.add_library_dir(dir.rstrip(os.sep)) self.preprocess_options = None - # If vcruntime_redist is available, link against it dynamically. Otherwise, - # use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib - # later to dynamically link to ucrtbase but not vcruntime. + # bpo-38597: Always compile with dynamic linking + # Future releases of Python 3.x will include all past + # versions of vcruntime*.dll for compatibility. self.compile_options = [ - '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG' + '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG', '/MD' ] - self.compile_options.append('/MD' if self._vcruntime_redist else '/MT') self.compile_options_debug = [ '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG' @@ -289,8 +258,6 @@ class MSVCCompiler(CCompiler) : ldflags = [ '/nologo', '/INCREMENTAL:NO', '/LTCG' ] - if not self._vcruntime_redist: - ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib')) ldflags_debug = [ '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' @@ -532,24 +499,11 @@ class MSVCCompiler(CCompiler) : try: log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) self.spawn([self.linker] + ld_args) - self._copy_vcruntime(output_dir) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) - def _copy_vcruntime(self, output_dir): - vcruntime = self._vcruntime_redist - if not vcruntime or not os.path.isfile(vcruntime): - return - - if os.path.basename(vcruntime).lower() in _BUNDLED_DLLS: - return - - log.debug('Copying "%s"', vcruntime) - vcruntime = shutil.copy(vcruntime, output_dir) - os.chmod(vcruntime, stat.S_IWRITE) - def spawn(self, cmd): old_path = os.getenv('path') try: diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 2d7cdf0..dbcd9d1 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -688,7 +688,15 @@ class build_ext(Command): provided, "PyInit_" + module_name. Only relevant on Windows, where the .pyd file (DLL) must export the module "PyInit_" function. """ - initfunc_name = "PyInit_" + ext.name.split('.')[-1] + suffix = '_' + ext.name.split('.')[-1] + try: + # Unicode module name support as defined in PEP-489 + # https://www.python.org/dev/peps/pep-0489/#export-hook-name + suffix.encode('ascii') + except UnicodeEncodeError: + suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') + + initfunc_name = "PyInit" + suffix if initfunc_name not in ext.export_symbols: ext.export_symbols.append(initfunc_name) return ext.export_symbols diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 52d36b2..5e47e07 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -304,6 +304,19 @@ class BuildExtTestCase(TempdirManager, cmd.ensure_finalized() self.assertEqual(cmd.get_source_files(), ['xxx']) + def test_unicode_module_names(self): + modules = [ + Extension('foo', ['aaa'], optional=False), + Extension('föö', ['uuu'], optional=False), + ] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = self.build_ext(dist) + cmd.ensure_finalized() + self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo(_d)?\..*') + self.assertRegex(cmd.get_ext_filename(modules[1].name), r'föö(_d)?\..*') + self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) + self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) + def test_compiler_option(self): # cmd.compiler is an option and # should not be overridden by a compiler instance diff --git a/Lib/distutils/tests/test_config_cmd.py b/Lib/distutils/tests/test_config_cmd.py index b735fd3..8bd2c94 100644 --- a/Lib/distutils/tests/test_config_cmd.py +++ b/Lib/distutils/tests/test_config_cmd.py @@ -47,8 +47,7 @@ class ConfigTestCase(support.LoggingSilencer, cmd = config(dist) cmd._check_compiler() compiler = cmd.compiler - is_xlc = shutil.which(compiler.preprocessor[0]).startswith("/usr/vac") - if is_xlc: + if sys.platform[:3] == "aix" and "xlc" in compiler.preprocessor[0].lower(): self.skipTest('xlc: The -E option overrides the -P, -o, and -qsyntaxonly options') # simple pattern searches diff --git a/Lib/distutils/tests/test_msvccompiler.py b/Lib/distutils/tests/test_msvccompiler.py index 70a9c93..b518d6a 100644 --- a/Lib/distutils/tests/test_msvccompiler.py +++ b/Lib/distutils/tests/test_msvccompiler.py @@ -32,57 +32,6 @@ class msvccompilerTestCase(support.TempdirManager, finally: _msvccompiler._find_vcvarsall = old_find_vcvarsall - def test_compiler_options(self): - import distutils._msvccompiler as _msvccompiler - # suppress path to vcruntime from _find_vcvarsall to - # check that /MT is added to compile options - old_find_vcvarsall = _msvccompiler._find_vcvarsall - def _find_vcvarsall(plat_spec): - return old_find_vcvarsall(plat_spec)[0], None - _msvccompiler._find_vcvarsall = _find_vcvarsall - try: - compiler = _msvccompiler.MSVCCompiler() - compiler.initialize() - - self.assertIn('/MT', compiler.compile_options) - self.assertNotIn('/MD', compiler.compile_options) - finally: - _msvccompiler._find_vcvarsall = old_find_vcvarsall - - def test_vcruntime_copy(self): - import distutils._msvccompiler as _msvccompiler - # force path to a known file - it doesn't matter - # what we copy as long as its name is not in - # _msvccompiler._BUNDLED_DLLS - old_find_vcvarsall = _msvccompiler._find_vcvarsall - def _find_vcvarsall(plat_spec): - return old_find_vcvarsall(plat_spec)[0], __file__ - _msvccompiler._find_vcvarsall = _find_vcvarsall - try: - tempdir = self.mkdtemp() - compiler = _msvccompiler.MSVCCompiler() - compiler.initialize() - compiler._copy_vcruntime(tempdir) - - self.assertTrue(os.path.isfile(os.path.join( - tempdir, os.path.basename(__file__)))) - finally: - _msvccompiler._find_vcvarsall = old_find_vcvarsall - - def test_vcruntime_skip_copy(self): - import distutils._msvccompiler as _msvccompiler - - tempdir = self.mkdtemp() - compiler = _msvccompiler.MSVCCompiler() - compiler.initialize() - dll = compiler._vcruntime_redist - self.assertTrue(os.path.isfile(dll), dll or "") - - compiler._copy_vcruntime(tempdir) - - self.assertFalse(os.path.isfile(os.path.join( - tempdir, os.path.basename(dll))), dll or "") - def test_get_vc_env_unicode(self): import distutils._msvccompiler as _msvccompiler diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index d10a78d..4d7a6de 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -288,7 +288,7 @@ class UnixCCompiler(CCompiler): # vs # /usr/lib/libedit.dylib cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s+(\S+)', cflags) + m = re.search(r'-isysroot\s*(\S+)', cflags) if m is None: sysroot = '/' else: diff --git a/Lib/doctest.py b/Lib/doctest.py index dcbcfe5..ee71984 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -211,6 +211,13 @@ def _normalize_module(module, depth=2): else: raise TypeError("Expected a module, string, or None") +def _newline_convert(data): + # We have two cases to cover and we need to make sure we do + # them in the right order + for newline in ('\r\n', '\r'): + data = data.replace(newline, '\n') + return data + def _load_testfile(filename, package, module_relative, encoding): if module_relative: package = _normalize_module(package, 3) @@ -221,7 +228,7 @@ def _load_testfile(filename, package, module_relative, encoding): file_contents = file_contents.decode(encoding) # get_data() opens files as 'rb', so one must do the equivalent # conversion as universal newlines would do. - return file_contents.replace(os.linesep, '\n'), filename + return _newline_convert(file_contents), filename with open(filename, encoding=encoding) as f: return f.read(), filename diff --git a/Lib/encodings/punycode.py b/Lib/encodings/punycode.py index 66c5101..1c57264 100644 --- a/Lib/encodings/punycode.py +++ b/Lib/encodings/punycode.py @@ -143,7 +143,7 @@ def decode_generalized_number(extended, extpos, bias, errors): digit = char - 22 # 0x30-26 elif errors == "strict": raise UnicodeError("Invalid extended code point '%s'" - % extended[extpos]) + % extended[extpos-1]) else: return extpos, None t = T(j, bias) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index fc0edec..566fb2a 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -2,6 +2,7 @@ import os import os.path import pkgutil import sys +import runpy import tempfile @@ -23,9 +24,18 @@ def _run_pip(args, additional_paths=None): if additional_paths is not None: sys.path = additional_paths + sys.path - # Install the bundled software - import pip._internal - return pip._internal.main(args) + # 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") def version(): diff --git a/Lib/fractions.py b/Lib/fractions.py index e774d58..e4fcc89 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -636,7 +636,9 @@ class Fraction(numbers.Rational): def __bool__(a): """a != 0""" - return a._numerator != 0 + # bpo-39274: Use bool() because (a._numerator != 0) can return an + # object which is not a bool. + return bool(a._numerator) # support for pickling, copy, and deepcopy diff --git a/Lib/functools.py b/Lib/functools.py index b41dea7..4cde5f5 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -11,7 +11,8 @@ __all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial', - 'partialmethod', 'singledispatch', 'singledispatchmethod'] + 'partialmethod', 'singledispatch', 'singledispatchmethod', + "cached_property"] from abc import get_cache_token from collections import namedtuple diff --git a/Lib/glob.py b/Lib/glob.py index 0b3fcc6..0dd2f8b 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -31,6 +31,7 @@ def iglob(pathname, *, recursive=False): If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ + sys.audit("glob.glob", pathname, recursive) it = _iglob(pathname, recursive, False) if recursive and _isrecursive(pathname): s = next(it) # skip empty string @@ -38,7 +39,6 @@ def iglob(pathname, *, recursive=False): return it def _iglob(pathname, recursive, dironly): - sys.audit("glob.glob", pathname, recursive) dirname, basename = os.path.split(pathname) if not has_magic(pathname): assert not dironly diff --git a/Lib/gzip.py b/Lib/gzip.py index 2968f47..87b553d 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -201,7 +201,7 @@ class GzipFile(_compression.BaseStream): self.fileobj = fileobj if self.mode == WRITE: - self._write_gzip_header() + self._write_gzip_header(compresslevel) @property def filename(self): @@ -228,7 +228,7 @@ class GzipFile(_compression.BaseStream): self.bufsize = 0 self.offset = 0 # Current file offset for seek(), tell(), etc - def _write_gzip_header(self): + def _write_gzip_header(self, compresslevel): self.fileobj.write(b'\037\213') # magic header self.fileobj.write(b'\010') # compression method try: @@ -249,7 +249,13 @@ class GzipFile(_compression.BaseStream): if mtime is None: mtime = time.time() write32u(self.fileobj, int(mtime)) - self.fileobj.write(b'\002') + if compresslevel == _COMPRESS_LEVEL_BEST: + xfl = b'\002' + elif compresslevel == _COMPRESS_LEVEL_FAST: + xfl = b'\004' + else: + xfl = b'\000' + self.fileobj.write(xfl) self.fileobj.write(b'\377') if fname: self.fileobj.write(fname + b'\000') diff --git a/Lib/http/client.py b/Lib/http/client.py index 33a4347..019380a 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -828,6 +828,8 @@ class HTTPConnection: (self.host, self.port) = self._get_hostport(host, port) + self._validate_host(self.host) + # This is stored as an instance variable to allow unit # tests to replace it with a suitable mockup self._create_connection = socket.create_connection @@ -1183,6 +1185,14 @@ class HTTPConnection: raise InvalidURL(f"URL can't contain control characters. {url!r} " f"(found at least {match.group()!r})") + def _validate_host(self, host): + """Validate a host so it doesn't contain control characters.""" + # Prevent CVE-2019-18348. + match = _contains_disallowed_url_pchar_re.search(host) + if match: + raise InvalidURL(f"URL can't contain control characters. {host!r} " + f"(found at least {match.group()!r})") + def putheader(self, header, *values): """Send a request header line to the server. diff --git a/Lib/http/server.py b/Lib/http/server.py index b247675..38f7acc 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -103,6 +103,7 @@ import socketserver import sys import time import urllib.parse +import contextlib from functools import partial from http import HTTPStatus @@ -1280,4 +1281,19 @@ if __name__ == '__main__': else: handler_class = partial(SimpleHTTPRequestHandler, directory=args.directory) - test(HandlerClass=handler_class, port=args.port, bind=args.bind) + + # ensure dual-stack is not disabled; ref #38907 + class DualStackServer(ThreadingHTTPServer): + def server_bind(self): + # suppress exception when protocol is IPv4 + with contextlib.suppress(Exception): + self.socket.setsockopt( + socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) + return super().server_bind() + + test( + HandlerClass=handler_class, + ServerClass=DualStackServer, + port=args.port, + bind=args.bind, + ) diff --git a/Lib/idlelib/Icons/README.txt b/Lib/idlelib/Icons/README.txt new file mode 100644 index 0000000..8b47162 --- /dev/null +++ b/Lib/idlelib/Icons/README.txt @@ -0,0 +1,9 @@ +The IDLE icons are from https://bugs.python.org/issue1490384 + +Created by Andrew Clover. + +The original sources are available from Andrew's website: +https://www.doxdesk.com/software/py/pyicons.html + +Various different formats and sizes are available at this GitHub Pull Request: +https://github.com/python/cpython/pull/17473 diff --git a/Lib/idlelib/Icons/idle.icns b/Lib/idlelib/Icons/idle.icns deleted file mode 100644 index f65e3130f0afff1aa1bb13599f7a7d67968c9c42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57435 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 literal 0 HcmV?d00001 diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index e829bc9..de7543e 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,10 +3,42 @@ Released on 2019-12-16? ====================================== +bpo-38689: IDLE will no longer freeze when inspect.signature fails +when fetching a calltip. + +bpo-27115: For 'Go to Line', use a Query entry box subclass with +IDLE standard behavior and improved error checking. + +bpo-39885: Since clicking to get an IDLE context menu moves the +cursor, any text selection should be and now is cleared. + +bpo-39852: Edit "Go to line" now clears any selection, preventing +accidental deletion. It also updates Ln and Col on the status bar. + +bpo-39781: Selecting code context lines no longer causes a jump. + +bpo-39663: Add tests for pyparse find_good_parse_start(). + +bpo-39600: Remove duplicate font names from configuration list. + +bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` +or shell restart occurs. Patch by Zackery Spytz. + +bpo-30780: Add remaining configdialog tests for buttons and +highlights and keys tabs. + +bpo-39388: Settings dialog Cancel button cancels pending changes. + +bpo-39050: Settings dialog Help button again displays help text. + +bpo-32989: Add tests for editor newline_and_indent_event method. +Remove unneeded arguments and dead code from pyparse +find_good_parse_start method. + bpo-38943: Fix autocomplete windows not always appearing on some systems. Patch by Johnny Najera. -bpo-38944: Excape key now closes IDLE completion windows. Patch by +bpo-38944: Escape key now closes IDLE completion windows. Patch by Johnny Najera. bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 48a1f4a..bc3d978 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -90,7 +90,7 @@ Configuration config-extensions.def # Defaults for extensions config-highlight.def # Defaults for colorizing config-keys.def # Defaults for key bindings -config-main.def # Defai;ts fpr font and geneal +config-main.def # Defaults for font and general tabs Text ---- diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 0643c09..fe7a6be 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -4,7 +4,7 @@ An auto-completion window for IDLE, used by the autocomplete extension import platform from tkinter import * -from tkinter.ttk import Frame, Scrollbar +from tkinter.ttk import Scrollbar from idlelib.autocomplete import FILES, ATTRS from idlelib.multicall import MC_SHIFT diff --git a/Lib/idlelib/calltip.py b/Lib/idlelib/calltip.py index a3dda26..d4092c7 100644 --- a/Lib/idlelib/calltip.py +++ b/Lib/idlelib/calltip.py @@ -33,7 +33,7 @@ class Calltip: # See __init__ for usage return calltip_w.CalltipWindow(self.text) - def _remove_calltip_window(self, event=None): + def remove_calltip_window(self, event=None): if self.active_calltip: self.active_calltip.hidetip() self.active_calltip = None @@ -55,7 +55,7 @@ class Calltip: self.open_calltip(False) def open_calltip(self, evalfuncs): - self._remove_calltip_window() + self.remove_calltip_window() hp = HyperParser(self.editwin, "insert") sur_paren = hp.get_surrounding_brackets('(') @@ -129,20 +129,22 @@ def get_argspec(ob): empty line or _MAX_LINES. For builtins, this typically includes the arguments in addition to the return value. ''' - argspec = default = "" + # Determine function object fob to inspect. try: ob_call = ob.__call__ - except BaseException: - return default - + except BaseException: # Buggy user object could raise anything. + return '' # No popup for non-callables. fob = ob_call if isinstance(ob_call, types.MethodType) else ob + # Initialize argspec and wrap it to get lines. try: argspec = str(inspect.signature(fob)) - except ValueError as err: + except Exception as err: msg = str(err) if msg.startswith(_invalid_method): return _invalid_method + else: + argspec = '' if '/' in argspec and len(argspec) < _MAX_COLS - len(_argument_positional): # Add explanation TODO remove after 3.7, before 3.9. @@ -154,6 +156,7 @@ def get_argspec(ob): lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) 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: @@ -167,9 +170,8 @@ def get_argspec(ob): line = line[: _MAX_COLS - 3] + '...' lines.append(line) argspec = '\n'.join(lines) - if not argspec: - argspec = _default_callable_argspec - return argspec + + return argspec or _default_callable_argspec if __name__ == '__main__': diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index 4ce9813..989b30e 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -7,7 +7,6 @@ the lines which contain the block opening keywords, e.g. 'if', for the 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. - """ import re from sys import maxsize as INFINITY @@ -17,8 +16,8 @@ from tkinter.constants import NSEW, SUNKEN from idlelib.config import idleConf -BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with", "async"} +BLOCKOPENERS = {'class', 'def', 'if', 'elif', 'else', 'while', 'for', + 'try', 'except', 'finally', 'with', 'async'} def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")): @@ -84,7 +83,7 @@ class CodeContext: if self.t1 is not None: try: self.text.after_cancel(self.t1) - except tkinter.TclError: + except tkinter.TclError: # pragma: no cover pass self.t1 = None @@ -112,7 +111,7 @@ class CodeContext: padx += widget.tk.getint(info['padx']) padx += widget.tk.getint(widget.cget('padx')) border += widget.tk.getint(widget.cget('border')) - self.context = tkinter.Text( + context = self.context = tkinter.Text( self.editwin.text_frame, height=1, width=1, # Don't request more than we get. @@ -120,11 +119,11 @@ class CodeContext: padx=padx, border=border, relief=SUNKEN, state='disabled') self.update_font() self.update_highlight_colors() - self.context.bind('', self.jumptoline) + context.bind('', self.jumptoline) # Get the current context and initiate the recurring update event. self.timer_event() # Grid the context widget above the text widget. - self.context.grid(row=0, column=1, sticky=NSEW) + context.grid(row=0, column=1, sticky=NSEW) line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'linenumber') @@ -215,18 +214,25 @@ class CodeContext: self.context['state'] = 'disabled' def jumptoline(self, event=None): - "Show clicked context line at top of editor." - lines = len(self.info) - if lines == 1: # No context lines are showing. - newtop = 1 - else: - # Line number clicked. - contextline = int(float(self.context.index('insert'))) - # Lines not displayed due to maxlines. - offset = max(1, lines - self.context_depth) - 1 - newtop = self.info[offset + contextline][0] - self.text.yview(f'{newtop}.0') - self.update_code_context() + """ Show clicked context line at top of editor. + + If a selection was made, don't jump; allow copying. + If no visible context, show the top line of the file. + """ + try: + self.context.index("sel.first") + except tkinter.TclError: + lines = len(self.info) + if lines == 1: # No context lines are showing. + newtop = 1 + else: + # Line number clicked. + contextline = int(float(self.context.index('insert'))) + # Lines not displayed due to maxlines. + offset = max(1, lines - self.context_depth) - 1 + newtop = self.info[offset + contextline][0] + self.text.yview(f'{newtop}.0') + self.update_code_context() def timer_event(self): "Event on editor text widget triggered every UPDATEINTERVAL ms." diff --git a/Lib/idlelib/config_key.py b/Lib/idlelib/config_key.py index 4478323..7510aa9 100644 --- a/Lib/idlelib/config_key.py +++ b/Lib/idlelib/config_key.py @@ -1,7 +1,7 @@ """ Dialog for building Tkinter accelerator key bindings """ -from tkinter import Toplevel, Listbox, Text, StringVar, TclError +from tkinter import Toplevel, Listbox, StringVar, TclError from tkinter.ttk import Frame, Button, Checkbutton, Entry, Label, Scrollbar from tkinter import messagebox import string diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index aaf319b..8259649 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -11,7 +11,7 @@ Refer to comments in EditorWindow autoindent code for details. """ import re -from tkinter import (Toplevel, Listbox, Text, Scale, Canvas, +from tkinter import (Toplevel, Listbox, Scale, Canvas, StringVar, BooleanVar, IntVar, TRUE, FALSE, TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE, NONE, BOTH, X, Y, W, E, EW, NS, NSEW, NW, @@ -149,17 +149,19 @@ class ConfigDialog(Toplevel): else: padding_args = {'padding': (6, 3)} outer = Frame(self, padding=2) - buttons = Frame(outer, padding=2) + buttons_frame = Frame(outer, padding=2) + self.buttons = {} for txt, cmd in ( ('Ok', self.ok), ('Apply', self.apply), ('Cancel', self.cancel), ('Help', self.help)): - Button(buttons, text=txt, command=cmd, takefocus=FALSE, - **padding_args).pack(side=LEFT, padx=5) + self.buttons[txt] = Button(buttons_frame, text=txt, command=cmd, + takefocus=FALSE, **padding_args) + self.buttons[txt].pack(side=LEFT, padx=5) # Add space above buttons. Frame(outer, height=2, borderwidth=0).pack(side=TOP) - buttons.pack(side=BOTTOM) + buttons_frame.pack(side=BOTTOM) return outer def ok(self): @@ -191,6 +193,7 @@ class ConfigDialog(Toplevel): Methods: destroy: inherited """ + changes.clear() self.destroy() def destroy(self): @@ -204,13 +207,12 @@ class ConfigDialog(Toplevel): Attributes accessed: note - Methods: view_text: Method from textview module. """ page = self.note.tab(self.note.select(), option='text').strip() view_text(self, title='Help for IDLE preferences', - text=help_common+help_pages.get(page, '')) + contents=help_common+help_pages.get(page, '')) def deactivate_current_config(self): """Remove current key bindings. @@ -604,9 +606,8 @@ class FontPage(Frame): font_size = configured_font[1] font_bold = configured_font[2]=='bold' - # Set editor font selection list and font_name. - fonts = list(tkFont.families(self)) - fonts.sort() + # Set sorted no-duplicate editor font selection list and font_name. + fonts = sorted(set(tkFont.families(self))) for font in fonts: self.fontlist.insert(END, font) self.font_name.set(font_name) @@ -851,6 +852,7 @@ class HighPage(Frame): text.configure( font=('courier', 12, ''), cursor='hand2', width=1, height=1, takefocus=FALSE, highlightthickness=0, wrap=NONE) + # Prevent perhaps invisible selection of word or slice. text.bind('', lambda e: 'break') text.bind('', lambda e: 'break') string_tags=( @@ -1283,8 +1285,7 @@ class HighPage(Frame): theme_name - string, the name of the new theme theme - dictionary containing the new theme """ - if not idleConf.userCfg['highlight'].has_section(theme_name): - idleConf.userCfg['highlight'].add_section(theme_name) + idleConf.userCfg['highlight'].AddSection(theme_name) for element in theme: value = theme[element] idleConf.userCfg['highlight'].SetOption(theme_name, element, value) @@ -1729,8 +1730,7 @@ class KeysPage(Frame): keyset_name - string, the name of the new key set keyset - dictionary containing the new keybindings """ - if not idleConf.userCfg['keys'].has_section(keyset_name): - idleConf.userCfg['keys'].add_section(keyset_name) + idleConf.userCfg['keys'].AddSection(keyset_name) for event in keyset: value = keyset[event] idleConf.userCfg['keys'].SetOption(keyset_name, event, value) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 92dcf57..b0f88b5 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -328,7 +328,7 @@ class EditorWindow(object): text.bind("<>", scriptbinding.run_module_event) text.bind("<>", scriptbinding.run_custom_event) text.bind("<>", self.Rstrip(self).do_rstrip) - ctip = self.Calltip(self) + self.ctip = ctip = self.Calltip(self) text.bind("<>", ctip.try_open_calltip_event) #refresh-calltip must come after paren-closed to work right text.bind("<>", ctip.refresh_calltip_event) @@ -499,6 +499,7 @@ class EditorWindow(object): rmenu = None def right_menu_event(self, event): + self.text.tag_remove("sel", "1.0", "end") self.text.mark_set("insert", "@%d,%d" % (event.x, event.y)) if not self.rmenu: self.make_rmenu() @@ -671,15 +672,16 @@ class EditorWindow(object): def goto_line_event(self, event): text = self.text - lineno = tkSimpleDialog.askinteger("Goto", - "Go to line number:",parent=text) - if lineno is None: - return "break" - if lineno <= 0: - text.bell() - return "break" - text.mark_set("insert", "%d.0" % lineno) - text.see("insert") + lineno = query.Goto( + text, "Go To Line", + "Enter a positive integer\n" + "('big' = end of file):" + ).result + if lineno is not None: + text.tag_remove("sel", "1.0", "end") + text.mark_set("insert", f'{lineno}.0') + text.see("insert") + self.set_line_and_column() return "break" def open_module(self): @@ -1342,38 +1344,51 @@ class EditorWindow(object): text.undo_block_stop() def newline_and_indent_event(self, event): + """Insert a newline and indentation after Enter keypress event. + + Properly position the cursor on the new line based on information + from the current line. This takes into account if the current line + is a shell prompt, is empty, has selected text, contains a block + opener, contains a block closer, is a continuation line, or + is inside a string. + """ text = self.text first, last = self.get_selection_indices() text.undo_block_start() - try: + try: # Close undo block and expose new line in finally clause. if first and last: text.delete(first, last) text.mark_set("insert", first) line = text.get("insert linestart", "insert") + + # Count leading whitespace for indent size. i, n = 0, len(line) while i < n and line[i] in " \t": - i = i+1 + i += 1 if i == n: - # the cursor is in or at leading indentation in a continuation - # line; just inject an empty line at the start + # The cursor is in or at leading indentation in a continuation + # line; just inject an empty line at the start. text.insert("insert linestart", '\n') return "break" indent = line[:i] - # strip whitespace before insert point unless it's in the prompt + + # Strip whitespace before insert point unless it's in the prompt. i = 0 while line and line[-1] in " \t" and line != self.prompt_last_line: line = line[:-1] - i = i+1 + i += 1 if i: text.delete("insert - %d chars" % i, "insert") - # strip whitespace after insert point + + # Strip whitespace after insert point. while text.get("insert") in " \t": text.delete("insert") - # start new line + + # Insert new line. text.insert("insert", '\n') - # adjust indentation for continuations and block - # open/close first need to find the last stmt + # Adjust indentation for continuations and block open/close. + # First need to find the last statement. lno = index2line(text.index('insert')) y = pyparse.Parser(self.indentwidth, self.tabwidth) if not self.prompt_last_line: @@ -1383,7 +1398,7 @@ class EditorWindow(object): rawtext = text.get(startatindex, "insert") y.set_code(rawtext) bod = y.find_good_parse_start( - self._build_char_in_string_func(startatindex)) + self._build_char_in_string_func(startatindex)) if bod is not None or startat == 1: break y.set_lo(bod or 0) @@ -1399,26 +1414,26 @@ class EditorWindow(object): c = y.get_continuation_type() if c != pyparse.C_NONE: - # The current stmt hasn't ended yet. + # The current statement hasn't ended yet. if c == pyparse.C_STRING_FIRST_LINE: - # after the first line of a string; do not indent at all + # After the first line of a string do not indent at all. pass elif c == pyparse.C_STRING_NEXT_LINES: - # inside a string which started before this line; - # just mimic the current indent + # Inside a string which started before this line; + # just mimic the current indent. text.insert("insert", indent) elif c == pyparse.C_BRACKET: - # line up with the first (if any) element of the + # Line up with the first (if any) element of the # last open bracket structure; else indent one # level beyond the indent of the line with the - # last open bracket + # last open bracket. self.reindent_to(y.compute_bracket_indent()) elif c == pyparse.C_BACKSLASH: - # if more than one line in this stmt already, just + # If more than one line in this statement already, just # mimic the current indent; else if initial line # has a start on an assignment stmt, indent to # beyond leftmost =; else to beyond first chunk of - # non-whitespace on initial line + # non-whitespace on initial line. if y.get_num_lines_in_stmt() > 1: text.insert("insert", indent) else: @@ -1427,9 +1442,9 @@ class EditorWindow(object): assert 0, "bogus continuation type %r" % (c,) return "break" - # This line starts a brand new stmt; indent relative to + # This line starts a brand new statement; indent relative to # indentation of initial line of closest preceding - # interesting stmt. + # interesting statement. indent = y.get_base_indent_string() text.insert("insert", indent) if y.is_block_opener(): diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 09dc4c5..424c6b5 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a1 documentation + IDLE — Python 3.9.0a4 documentation @@ -17,7 +17,7 @@ @@ -71,7 +71,7 @@
  • - 3.9.0a1 Documentation » + 3.9.0a4 Documentation »
  • @@ -197,7 +197,9 @@ be undone.

    Replace…

    Open a search-and-replace dialog.

    -
    Go to Line

    Move cursor to the line number requested and make that line visible.

    +
    Go to Line

    Move the cursor to the beginning of the line requested and make that +line visible. A request past the end of the file goes to the end. +Clear any selection and update the line and column status.

    Show Completions

    Open a scrollable list allowing selection of keywords and attributes. See Completions in the Editing and navigation section below.

    @@ -382,7 +384,8 @@ Context menus have the standard clipboard functions also on the Edit menu.

    Editor windows also have breakpoint functions. Lines with a breakpoint set are specially marked. Breakpoints only have an effect when running under the -debugger. Breakpoints for a file are saved in the user’s .idlerc directory.

    +debugger. Breakpoints for a file are saved in the user’s .idlerc +directory.

    Set Breakpoint

    Set a breakpoint on the current line.

    @@ -634,17 +637,20 @@ clash, or a single installation might need admin access. If one undo the clash, or cannot or does not want to run as admin, it might be easiest to completely remove Python and start over.

    A zombie pythonw.exe process could be a problem. On Windows, use Task -Manager to detect and stop one. Sometimes a restart initiated by a program -crash or Keyboard Interrupt (control-C) may fail to connect. Dismissing -the error box or Restart Shell on the Shell menu may fix a temporary problem.

    +Manager to check for one and stop it if there is. Sometimes a restart +initiated by a program crash or Keyboard Interrupt (control-C) may fail +to connect. Dismissing the error box or using Restart Shell on the Shell +menu may fix a temporary problem.

    When IDLE first starts, it attempts to read user configuration files in -~/.idlerc/ (~ is one’s home directory). If there is a problem, an error +~/.idlerc/ (~ is one’s home directory). If there is a problem, an error message should be displayed. Leaving aside random disk glitches, this can -be prevented by never editing the files by hand, using the configuration -dialog, under Options, instead Options. Once it happens, the solution may -be to delete one or more of the configuration files.

    +be prevented by never editing the files by hand. Instead, use the +configuration dialog, under Options. Once there is an error in a user +configuration file, the best solution may be to delete it and start over +with the settings dialog.

    If IDLE quits with no message, and it was not started from a console, try -starting from a console (python -m idlelib) and see if a message appears.

    +starting it from a console or terminal (python -m idlelib) and see if +this results in an error message.

    Running user code¶

    @@ -791,20 +797,20 @@ the scrollbar, or up and down arrow keys held down. Or click the TOC (Table of Contents) button and select a section header in the opened box.

    Help menu entry “Python Docs” opens the extensive sources of help, -including tutorials, available at docs.python.org/x.y, where ‘x.y’ +including tutorials, available at docs.python.org/x.y, where ‘x.y’ is the currently running Python version. If your system has an off-line copy of the docs (this may be an installation option), that will be opened instead.

    Selected URLs can be added or removed from the help menu at any time using the -General tab of the Configure IDLE dialog .

    +General tab of the Configure IDLE dialog.

    Setting preferences¶

    The font preferences, highlighting, keys, and general preferences can be changed via Configure IDLE on the Option menu. -Non-default user settings are saved in a .idlerc directory in the user’s +Non-default user settings are saved in a .idlerc directory in the user’s home directory. Problems caused by bad user configuration files are solved -by editing or deleting one or more of the files in .idlerc.

    +by editing or deleting one or more of the files in .idlerc.

    On the Font tab, see the text sample for the effect of font face and size on multiple characters in multiple languages. Edit the sample to add other characters of personal interest. Use the sample to select @@ -929,7 +935,7 @@ also used for testing.

  • - 3.9.0a1 Documentation » + 3.9.0a4 Documentation »
  • @@ -952,7 +958,7 @@ also used for testing.