Skip to content

Commit 67204e1

Browse files
committed
We can compile on python 3.11
1 parent 7cddf86 commit 67204e1

File tree

7 files changed

+399
-163
lines changed

7 files changed

+399
-163
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ classifiers = [
1818
"Programming Language :: Python :: 3 :: Only",
1919
]
2020
dependencies = [
21-
"llvmlite>=0.38,<0.45",
21+
"llvmlite>=0.38,<0.39",
2222
"numpy",
2323
"scipy",
2424
"psutil",

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
llvmlite>=0.38,<0.45
1+
llvmlite>=0.38,<0.39
22
numpy
33
scipy
44
psutil

typed_python/CompilerVisibleObjectVisitor.hpp

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "ShaHash.hpp"
2020
#include "SpecialModuleNames.hpp"
21+
#include "PyVersionCompat.hpp"
2122
#include "util.hpp"
2223
#include <unordered_map>
2324

@@ -680,30 +681,58 @@ class CompilerVisibleObjectVisitor {
680681
PyCodeObject* co = (PyCodeObject*)obj.pyobj();
681682

682683
visitor.visitHash(ShaHash(4));
683-
visitor.visitHash(ShaHash(co->co_argcount));
684-
visitor.visitHash(co->co_kwonlyargcount);
685-
visitor.visitHash(co->co_nlocals);
686-
visitor.visitHash(co->co_stacksize);
684+
visitor.visitHash(ShaHash(PyCompat::codeGetArgcount(co)));
685+
visitor.visitHash(PyCompat::codeGetKwonlyargcount(co));
686+
visitor.visitHash(PyCompat::codeGetNlocals(co));
687+
visitor.visitHash(PyCompat::codeGetStacksize(co));
687688
// don't serialize the 'co_flags' field because it's not actually stable
688689
// and it doesn't contain any semantic information not available elsewhere.
689690
// visitor.visitHash(co->co_flags);
690-
visitor.visitHash(co->co_firstlineno);
691-
visitor.visitHash(ShaHash::SHA1(PyBytes_AsString(co->co_code), PyBytes_GET_SIZE(co->co_code)));
692-
visitor.visitTuple(co->co_consts);
693-
visitor.visitTuple(co->co_names);
694-
visitor.visitTuple(co->co_varnames);
695-
visitor.visitTuple(co->co_freevars);
696-
visitor.visitTuple(co->co_cellvars);
691+
visitor.visitHash(PyCompat::codeGetFirstlineno(co));
692+
693+
{
694+
PyObject* code = PyCompat::codeGetCode(co);
695+
PyCompat::NewRefIf311 guard(code);
696+
visitor.visitHash(ShaHash::SHA1(PyBytes_AsString(code), PyBytes_GET_SIZE(code)));
697+
}
698+
{
699+
PyObject* consts = PyCompat::codeGetConsts(co);
700+
PyCompat::NewRefIf311 guard(consts);
701+
visitor.visitTuple(consts);
702+
}
703+
{
704+
PyObject* names = PyCompat::codeGetNames(co);
705+
PyCompat::NewRefIf311 guard(names);
706+
visitor.visitTuple(names);
707+
}
708+
{
709+
PyObject* varnames = PyCompat::codeGetVarnames(co);
710+
PyCompat::NewRefIf311 guard(varnames);
711+
visitor.visitTuple(varnames);
712+
}
713+
{
714+
PyObject* freevars = PyCompat::codeGetFreevars(co);
715+
PyCompat::NewRefIf311 guard(freevars);
716+
visitor.visitTuple(freevars);
717+
}
718+
{
719+
PyObject* cellvars = PyCompat::codeGetCellvars(co);
720+
PyCompat::NewRefIf311 guard(cellvars);
721+
visitor.visitTuple(cellvars);
722+
}
697723
// we ignore this, because otherwise, we'd have the hash change
698724
// whenever we instantiate code in a new location
699725
// visit(co->co_filename)
700-
visitor.visitTopo(co->co_name);
701-
702-
# if PY_MINOR_VERSION >= 10
703-
visitor.visitTopo(co->co_linetable);
704-
# else
705-
visitor.visitTopo(co->co_lnotab);
706-
# endif
726+
{
727+
PyObject* name = PyCompat::codeGetName(co);
728+
PyCompat::NewRefIf311 guard(name);
729+
visitor.visitTopo(name);
730+
}
731+
{
732+
PyObject* linetable = PyCompat::codeGetLinetable(co);
733+
PyCompat::NewRefIf311 guard(linetable);
734+
visitor.visitTopo(linetable);
735+
}
707736
return;
708737
}
709738

typed_python/FunctionType.hpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Format.hpp"
2323
#include "SpecialModuleNames.hpp"
2424
#include "PyInstance.hpp"
25+
#include "PyVersionCompat.hpp"
2526

2627
class Function;
2728

@@ -1082,7 +1083,12 @@ class Function : public Type {
10821083
static PyObject* moduleHashName = PyUnicode_FromString("__module_hash__");
10831084
outSequences.push_back(std::vector<PyObject*>({moduleHashName}));
10841085

1085-
PyBytes_AsStringAndSize(((PyCodeObject*)code)->co_code, (char**)&bytes, &bytecount);
1086+
PyObject* codeBytes = PyCompat::codeGetCode(code);
1087+
PyCompat::NewRefIf311 codeBytesGuard(codeBytes);
1088+
PyBytes_AsStringAndSize(codeBytes, (char**)&bytes, &bytecount);
1089+
1090+
PyObject* names = PyCompat::codeGetNames(code);
1091+
PyCompat::NewRefIf311 namesGuard(names);
10861092

10871093
long opcodeCount = bytecount / 2;
10881094

@@ -1103,7 +1109,7 @@ class Function : public Type {
11031109
for (long ix = 0; ix < opcodeCount; ix++) {
11041110
// if we're loading an attr on an existing sequence, just make it bigger
11051111
if ((opcodeFor(ix) == LOAD_ATTR || opcodeFor(ix) == LOAD_METHOD) && curDotSequence.size()) {
1106-
curDotSequence.push_back(PyTuple_GetItem(code->co_names, opcodeTargetFor(ix)));
1112+
curDotSequence.push_back(PyTuple_GetItem(names, opcodeTargetFor(ix)));
11071113
} else if (curDotSequence.size()) {
11081114
// any other operation should flush the buffer
11091115
outSequences.push_back(curDotSequence);
@@ -1112,12 +1118,12 @@ class Function : public Type {
11121118

11131119
// if we're loading a global, we start a new sequence
11141120
if (opcodeFor(ix) == LOAD_GLOBAL) {
1115-
curDotSequence.push_back(PyTuple_GetItem(code->co_names, opcodeTargetFor(ix)));
1121+
curDotSequence.push_back(PyTuple_GetItem(names, opcodeTargetFor(ix)));
11161122
} else if (
11171123
opcodeFor(ix) == STORE_GLOBAL
11181124
|| opcodeFor(ix) == DELETE_GLOBAL
11191125
) {
1120-
outSequences.push_back({PyTuple_GetItem(code->co_names, opcodeTargetFor(ix))});
1126+
outSequences.push_back({PyTuple_GetItem(names, opcodeTargetFor(ix))});
11211127
}
11221128
}
11231129

@@ -1127,7 +1133,9 @@ class Function : public Type {
11271133
}
11281134

11291135
// recurse into sub code objects
1130-
iterate(code->co_consts, [&](PyObject* o) {
1136+
PyObject* consts = PyCompat::codeGetConsts(code);
1137+
PyCompat::NewRefIf311 constsGuard(consts);
1138+
iterate(consts, [&](PyObject* o) {
11311139
if (PyCode_Check(o)) {
11321140
extractDottedGlobalAccessesFromCode((PyCodeObject*)o, outSequences);
11331141
}
@@ -1138,7 +1146,12 @@ class Function : public Type {
11381146
uint8_t* bytes;
11391147
Py_ssize_t bytecount;
11401148

1141-
PyBytes_AsStringAndSize(((PyCodeObject*)code)->co_code, (char**)&bytes, &bytecount);
1149+
PyObject* codeBytes = PyCompat::codeGetCode(code);
1150+
PyCompat::NewRefIf311 codeBytesGuard(codeBytes);
1151+
PyBytes_AsStringAndSize(codeBytes, (char**)&bytes, &bytecount);
1152+
1153+
PyObject* names = PyCompat::codeGetNames(code);
1154+
PyCompat::NewRefIf311 namesGuard(names);
11421155

11431156
long opcodeCount = bytecount / 2;
11441157

@@ -1155,7 +1168,7 @@ class Function : public Type {
11551168
for (long ix = 0; ix < opcodeCount; ix++) {
11561169
// if we're loading a global, we start a new sequence
11571170
if (opcodeFor(ix) == LOAD_GLOBAL) {
1158-
PyObject* name = PyTuple_GetItem(code->co_names, opcodeTargetFor(ix));
1171+
PyObject* name = PyTuple_GetItem(names, opcodeTargetFor(ix));
11591172
if (!PyUnicode_Check(name)) {
11601173
throw std::runtime_error("Function had a non-string object in co_names");
11611174
}
@@ -1164,7 +1177,7 @@ class Function : public Type {
11641177
opcodeFor(ix) == STORE_GLOBAL
11651178
|| opcodeFor(ix) == DELETE_GLOBAL
11661179
) {
1167-
PyObject* name = PyTuple_GetItem(code->co_names, opcodeTargetFor(ix));
1180+
PyObject* name = PyTuple_GetItem(names, opcodeTargetFor(ix));
11681181
if (!PyUnicode_Check(name)) {
11691182
throw std::runtime_error("Function had a non-string object in co_names");
11701183
}
@@ -1173,7 +1186,9 @@ class Function : public Type {
11731186
}
11741187

11751188
// recurse into sub code objects
1176-
iterate(code->co_consts, [&](PyObject* o) {
1189+
PyObject* consts = PyCompat::codeGetConsts(code);
1190+
PyCompat::NewRefIf311 constsGuard(consts);
1191+
iterate(consts, [&](PyObject* o) {
11771192
if (PyCode_Check(o)) {
11781193
extractGlobalAccessesFromCode((PyCodeObject*)o, outAccesses);
11791194
}
@@ -1183,14 +1198,25 @@ class Function : public Type {
11831198
}
11841199

11851200
static void extractNamesFromCode(PyCodeObject* code, std::set<PyObject*>& outNames) {
1186-
iterate(code->co_names, [&](PyObject* o) { outNames.insert(o); });
1187-
iterate(code->co_freevars, [&](PyObject* o) { outNames.insert(o); });
1188-
1189-
iterate(code->co_consts, [&](PyObject* o) {
1190-
if (PyCode_Check(o)) {
1191-
extractNamesFromCode((PyCodeObject*)o, outNames);
1192-
}
1193-
});
1201+
{
1202+
PyObject* names = PyCompat::codeGetNames(code);
1203+
PyCompat::NewRefIf311 guard(names);
1204+
iterate(names, [&](PyObject* o) { outNames.insert(o); });
1205+
}
1206+
{
1207+
PyObject* freevars = PyCompat::codeGetFreevars(code);
1208+
PyCompat::NewRefIf311 guard(freevars);
1209+
iterate(freevars, [&](PyObject* o) { outNames.insert(o); });
1210+
}
1211+
{
1212+
PyObject* consts = PyCompat::codeGetConsts(code);
1213+
PyCompat::NewRefIf311 guard(consts);
1214+
iterate(consts, [&](PyObject* o) {
1215+
if (PyCode_Check(o)) {
1216+
extractNamesFromCode((PyCodeObject*)o, outNames);
1217+
}
1218+
});
1219+
}
11941220

11951221
static PyObject* moduleHashName = PyUnicode_FromString("__module_hash__");
11961222
outNames.insert(moduleHashName);

typed_python/PyTemporaryReferenceTracer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
******************************************************************************/
1616

1717
#include "PyTemporaryReferenceTracer.hpp"
18+
#include "PyVersionCompat.hpp"
1819

1920
bool PyTemporaryReferenceTracer::isLineNewStatement(PyObject* code, int line) {
2021
PyErrorStasher stashCurrentException;
@@ -61,10 +62,12 @@ int PyTemporaryReferenceTracer::globalTraceFun(PyObject* dummyObj, PyFrameObject
6162
);
6263

6364
// we process any statement on a line that's a new statement
65+
PyObject* code = (PyObject*)PyFrame_GetCode(frame);
6466
bool shouldProcess = globalTracer.isLineNewStatement(
65-
(PyObject*)frame->f_code,
67+
code,
6668
PyFrame_GetLineNumber(frame)
6769
);
70+
Py_DECREF(code);
6871

6972
if (shouldProcess || forceProcess) {
7073
auto it = globalTracer.frameToActions.find(frame);
@@ -165,19 +168,21 @@ void PyTemporaryReferenceTracer::keepaliveForCurrentInstruction(PyObject* o, PyF
165168

166169
void PyTemporaryReferenceTracer::traceObject(PyObject* o) {
167170
PyThreadState *tstate = PyThreadState_GET();
168-
PyFrameObject *f = tstate->frame;
171+
PyFrameObject *f = PyCompat::getFrame(tstate);
169172

170173
if (f) {
171174
PyTemporaryReferenceTracer::traceObject(o, f);
175+
PyCompat::NewRefIf311 guard((PyObject*)f);
172176
}
173177
}
174178

175179
void PyTemporaryReferenceTracer::keepaliveForCurrentInstruction(PyObject* o) {
176180
PyThreadState *tstate = PyThreadState_GET();
177-
PyFrameObject *f = tstate->frame;
181+
PyFrameObject *f = PyCompat::getFrame(tstate);
178182

179183
if (f) {
180184
PyTemporaryReferenceTracer::keepaliveForCurrentInstruction(o, f);
185+
PyCompat::NewRefIf311 guard((PyObject*)f);
181186
}
182187
}
183188

0 commit comments

Comments
 (0)