File: extension.c

package info (click to toggle)
python3.14 3.14.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 152,200 kB
  • sloc: python: 757,783; ansic: 718,195; xml: 31,250; sh: 5,982; cpp: 4,093; makefile: 2,007; objc: 787; lisp: 502; javascript: 136; asm: 75; csh: 12
file content (142 lines) | stat: -rw-r--r-- 3,515 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// gh-116869: Basic C test extension to check that the Python C API
// does not emit C compiler warnings.
//
// Test also the internal C API if the TEST_INTERNAL_C_API macro is defined.

// Always enable assertions
#undef NDEBUG

#ifdef TEST_INTERNAL_C_API
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"
#include "datetime.h"

#ifdef TEST_INTERNAL_C_API
   // gh-135906: Check for compiler warnings in the internal C API.
   // - Cython uses pycore_critical_section.h, pycore_frame.h and
   //   pycore_template.h.
   // - greenlet uses pycore_frame.h, pycore_interpframe_structs.h and
   //   pycore_interpframe.h.
#  include "internal/pycore_critical_section.h"
#  include "internal/pycore_frame.h"
#  include "internal/pycore_gc.h"
#  include "internal/pycore_interp.h"
#  include "internal/pycore_interpframe.h"
#  include "internal/pycore_interpframe_structs.h"
#  include "internal/pycore_object.h"
#  include "internal/pycore_pystate.h"
#  include "internal/pycore_template.h"
#endif

#ifndef MODULE_NAME
#  error "MODULE_NAME macro must be defined"
#endif

#define _STR(NAME) #NAME
#define STR(NAME) _STR(NAME)

PyDoc_STRVAR(_testcext_add_doc,
"add(x, y)\n"
"\n"
"Return the sum of two integers: x + y.");

static PyObject *
_testcext_add(PyObject *Py_UNUSED(module), PyObject *args)
{
    long i, j, res;
    if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) {
        return NULL;
    }
    res = i + j;
    return PyLong_FromLong(res);
}


static PyObject *
test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
    // datetime.h is excluded from the limited C API
#ifndef Py_LIMITED_API
    PyDateTime_IMPORT;
    if (PyErr_Occurred()) {
        return NULL;
    }
#endif

    Py_RETURN_NONE;
}


static PyMethodDef _testcext_methods[] = {
    {"add", _testcext_add, METH_VARARGS, _testcext_add_doc},
    {"test_datetime", test_datetime, METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL}  // sentinel
};


static int
_testcext_exec(PyObject *module)
{
    PyObject *result;

#ifdef __STDC_VERSION__
    if (PyModule_AddIntMacro(module, __STDC_VERSION__) < 0) {
        return -1;
    }
#endif

    result = PyObject_CallMethod(module, "test_datetime", "");
    if (!result) return -1;
    Py_DECREF(result);

    // test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR()
    Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
    assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0);

    return 0;
}

// Converting from function pointer to void* has undefined behavior, but
// works on all known platforms, and CPython's module and type slots currently
// need it.
// (GCC doesn't have a narrower category for this than -Wpedantic.)
_Py_COMP_DIAG_PUSH
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wpedantic"
#endif

static PyModuleDef_Slot _testcext_slots[] = {
    {Py_mod_exec, (void*)_testcext_exec},
    {0, NULL}
};

_Py_COMP_DIAG_POP


PyDoc_STRVAR(_testcext_doc, "C test extension.");

static struct PyModuleDef _testcext_module = {
    PyModuleDef_HEAD_INIT,  // m_base
    STR(MODULE_NAME),  // m_name
    _testcext_doc,  // m_doc
    0,  // m_size
    _testcext_methods,  // m_methods
    _testcext_slots,  // m_slots
    NULL,  // m_traverse
    NULL,  // m_clear
    NULL,  // m_free
};


#define _FUNC_NAME(NAME) PyInit_ ## NAME
#define FUNC_NAME(NAME) _FUNC_NAME(NAME)

PyMODINIT_FUNC
FUNC_NAME(MODULE_NAME)(void)
{
    return PyModuleDef_Init(&_testcext_module);
}