构建和 C API 的改变

针对 Python 构建过程和 C API 的改变包括:

This function was added to close a security hole for applications that embed Python. The old function, PySys_SetArgv(), would always update sys.path, and sometimes it would add the current directory. This meant that, if you ran an application embedding Python in a directory controlled by someone else, attackers could put a Trojan-horse module in the directory (say, a file named os.py) that your application would then import and run.

If you maintain a C/C++ application that embeds Python, check whether you're calling PySys_SetArgv() and carefully consider whether the application should be using PySys_SetArgvEx() with updatepath set to false.

Security issue reported as CVE 2008-5983 [https://www.cve.org/CVERecord?id=CVE-2008-5983]; discussed in bpo-5753 [https://bugs.python.org/issue?@action=redirect&bpo=5753], and fixed by Antoine Pitrou.

  • New macros: the Python header files now define the following macros: Py_ISALNUM, Py_ISALPHA, Py_ISDIGIT, Py_ISLOWER, Py_ISSPACE, Py_ISUPPER, Py_ISXDIGIT, Py_TOLOWER, and Py_TOUPPER. All of these functions are analogous to the C standard macros for classifying characters, but ignore the current locale setting, because in several places Python needs to analyze characters in a locale-independent way. (Added by Eric Smith; bpo-5793 [https://bugs.python.org/issue?@action=redirect&bpo=5793].)

  • Removed function: PyEval_CallObject() is now only available as a macro. A function version was being kept around to preserve ABI linking compatibility, but that was in 1997; it can certainly be deleted by now. (Removed by Antoine Pitrou; bpo-8276 [https://bugs.python.org/issue?@action=redirect&bpo=8276].)

  • New format codes: the PyString_FromFormat(), PyString_FromFormatV(), and PyErr_Format() functions now accept %lld and %llu format codes for displaying C's long long types. (Contributed by Mark Dickinson; bpo-7228 [https://bugs.python.org/issue?@action=redirect&bpo=7228].)

  • The complicated interaction between threads and process forking has been changed. Previously, the child process created by os.fork() might fail because the child is created with only a single thread running, the thread performing the os.fork(). If other threads were holding a lock, such as Python's import lock, when the fork was performed, the lock would still be marked as "held" in the new process. But in the child process nothing would ever release the lock, since the other threads weren't replicated, and the child process would no longer be able to perform imports.

Python 2.7 acquires the import lock before performing an os.fork(), and will also clean up any locks created using the threading module. C extension modules that have internal locks, or that call fork() themselves, will not benefit from this cleanup.

(Fixed by Thomas Wouters; bpo-1590864 [https://bugs.python.org/issue?@action=redirect&bpo=1590864].)

configure also now sets a LDCXXSHARED Makefile variable for supporting C++ linking. (Contributed by Arfrever Frehtes Taifersar Arahesis; bpo-1222585 [https://bugs.python.org/issue?@action=redirect&bpo=1222585].)

Capsule 对象

Python 3.1 adds a new C datatype, PyCapsule, for providing a C API to an extension module. A capsule is essentially the holder of a C void * pointer, and is made available as a module attribute; for example, the socket module's API is exposed as socket.CAPI, and unicodedata exposes ucnhash_CAPI. Other extensions can import the module, access its dictionary to get the capsule object, and then get the void * pointer, which will usually point to an array of pointers to the module's various API functions.

There is an existing data type already used for this, PyCObject, but it doesn't provide type safety. Evil code written in pure Python could cause a segmentation fault by taking a PyCObject from module A and somehow substituting it for the PyCObject in module B. Capsules know their own name, and getting the pointer requires providing the name:

  1. void *vtable;
  2.  
  3. if (!PyCapsule_IsValid(capsule, "mymodule.CAPI") { PyErr_SetString(PyExc_ValueError, "argument type invalid"); return NULL;
  4. }
  5.  
  6. vtable = PyCapsule_GetPointer(capsule, "mymodule.CAPI");

You are assured that vtable points to whatever you're expecting. If a different capsule was passed in, PyCapsule_IsValid() would detect the mismatched name and return false. Refer to 给扩展模块提供C API for more information on using these objects.

Python 2.7 now uses capsules internally to provide various extension-module APIs, but the PyCObject_AsVoidPtr() was modified to handle capsules, preserving compile-time compatibility with the PyCObject interface. Use of PyCObject_AsVoidPtr() will signal a PendingDeprecationWarning, which is silent by default.

Implemented in Python 3.1 and backported to 2.7 by Larry Hastings; discussed in bpo-5630 [https://bugs.python.org/issue?@action=redirect&bpo=5630].

特定于 Windows 的更改:

特定于 Mac OS X 的更改:

在 2.7.13 版本发生变更: As of 2.7.13, this change was removed. LibraryPython/2.7/sitepackages, the sitepackages directory used by the Apple-supplied system Python 2.7 is no longer appended to sys.path for user-installed Pythons such as from the python.org installers. As of macOS 10.12, Apple changed how the system sitepackages directory is configured, which could cause installation of pip components, like setuptools, to fail. Packages installed for the system Python will no longer be shared with user-installed Pythons. (bpo-28440 [https://bugs.python.org/issue?@action=redirect&bpo=28440])

特定于 FreeBSD 的更改:

其他的改变和修正

  • Two benchmark scripts, iobench and ccbench, were added to the Tools directory. iobench measures the speed of the built-in file I/O objects returned by open() while performing various operations, and ccbench is a concurrency benchmark that tries to measure computing throughput, thread switching latency, and IO processing bandwidth when performing several tasks using a varying number of threads.

  • The Tools/i18n/msgfmt.py script now understands plural forms in .po files. (Fixed by Martin von Löwis; bpo-5464 [https://bugs.python.org/issue?@action=redirect&bpo=5464].)

  • When importing a module from a .pyc or .pyo file with an existing .py counterpart, the co_filename attributes of the resulting code objects are overwritten when the original filename is obsolete. This can happen if the file has been renamed, moved, or is accessed through different paths. (Patch by Ziga Seilnacht and Jean-Paul Calderone; bpo-1180193 [https://bugs.python.org/issue?@action=redirect&bpo=1180193].)

  • The regrtest.py script now takes a --randseed= switch that takes an integer that will be used as the random seed for the -r option that executes tests in random order. The -r option also reports the seed that was used (Added by Collin Winter.)

  • Another regrtest.py switch is -j, which takes an integer specifying how many tests run in parallel. This allows reducing the total runtime on multi-core machines. This option is compatible with several other options, including the -R switch which is known to produce long runtimes. (Added by Antoine Pitrou, bpo-6152 [https://bugs.python.org/issue?@action=redirect&bpo=6152].) This can also be used with a new -F switch that runs selected tests in a loop until they fail. (Added by Antoine Pitrou; bpo-7312 [https://bugs.python.org/issue?@action=redirect&bpo=7312].)

  • When executed as a script, the py_compile.py module now accepts '-' as an argument, which will read standard input for the list of filenames to be compiled. (Contributed by Piotr Ożarowski; bpo-8233 [https://bugs.python.org/issue?@action=redirect&bpo=8233].)

移植到 Python 2.7

本节列出了先前描述的改变以及可能需要修改你的代码的其他问题修正:

在标准库中:

Comparisons involving a signaling NaN value (or sNAN) now signal InvalidOperation instead of silently returning a true or false value depending on the comparison operator. Quiet NaN values (or NaN) are now hashable. (Fixed by Mark Dickinson; bpo-7279 [https://bugs.python.org/issue?@action=redirect&bpo=7279].)

  1. >>> import urlparse
  2. >>> urlparse.urlsplit('invented://host/filename?query')
  3. ('invented', '', '//host/filename?query', '', '')

Python 2.7 (and Python 2.6.5) will return:

  1. >>> import urlparse
  2. >>> urlparse.urlsplit('invented://host/filename?query')
  3. ('invented', 'host', '/filename?query', '', '')

(Python 2.7 actually produces slightly different output, since it returns a named tuple instead of a standard tuple.)

对于C 扩展模块:

对于嵌入Python的应用程序:

  • The PySys_SetArgvEx() function was added, letting applications close a security hole when the existing PySys_SetArgv() function was used. Check whether you're calling PySys_SetArgv() and carefully consider whether the application should be using PySys_SetArgvEx() with updatepath set to false.

New Features Added to Python 2.7 Maintenance Releases

New features may be added to Python 2.7 maintenance releases when the situation genuinely calls for it. Any such additions must go through the Python Enhancement Proposal process, and make a compelling case for why they can't be adequately addressed by either adding the new feature solely to Python 3, or else by publishing it on the Python Package Index.

In addition to the specific proposals listed below, there is a general exemption allowing new -3 warnings to be added in any Python 2.7 maintenance release.

Two new environment variables for debug mode

In debug mode, the [xxx refs] statistic is not written by default, the PYTHONSHOWREFCOUNT environment variable now must also be set. (Contributed by Victor Stinner; bpo-31733 [https://bugs.python.org/issue?@action=redirect&bpo=31733].)

When Python is compiled with COUNT_ALLOC defined, allocation counts are no longer dumped by default anymore: the PYTHONSHOWALLOCCOUNT environment variable must now also be set. Moreover, allocation counts are now dumped into stderr, rather than stdout. (Contributed by Victor Stinner; bpo-31692 [https://bugs.python.org/issue?@action=redirect&bpo=31692].)

Added in version 2.7.15.

PEP 434: IDLE Enhancement Exception for All Branches

PEP 434 [https://peps.python.org/pep-0434/] describes a general exemption for changes made to the IDLE development environment shipped along with Python. This exemption makes it possible for the IDLE developers to provide a more consistent user experience across all supported versions of Python 2 and 3.

For details of any IDLE changes, refer to the NEWS file for the specific release.

PEP 466: 针对 Python 2.7 的网络安全加固

PEP 466 [https://peps.python.org/pep-0466/] describes a number of network security enhancement proposals that have been approved for inclusion in Python 2.7 maintenance releases, with the first of those changes appearing in the Python 2.7.7 release.

PEP 466 [https://peps.python.org/pep-0466/] Python 2.7.7 中添加的相关功能:

PEP 466 [https://peps.python.org/pep-0466/] Python 2.7.8 中添加的相关功能:

PEP 466 [https://peps.python.org/pep-0466/] Python 2.7.9 中添加的相关功能:

Refer to the "Version added: 2.7.9" notes in the module documentation for specific details.

PEP 477: 将 ensurepip (PEP 453) 向下移植到 Python 2.7

PEP 477 [https://peps.python.org/pep-0477/] approves the inclusion of the PEP 453 [https://peps.python.org/pep-0453/] ensurepip module and the improved documentation that was enabled by it in the Python 2.7 maintenance releases, appearing first in the Python 2.7.9 release.

默认对 pip 进行初始配置

The new ensurepip module (defined in PEP 453 [https://peps.python.org/pep-0453/]) provides a standard cross-platform mechanism to bootstrap the pip installer into Python installations. The version of pip included with Python 2.7.9 is pip 1.5.6, and future 2.7.x maintenance releases will update the bundled version to the latest version of pip that is available at the time of creating the release candidate.

By default, the commands pip, pipX and pipX.Y will be installed on all platforms (where X.Y stands for the version of the Python installation), along with the pip Python package and its dependencies.

For CPython source builds on POSIX systems, the make install and make altinstall commands do not bootstrap pip by default. This behaviour can be controlled through configure options, and overridden through Makefile options.

在 Windows 和 Mac OS X 上,现在 CPython 安装程序默认会将 pip 与 CPython 本身一同安装(用户可以在安装过程中选择不安装它)。 Window 用户需要选择执行 PATH 修改以使 pip 在命令行中默认可用,在其他情况下它仍然可以通过 Windows 版 Python 启动器以 py -m pip 的方式使用。

As discussed in the PEP [https://peps.python.org/pep-0477/#disabling-ensurepip-by-downstream-distributors], platform packagers may choose not to install these commands by default, as long as, when invoked, they provide clear and simple directions on how to install them on that platform (usually using the system package manager).

文档更改

作为此项更改的一部分,文档的 安装 Python 模块分发 Python 模块 章节已经完全重新设计,快速入门和 FAQ 文档也是如此。 大部分打包指南文档现在都已被移至由 Python Packaging Authority 维护的 Python Packaging User Guide [https://packaging.python.org] 以及相应的独立项目文档。

不过,由于目前迁移过程尚未完成,这些指南的旧版本仍然可通过 使用 setuptools 构建 C 和 C++ 扩展使用 setuptools 构建 C 和 C++ 扩展 来访问。

参见

  • PEP 453 [https://peps.python.org/pep-0453/] — Python安装中pip的显式引导
  • PEP 由Donald Stufft 和 Nick Coghlan 撰写,由 Donald Stufft,Nick Coghlan,Martin von Löwis 和 Ned Deily 实现。

PEP 476: 默认为 stdlib http 客户端启用证书验证

PEP 476 [https://peps.python.org/pep-0476/] updated httplib and modules which use it, such as urllib2 and xmlrpclib, to now verify that the server presents a certificate which is signed by a Certificate Authority in the platform trust store and whose hostname matches the hostname being requested by default, significantly improving security for many applications. This change was made in the Python 2.7.9 release.

对于需要之前版本的旧有行为的应用程序,可以传入一个替代的上下文:

  1. import urllib2
  2. import ssl
  3.  
  4. # This disables all verification
  5. context = ssl._create_unverified_context()
  6.  
  7. # This allows using a specific certificate for the host, which doesn't need
  8. # to be in the trust store
  9. context = ssl.create_default_context(cafile="pathto/file.crt")
  10.  
  11. urllib2.urlopen("https://invalid-cert", context=context)

PEP 493:适用于Python 2.7 的 HTTPS 验证迁移工具

PEP 493 [https://peps.python.org/pep-0493/] provides additional migration tools to support a more incremental infrastructure upgrade process for environments containing applications and services relying on the historically permissive processing of server certificates when establishing client HTTPS connections. These additions were made in the Python 2.7.12 release.

These tools are intended for use in cases where affected applications and services can't be modified to explicitly pass a more permissive SSL context when establishing the connection.

For applications and services which can't be modified at all, the new PYTHONHTTPSVERIFY environment variable may be set to 0 to revert an entire Python process back to the default permissive behaviour of Python 2.7.8 and earlier.

For cases where the connection establishment code can't be modified, but the overall application can be, the new ssl._https_verify_certificates() function can be used to adjust the default behaviour at runtime.

新增 make regen-all 构建目标

为了简化交叉编译,并确保 CPython 能够可靠地编译而不需要已存在可用的 Python 版本,基于 autotools 的构建系统将不再尝试根据文件修改时间隐式地重新编译已生成的文件。

取而代之的是,新增了一个 make regen-all 命令以便在需要时强制重新生成这些文件(例如在基于预生成版本构建了 Python 的初始版本之后)。

还定义了其他一些更具选择性的重生成目标 —— 详情参见 Makefile.pre.in [https://github.compythoncpython/tree/3.13/Makefile.pre.in]。

(由 Victor Stinner 在 bpo-23404 [https://bugs.python.org/issue?@action=redirect&bpo=23404] 中贡献。)

Added in version 2.7.14.

移除了 make touch 构建目标

之前用于通过更新生成文件的修改时间来请求隐式的重新生成这些文件的 make touch 构建目标已被移除。

它已被新的 make regen-all 目标所替代。

(由 Victor Stinner 在 bpo-23404 [https://bugs.python.org/issue?@action=redirect&bpo=23404] 中贡献。)

在 2.7.14 版本发生变更.

致谢

作者要感谢以下人员为本文的各种草案提供建议,更正和帮助: Nick Coghlan, Philip Jenvey, Ryan Lovett, R. David Murray, Hugh Secker-Walker.