#!/usr/bin/python # Usage: typeslots.py < Include/typeslots.h typeslots.inc import sys, re def generate_typeslots(out=sys.stdout): out.write("/* Generated by typeslots.py */\n") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) if not m: continue member = m.group(1) if member == "tp_token": # The heap type structure (ht_*) is an implementation detail; # the public slot for it has a familiar `tp_` prefix member = '{-1, offsetof(PyHeapTypeObject, ht_token)}' elif member.startswith("tp_"): member = f'{{-1, offsetof(PyTypeObject, {member})}}' elif member.startswith("am_"): member = (f'{{offsetof(PyAsyncMethods, {member}),'+ ' offsetof(PyTypeObject, tp_as_async)}') elif member.startswith("nb_"): member = (f'{{offsetof(PyNumberMethods, {member}),'+ ' offsetof(PyTypeObject, tp_as_number)}') elif member.startswith("mp_"): member = (f'{{offsetof(PyMappingMethods, {member}),'+ ' offsetof(PyTypeObject, tp_as_mapping)}') elif member.startswith("sq_"): member = (f'{{offsetof(PySequenceMethods, {member}),'+ ' offsetof(PyTypeObject, tp_as_sequence)}') elif member.startswith("bf_"): member = (f'{{offsetof(PyBufferProcs, {member}),'+ ' offsetof(PyTypeObject, tp_as_buffer)}') res[int(m.group(2))] = member M = max(res.keys())+1 for i in range(1,M): if i in res: out.write("%s,\n" % res[i]) else: out.write("{0, 0},\n") def main(): if len(sys.argv) == 2: with open(sys.argv[1], "w") as f: generate_typeslots(f) else: generate_typeslots() if __name__ == "__main__": main()