Skip to content

Commit 239f755

Browse files
committed
Creation of the project
0 parents  commit 239f755

9 files changed

+530
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.swp
2+
tests/build/

CODE_OF_CONDUCT.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Code of Conduct
2+
3+
Please note that all interactions on
4+
[Python Software Foundation](https://www.python.org/psf-landing/)-supported
5+
infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties)
6+
by the [PSF Code of Conduct](https://www.python.org/psf/codeofconduct/),
7+
which includes all the infrastructure used in the development of Python itself
8+
(e.g. mailing lists, issue trackers, GitHub, etc.).
9+
10+
In general, this means that everyone is expected to be **open**, **considerate**, and
11+
**respectful** of others no matter what their position is within the project.

COPYING

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
Copyright 2016, Red Hat, Inc. and Google Inc.
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a
5+
copy of this software and associated documentation files (the
6+
"Software"), to deal in the Software without restriction, including
7+
without limitation the rights to use, copy, modify, merge, publish,
8+
distribute, sublicense, and/or sell copies of the Software, and to
9+
permit persons to whom the Software is furnished to do so, subject to
10+
the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included
13+
in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.rst

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
++++++++++++++++++++++++++
2+
Python C API compatibility
3+
++++++++++++++++++++++++++
4+
5+
Header file providing new functions of the Python C API for old Python versions.
6+
7+
Python 3.6 to Python 3.10 are supported. It requires a subset of C99 like
8+
``static inline`` functions:
9+
see `PEP 7 <https://www.python.org/dev/peps/pep-0007/>`_.
10+
11+
Homepage: https://github.com/pythoncapi/pythoncapi_compat
12+
13+
This project is distributed under the MIT license.
14+
15+
This project is covered by the `PSF Code of Conduct
16+
<https://www.python.org/psf/codeofconduct/>`_.
17+
18+
This project is guided by evolution of the C API described in:
19+
`PEP xxx: Modify the C API to hide implementation details
20+
<https://github.com/vstinner/misc/blob/master/cpython/pep-opaque-c-api.rst>`_
21+
(draft).
22+
23+
Usage
24+
=====
25+
26+
Copy the header file in your project and include it using::
27+
28+
#include "pythoncapi_compat.h"
29+
30+
Functions
31+
=========
32+
33+
Python 3.9
34+
----------
35+
36+
::
37+
38+
// PyObject
39+
void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
40+
void Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
41+
void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
42+
43+
PyObject* PyObject_CallNoArgs(PyObject *func)
44+
45+
// PyFrameObject
46+
PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
47+
PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
48+
49+
// PyThreadState
50+
PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
51+
PyInterpreterState* PyThreadState_GetInterpreter(PyThreadState *tstate)
52+
// Availability: Python 3.7+
53+
uint64_t PyThreadState_GetID(PyThreadState *tstate)
54+
55+
// PyInterpreterState
56+
PyInterpreterState* PyInterpreterState_Get(void)
57+
58+
// GC protocol
59+
int PyObject_GC_IsTracked(PyObject* obj)
60+
int PyObject_GC_IsFinalized(PyObject *obj)
61+
62+
// Module helper
63+
int PyModule_AddType(PyObject *module, PyTypeObject *type)
64+
65+
66+
Run tests
67+
=========
68+
69+
Run the command::
70+
71+
python3 tests/test_matrix.py
72+
73+
To test one specific Python executable::
74+
75+
python3.6 tests/run_tests.py

pythoncapi_compat.h

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/* Header file providing new functions of the Python C API
2+
for old Python versions.
3+
4+
File distributed under the MIT license.
5+
Homepage: https://github.com/pythoncapi/pythoncapi_compat.
6+
*/
7+
8+
#ifndef PYTHONCAPI_COMPAT
9+
#define PYTHONCAPI_COMPAT
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
#include <Python.h>
16+
#include "frameobject.h" // PyFrameObject
17+
18+
19+
// bpo-39573: Py_TYPE(), Py_REFCNT() and Py_SIZE() can no longer be used
20+
// as l-value in Python 3.10.
21+
#if PY_VERSION_HEX < 0x030900A4
22+
static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
23+
{
24+
ob->ob_refcnt = refcnt;
25+
}
26+
#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject*)(ob), refcnt)
27+
28+
29+
static inline void
30+
_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
31+
{
32+
ob->ob_type = type;
33+
}
34+
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
35+
36+
static inline void
37+
_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
38+
{
39+
ob->ob_size = size;
40+
}
41+
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
42+
43+
#endif // PY_VERSION_HEX < 0x030900A4
44+
45+
46+
#if PY_VERSION_HEX < 0x030900B1
47+
static inline PyCodeObject*
48+
PyFrame_GetCode(PyFrameObject *frame)
49+
{
50+
assert(frame != NULL);
51+
PyCodeObject *code = frame->f_code;
52+
assert(code != NULL);
53+
Py_INCREF(code);
54+
return code;
55+
}
56+
#endif
57+
58+
59+
#if PY_VERSION_HEX < 0x030900B1
60+
static inline PyFrameObject*
61+
PyFrame_GetBack(PyFrameObject *frame)
62+
{
63+
assert(frame != NULL);
64+
PyFrameObject *back = frame->f_back;
65+
Py_XINCREF(back);
66+
return back;
67+
}
68+
#endif
69+
70+
71+
#if PY_VERSION_HEX < 0x030900A5
72+
static inline PyInterpreterState *
73+
PyThreadState_GetInterpreter(PyThreadState *tstate)
74+
{
75+
assert(tstate != NULL);
76+
return tstate->interp;
77+
}
78+
#endif
79+
80+
81+
#if PY_VERSION_HEX < 0x030900B1
82+
static inline PyFrameObject*
83+
PyThreadState_GetFrame(PyThreadState *tstate)
84+
{
85+
assert(tstate != NULL);
86+
PyFrameObject *frame = tstate->frame;
87+
Py_XINCREF(frame);
88+
return frame;
89+
}
90+
#endif
91+
92+
93+
#if PY_VERSION_HEX < 0x030900A5
94+
static inline PyInterpreterState *
95+
PyInterpreterState_Get(void)
96+
{
97+
PyThreadState *tstate = PyThreadState_GET();
98+
if (tstate == NULL) {
99+
Py_FatalError("GIL released (tstate is NULL)");
100+
}
101+
PyInterpreterState *interp = tstate->interp;
102+
if (interp == NULL) {
103+
Py_FatalError("no current interpreter");
104+
}
105+
return interp;
106+
}
107+
#endif
108+
109+
110+
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6
111+
static inline uint64_t
112+
PyThreadState_GetID(PyThreadState *tstate)
113+
{
114+
assert(tstate != NULL);
115+
return tstate->id;
116+
}
117+
#endif
118+
119+
120+
#if PY_VERSION_HEX < 0x030900A1
121+
static inline PyObject*
122+
PyObject_CallNoArgs(PyObject *func)
123+
{
124+
return PyObject_CallFunctionObjArgs(func, NULL);
125+
}
126+
#endif
127+
128+
129+
#if PY_VERSION_HEX < 0x030900A5
130+
static inline int
131+
PyModule_AddType(PyObject *module, PyTypeObject *type)
132+
{
133+
if (PyType_Ready(type) < 0) {
134+
return -1;
135+
}
136+
137+
// inline _PyType_Name()
138+
const char *name = type->tp_name;
139+
assert(name != NULL);
140+
const char *dot = strrchr(name, '.');
141+
if (dot != NULL) {
142+
name = dot + 1;
143+
}
144+
145+
Py_INCREF(type);
146+
if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
147+
Py_DECREF(type);
148+
return -1;
149+
}
150+
151+
return 0;
152+
}
153+
#endif
154+
155+
156+
#if PY_VERSION_HEX < 0x030900A6
157+
static inline int
158+
PyObject_GC_IsTracked(PyObject* obj)
159+
{
160+
return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
161+
}
162+
163+
static inline int
164+
PyObject_GC_IsFinalized(PyObject *obj)
165+
{
166+
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
167+
}
168+
#endif // PY_VERSION_HEX < 0x030900A6
169+
170+
171+
#ifdef __cplusplus
172+
}
173+
#endif
174+
#endif // PYTHONCAPI_COMPAT

0 commit comments

Comments
 (0)