The __pypy__ 模块

The __pypy__ 模块是 PyPy 标准解释器提供的特殊功能的主要入口点。它的内容取决于 配置选项,这些选项可能会添加新功能和函数,其存在或不存在表明存在此类功能。这些通常用于在编写纯 Python 模块时实现兼容性,这些模块在 CPython 中是用 C 编写的。在 CPython 中不可用,因此必须在 if platform.python_implementation == 'PyPy' 块内使用,或者以其他方式隐藏在 CPython 解释器之外。

普遍可用的功能

  • internal_repr(obj): 返回对象的解释器级表示。

  • bytebuffer(length): 返回一个给定长度的新读写缓冲区。它就像一个简化的字符数组(实际上,取决于配置,array 模块在内部使用它)。

  • attach_gdb(): 在解释器级别启动 GDB(或在翻译之前启动 PDB)。

  • newmemoryview(buffer, itemsize, format, shape=None, strides=None): 使用来自 buffer 的数据以及指定的 itemsize、格式和可选的形状和步幅创建 memoryview 实例。

  • bufferable: 一个基类,它为子类提供了一个 __buffer__(self, flags) 方法供子类重写。此方法应返回类实例的 memoryview 实例。它由 C-API 的 tp_as_buffer. bf_getbuffer 调用。

  • builtinify(func): 在应用程序级模块中实现,这些模块在 CPython 中是用 C 实现的:此装饰器保护函数不被像方法一样绑定。有用,因为一些测试会做一些事情,比如将“内置”函数放在一个类上,并通过实例访问它。

  • hidden_applevel(func): 装饰器,它隐藏函数的框架,使其不属于应用程序级

  • get_hidden_tb(): 返回当前由隐藏在应用程序级框架处理的异常的回溯。

  • lookup_special(obj, meth): 在对象上查找特殊方法。

  • do_what_I_mean

  • resizelist_hint(sizehint) 将参数列表的底层存储重新分配到 sizehint

  • newlist_hint(...): 创建一个新的空列表,其底层存储的长度为 sizehint

  • add_memory_pressure(bytes): 添加估计字节的内存压力。在调用内部分配大量内存的 C 函数时很有用。这指示 GC 比平时更早地进行垃圾回收。

  • newdict(type): 创建一个具有特殊实现策略的普通字典。 type 是一个字符串,可以是

    • "module" - 等同于 some_module.__dict__
    • "instance" - 等同于一个实例字典,其键集不会经常改变
    • "kwargs" - 关键字参数字典,等同于你在函数中使用 **kwargs 所获得的字典,针对传递优化
    • "strdict" - 仅包含字符串键的字典。此字典应自动选择
  • reversed_dict: 以反向顺序枚举字典对象中的键。这是一个 __pypy__ 函数,而不是简单地通过调用 reversed() 来完成,以确保与 CPython 兼容:字典在 PyPY 中是有序的,但在 Cpython2.7 中不是。对于需要排序的情况,你应该使用 collections.OrderedDict 类。该类通过调用 __pypy__.reversed_dict() 来实现 __reversed__

  • dict_popitem_first: OrderedDict.popitem(last=False) 的解释器级实现。

  • delitem_if_value_is 原子等效于:if dict.get(key) is value: del dict[key]

    仅供特殊用途!避免在专门化的字典上使用,例如,对于 intstr 键,因为它会切换到对象策略。此外,is 操作实际上是指针相等性,因此如果 value 是不可变对象,例如 intstr,请避免使用它。

  • move_to_end: 将字典对象中的键移动到第一个或最后一个位置。这在 Python 3.x 中用于实现 OrderedDict.move_to_end()

  • strategy(dict or list or set): 返回对象当前使用的底层策略

  • list_get_physical_size(obj): 返回底层列表的物理大小(即超分配大小)

  • specialized_zip_2_lists

  • locals_to_fast

  • set_code_callback

  • save_module_content_for_future_reload

  • decode_long

  • side_effects_ok: 用于反向调试器:此函数通常返回 True,但如果我们正在评估调试命令(例如断点),则会返回 False。你负责在评估断点时完全不进行任何副作用(包括不进行缓存)。此函数旨在提供一些帮助——你可以在

    if not __pypy__.side_effects_ok():
        skip the caching logic
    

    getter 方法或属性内部,使其可用于断点。请注意,你需要重新运行 REVDB=.. pypy 才能更改 Python 代码。

  • stack_almost_full: 如果堆栈已满超过 15/16,则返回 True。

  • pyos_inputhook: 从 CPython C API 调用 PyOS_InputHook()

  • get_console_cp(): (仅限 Windows)返回控制台和控制台输出代码页。等同于调用 GetConsoleCPGetConsoleOuputCP

  • utf8content(u): 给定一个 unicode 字符串 u,返回其内部字节表示。仅用于调试。

  • os.real_getenv(...) 获取操作系统环境变量,跳过 Python 代码

  • _pypydatetime 为纯 Python datetime 标准库模块提供具有正确 C API 交互的基类

