在CPython源代码中定义math_sin函数?

Pin*_*ido 4 python cpython python-internals

我正在研究CPython的代码库。

我想知道在哪里可以找到表中math_sin显示的函数的定义:mathmethodsmathmodule.c

{"sin",             math_sin,       METH_O,         math_sin_doc}
Run Code Online (Sandbox Code Playgroud)

这样做grep "math_sin" -wr的主要cpython文件夹中唯一的回报:

Modules/mathmodule.c:    {"sin",             math_sin,       METH_O,         math_sin_doc},
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 9

math_sin通过FUNC1定义:

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

其中FUNC1定义为

#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);
Run Code Online (Sandbox Code Playgroud)

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

    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).");
Run Code Online (Sandbox Code Playgroud)

(但随后全部放在一行上,并且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 double,进行调用sin(arg_as_double),根据需要引发异常,或者将double的返回值sin()与返回之前PyFloat_FromDouble传递的函数包装在一起math_1()结果给呼叫者。

sin()这是POSIX中定义double sin(double x)函数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/{} \;)
Run Code Online (Sandbox Code Playgroud)

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

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

make clean && make CC="gcc -save-temps"
Run Code Online (Sandbox Code Playgroud)

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