Python Development ModePython开发模式

New in version 3.7.版本3.7中新增。

The Python Development Mode introduces additional runtime checks that are too expensive to be enabled by default. Python开发模式引入了额外的运行时检查,这些检查过于昂贵,无法在默认情况下启用。It should not be more verbose than the default if the code is correct; new warnings are only emitted when an issue is detected.如果代码是正确的,那么它不应该比默认值更详细;只有在检测到问题时才会发出新的警告。

It can be enabled using the -X dev command line option or by setting the PYTHONDEVMODE environment variable to 1.它可以使用-X dev命令行选项或通过将PYTHONDEVMODE环境变量设置为1来启用。

See also Python debug build.另请参见Python调试构建

Effects of the Python Development ModePython开发模式的影响

Enabling the Python Development Mode is similar to the following command, but with additional effects described below:启用Python开发模式类似于以下命令,但具有以下所述的附加效果:

PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python3 -W default -X faulthandler

Effects of the Python Development Mode:Python开发模式的影响:

  • Add default warning filter. 添加default 警告筛选器The following warnings are shown:显示以下警告:

    Normally, the above warnings are filtered by the default warning filters.通常情况下,上述警告由默认的警告筛选器进行过滤。

    It behaves as if the -W default command line option is used.它的行为就像使用了-W default命令行选项一样。

    Use the -W error command line option or set the PYTHONWARNINGS environment variable to error to treat warnings as errors.

  • Install debug hooks on memory allocators to check for:在内存分配器上安装调试挂钩以检查:

    • Buffer underflow

    • Buffer overflow

    • Memory allocator API violation

    • Unsafe usage of the GIL

    See the PyMem_SetupDebugHooks() C function.

    It behaves as if the PYTHONMALLOC environment variable is set to debug.

    To enable the Python Development Mode without installing debug hooks on memory allocators, set the PYTHONMALLOC environment variable to default.

  • Call faulthandler.enable() at Python startup to install handlers for the SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals to dump the Python traceback on a crash.

    It behaves as if the -X faulthandler command line option is used or if the PYTHONFAULTHANDLER environment variable is set to 1.

  • Enable asyncio debug mode. For example, asyncio checks for coroutines that were not awaited and logs them.

    It behaves as if the PYTHONASYNCIODEBUG environment variable is set to 1.

  • Check the encoding and errors arguments for string encoding and decoding operations. Examples: open(), str.encode() and bytes.decode().

    By default, for best performance, the errors argument is only checked at the first encoding/decoding error and the encoding argument is sometimes ignored for empty strings.

  • The io.IOBase destructor logs close() exceptions.

  • Set the dev_mode attribute of sys.flags to True.sys.flagsdev_mode属性设置为True

The Python Development Mode does not enable the tracemalloc module by default, because the overhead cost (to performance and memory) would be too large. Python开发模式默认情况下不启用tracemalloc模块,因为开销(性能和内存)太大。Enabling the tracemalloc module provides additional information on the origin of some errors. 启用tracemalloc模块可以提供有关某些错误来源的其他信息。For example, ResourceWarning logs the traceback where the resource was allocated, and a buffer overflow error logs the traceback where the memory block was allocated.例如,ResourceWarning记录分配资源的回溯,缓冲区溢出错误记录分配内存块的回溯。

The Python Development Mode does not prevent the -O command line option from removing assert statements nor from setting __debug__ to False.Python开发模式不会阻止-O命令行选项删除assert语句,也不会阻止将__debug__设置为False

The Python Development Mode can only be enabled at the Python startup. Python开发模式只能在Python启动时启用。Its value can be read from sys.flags.dev_mode.其值可以从sys.flags.dev_mode中读取。

Changed in version 3.8:版本3.8中更改: The io.IOBase destructor now logs close() exceptions.io.IOBase析构函数现在记录close()异常。

Changed in version 3.9:版本3.9中更改: The encoding and errors arguments are now checked for string encoding and decoding operations.现在检查encodingerrors参数以进行字符串编码和解码操作。

ResourceWarning Example资源警告示例

Example of a script counting the number of lines of the text file specified in the command line:计算命令行中指定的文本文件的行数的脚本示例:

import sys
def main():
fp = open(sys.argv[1])
nlines = len(fp.readlines())
print(nlines)
# The file is closed implicitly

if __name__ == "__main__":
main()

The script does not close the file explicitly. 脚本没有显式关闭文件。By default, Python does not emit any warning. 默认情况下,Python不会发出任何警告。Example using README.txt, which has 269 lines:使用READMEtxt的示例,它有269行:

$ python3 script.py README.txt
269

Enabling the Python Development Mode displays a ResourceWarning warning:启用Python开发模式会显示ResourceWarning警告:

$ python3 -X dev script.py README.txt
269
script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>
main()
ResourceWarning: Enable tracemalloc to get the object allocation traceback

In addition, enabling tracemalloc shows the line where the file was opened:此外,启用tracemalloc会显示打开文件的行:

$ python3 -X dev -X tracemalloc=5 script.py README.rst
269
script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>
main()
Object allocated at (most recent call last):
File "script.py", lineno 10
main()
File "script.py", lineno 4
fp = open(sys.argv[1])

The fix is to close explicitly the file. Example using a context manager:解决方法是显式关闭该文件。使用上下文管理器的示例:

def main():
# Close the file explicitly when exiting the with block
with open(sys.argv[1]) as fp:
nlines = len(fp.readlines())
print(nlines)

Not closing a resource explicitly can leave a resource open for way longer than expected; it can cause severe issues upon exiting Python. 不显式关闭资源可能会使资源的打开时间比预期的要长得多;退出Python时可能会导致严重问题。It is bad in CPython, but it is even worse in PyPy. CPython的情况很糟糕,但PyPy的情况更糟。Closing resources explicitly makes an application more deterministic and more reliable.明确地关闭资源会使应用程序更具确定性和可靠性。

Bad file descriptor error example错误的文件描述符错误示例

Script displaying the first line of itself:显示自身第一行的脚本:

import os
def main():
fp = open(__file__)
firstline = fp.readline()
print(firstline.rstrip())
os.close(fp.fileno())
# The file is closed implicitly

main()

By default, Python does not emit any warning:默认情况下,Python不会发出任何警告:

$ python3 script.py
import os

The Python Development Mode shows a ResourceWarning and logs a “Bad file descriptor” error when finalizing the file object:Python开发模式在完成文件对象时显示ResourceWarning并记录“Bad file descriptor”错误:

$ python3 script.py
import os
script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>
main()
ResourceWarning: Enable tracemalloc to get the object allocation traceback
Exception ignored in: <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>
Traceback (most recent call last):
File "script.py", line 10, in <module>
main()
OSError: [Errno 9] Bad file descriptor

os.close(fp.fileno()) closes the file descriptor. 关闭文件描述符。When the file object finalizer tries to close the file descriptor again, it fails with the Bad file descriptor error. 当文件对象终结器再次尝试关闭文件描述符时,它将失败,并出现Bad file descriptor错误。A file descriptor must be closed only once. 文件描述符只能关闭一次。In the worst case scenario, closing it twice can lead to a crash (see bpo-18748 for an example).在最坏的情况下,关闭两次可能会导致崩溃(例如,请参阅bpo-18748)。

The fix is to remove the os.close(fp.fileno()) line, or open the file with closefd=False.修复方法是删除os.close(fp.fileno())行,或者用closefd=False打开文件。