【问题标题】:Definition of math_sin function in the CPython source code?CPython源代码中math_sin函数的定义?
【发布时间】:2019-04-18 12:03:01
【问题描述】:

我正在研究 CPython 的代码库。

我想知道在哪里可以找到出现在mathmodule.cmathmethods 表中的math_sin 函数的定义:

{"sin",             math_sin,       METH_O,         math_sin_doc}

在主 cpython 文件夹中执行 grep "math_sin" -wr 只会返回:

Modules/mathmodule.c:    {"sin",             math_sin,       METH_O,         math_sin_doc},

在哪里可以找到这个函数的定义?

【问题讨论】:

  • @JohnColeman:不完全是。该问题涵盖了 sin 实现的最终位置(即使用 POSIX math.h double sin(double x) 函数),而不是负责 Python 的 float 类型和 C double 之间的编组的 math_sin 实现在哪里已定义。
  • @MartijnPieters 我看到了区别。我将撤回我的近距离投票。

标签: python cpython python-internals


【解决方案1】:

math_sin 是通过FUNC1 macro 定义的:

FUNC1(sin, sin, 0,
      "sin($module, x, /)\n--\n\n"
      "Return the sine of x (measured in radians).")

FUNC1 is defined as:

#define FUNC1(funcname, func, can_overflow, docstring)                  \
    static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
        return math_1(args, func, can_overflow);                            \
    }\
    PyDoc_STRVAR(math_##funcname##_doc, docstring);

因此预处理器将其扩展为:

    static PyObject * math_sin(PyObject *self, PyObject *args) {
        return math_1(args, sin, 0);
    }
    PyDoc_STRVAR(math_sin_doc, "sin($module, x, /)\n--\n\n"
      "Return the sine of x (measured in radians).");

(但随后全部放在一行上,并且 PyDoc_STRVAR 宏也已扩展)

所以math_sin(module, args) 基本上是对math_1(args, sin, 0) 的调用,math_1(args, sin, 0) 调用math_1_to_whatever(args, sin, PyFloat_FromDouble, 0),它负责验证传入的 Python 浮点数,将其转换为 C 双精度,调用 sin(arg_as_double),引发根据需要处理异常,或者在将结果返回给调用者之前,使用math_1() 传入的PyFloat_FromDouble 函数包装来自sin() 的双精度返回值。

sin() 这里是the double sin(double x) function defined in POSIX math.h

原则上,您可以预处理整个 Python 源代码树并将输出转储到新目录中;以下假设您已经成功构建了python 二进制文件,因为它用于为gcc 提取必要的包含标志:

find . -type d -exec mkdir -p /tmp/processed/{} \;
(export FLAGS=$(./python.exe -m sysconfig | grep PY_CORE_CFLAGS | cut -d\" -f2) && \
 find . -type f \( -name '*.c' -o -name '*.h' \) -exec gcc -E $FLAGS {} -o /tmp/processed/{} \;)

然后math_sin 将出现在/tmp/preprocessed/Modules/mathmodule.c 中。

或者您可以告诉编译器使用-save-temps 标志将预处理器输出保存到.i 文件:

make clean && make CC="gcc -save-temps"

您会在Modules/mathmodule.i 中找到make_sin

【讨论】:

  • 感谢 Pieters,但是 POSIX math.h 的 sin 定义从何而来? #include 不在 mathmodule.c 或 _math.c
  • @PintoDoido:它包含在pyport.h中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 2011-12-15
相关资源
最近更新 更多