快速字符串连接

使用这些方法来实现快速、最小复制的字符串构建,而不是使用原地连接 +=

  • builders.StringBuilder
  • builders.UnicodeBuilder

与 PyPy 调试日志交互

以下函数可用于将您自己的内容写入 PYPYLOG

  • debug_start(category, timestamp=False): 打开一个新部分;如果 timestampTrue,还会返回写入日志的时间戳。
  • debug_stop(category, timestamp=False): 关闭由 debug_start 打开的部分。
  • debug_print(...): 将任意文本打印到日志。
  • debug_print_once(category, ...): 等效于 debug_start + debug_print + debug_stop
  • debug_flush: 刷新日志。
  • debug_read_timestamp(): 从日志使用的相同计时器中读取时间戳。
  • debug_get_timestamp_unit(): 获取 debug_read_timestamp() 返回的值的单位。

根据架构和操作系统,PyPy 使用不同的方法读取时间戳,因此日志文件中使用的时间戳以不同的单位表示。可以通过调用 debug_get_timestamp_unit() 来了解使用的是哪种单位,它可以是以下值之一

tsc
x86 机器上的默认值:时间戳以 CPU 滴答数表示,通过 时间戳计数器 读取。
ns
时间戳以纳秒表示。
QueryPerformanceCounter
在 Windows 上,如果由于某种原因 tsc 不可用:时间戳使用 win API QueryPerformanceCounter() 读取。

不幸的是,似乎没有可靠的标准方法可以将 tsc 滴答数转换为纳秒,尽管在实践中,在现代 CPU 上,将滴答数除以 CPU 的最大标称频率就足够了。出于这个原因,PyPy 提供原始值,并将转换工作留给外部库。

透明代理功能

如果启用了 透明代理(使用 –objspace-std-withtproxy),以下函数将被放入 __pypy__

  • tproxy(typ, controller): 返回看起来像是类型 typ 的东西。它的行为完全由控制器控制。有关详细信息,请参阅有关 透明代理 的文档。
  • get_tproxy_controller(obj): 如果 obj 确实是透明代理,则返回其控制器。否则返回 None。

用于计时额外的时钟

time 子模块公开了平台相关的时钟类型,例如 CLOCK_BOOTTIMECLOCK_MONOTONICCLOCK_MONOTONIC_COARSECLOCK_MONOTONIC_RAW 以及两个函数

  • clock_gettime(m) 返回以秒为单位的时钟类型时间,以及
  • clock_getres(m) 返回以秒为单位的时钟分辨率。

扩展信号处理

thread.signals_enbaled 是一个在非主线程中使用的上下文管理器。
在 “with” 语句中启用接收信号。更准确地说,如果进程接收到信号,则信号处理程序可能会在主线程(如往常一样)或在 “with signals_enabled:” 中的另一个线程中调用。另一个线程应该准备好处理信号处理程序可能引发的意外异常——特别是 KeyboardInterrupt。

带溢出的整数运算

  • intop 提供了一个模块,其中包含具有二进制补码溢出行为的整数运算,而不是溢出到长整数。

py.py 上可用的功能(翻译后不可用)

  • isfake(obj): 如果 obj 是伪造的,则返回 True。