| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -680,5 +680,13 @@ def error(message, filename=None, location=None): | |||
| 680 | 680 | perror("unexpected error: %s" % err) | |
| 681 | 681 | raise | |
| 682 | 682 | ||
| 683 | + def _generate_tokens_from_c_tokenizer(source): | ||
| 684 | + """Tokenize a source reading Python code as unicode strings using the internal C tokenizer""" | ||
| 685 | + import _tokenize as c_tokenizer | ||
| 686 | + for info in c_tokenizer.TokenizerIter(source): | ||
| 687 | + tok, type, lineno, end_lineno, col_off, end_col_off, line = info | ||
| 688 | + yield TokenInfo(type, tok, (lineno, col_off), (end_lineno, end_col_off), line) | ||
| 689 | + | ||
| 690 | + | ||
| 683 | 691 | if __name__ == "__main__": | |
| 684 | 692 | main() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -339,6 +339,7 @@ PARSER_HEADERS= \ | |||
| 339 | 339 | PYTHON_OBJS= \ | |
| 340 | 340 | Python/_warnings.o \ | |
| 341 | 341 | Python/Python-ast.o \ | |
| 342 | + Python/Python-tokenize.o \ | ||
| 342 | 343 | Python/asdl.o \ | |
| 343 | 344 | Python/ast.o \ | |
| 344 | 345 | Python/ast_opt.o \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ extern PyObject* PyMarshal_Init(void); | |||
| 28 | 28 | extern PyObject* PyInit__imp(void); | |
| 29 | 29 | extern PyObject* PyInit_gc(void); | |
| 30 | 30 | extern PyObject* PyInit__ast(void); | |
| 31 | + extern PyObject* PyInit__tokenize(void); | ||
| 31 | 32 | extern PyObject* _PyWarnings_Init(void); | |
| 32 | 33 | extern PyObject* PyInit__string(void); | |
| 33 | 34 | ||
@@ -44,6 +45,9 @@ struct _inittab _PyImport_Inittab[] = { | |||
| 44 | 45 | /* This lives in Python/Python-ast.c */ | |
| 45 | 46 | {"_ast", PyInit__ast}, | |
| 46 | 47 | ||
| 48 | + /* This lives in Python/Python-tokenizer.c */ | ||
| 49 | + {"_tokenize", PyInit__tokenize}, | ||
| 50 | + | ||
| 47 | 51 | /* These entries are here for sys.builtin_module_names */ | |
| 48 | 52 | {"builtins", NULL}, | |
| 49 | 53 | {"sys", NULL}, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,9 +72,8 @@ extern PyObject* _PyWarnings_Init(void); | |||
| 72 | 72 | extern PyObject* PyInit__string(void); | |
| 73 | 73 | extern PyObject* PyInit__stat(void); | |
| 74 | 74 | extern PyObject* PyInit__opcode(void); | |
| 75 | - | ||
| 76 | 75 | extern PyObject* PyInit__contextvars(void); | |
| 77 | - | ||
| 76 | + extern PyObject* PyInit__tokenize(void); | ||
| 78 | 77 | ||
| 79 | 78 | /* tools/freeze/makeconfig.py marker for additional "extern" */ | |
| 80 | 79 | /* -- ADDMODULE MARKER 1 -- */ | |
@@ -83,7 +82,6 @@ extern PyObject* PyMarshal_Init(void); | |||
| 83 | 82 | extern PyObject* PyInit__imp(void); | |
| 84 | 83 | ||
| 85 | 84 | struct _inittab _PyImport_Inittab[] = { | |
| 86 | - | ||
| 87 | 85 | {"_abc", PyInit__abc}, | |
| 88 | 86 | {"array", PyInit_array}, | |
| 89 | 87 | {"_ast", PyInit__ast}, | |
@@ -105,6 +103,7 @@ struct _inittab _PyImport_Inittab[] = { | |||
| 105 | 103 | {"_blake2", PyInit__blake2}, | |
| 106 | 104 | {"time", PyInit_time}, | |
| 107 | 105 | {"_thread", PyInit__thread}, | |
| 106 | + {"_tokenize", PyInit__tokenize}, | ||
| 108 | 107 | {"_typing", PyInit__typing}, | |
| 109 | 108 | {"_statistics", PyInit__statistics}, | |
| 110 | 109 | #ifdef WIN32 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -488,6 +488,7 @@ | |||
| 488 | 488 | <ClCompile Include="..\Python\pystrtod.c" /> | |
| 489 | 489 | <ClCompile Include="..\Python\dtoa.c" /> | |
| 490 | 490 | <ClCompile Include="..\Python\Python-ast.c" /> | |
| 491 | + <ClCompile Include="..\Python\Python-tokenize.c" /> | ||
| 491 | 492 | <ClCompile Include="..\Python\pythonrun.c" /> | |
| 492 | 493 | <ClCompile Include="..\Python\specialize.c" /> | |
| 493 | 494 | <ClCompile Include="..\Python\suggestions.c" /> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,195 @@ | |||
| 1 | + #include "Python.h" | ||
| 2 | + #include "../Parser/tokenizer.h" | ||
| 3 | + | ||
| 4 | + static struct PyModuleDef _tokenizemodule; | ||
| 5 | + | ||
| 6 | + typedef struct { | ||
| 7 | + PyTypeObject* TokenizerIter; | ||
| 8 | + } tokenize_state; | ||
| 9 | + | ||
| 10 | + static tokenize_state* | ||
| 11 | + get_tokenize_state(PyObject* module) | ||
| 12 | + { | ||
| 13 | + return (tokenize_state*)PyModule_GetState(module); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + #define _tokenize_get_state_by_type(type) \ | ||
| 17 | + get_tokenize_state(_PyType_GetModuleByDef(type, &_tokenizemodule)) | ||
| 18 | + | ||
| 19 | + #include "clinic/Python-tokenize.c.h" | ||
| 20 | + | ||
| 21 | + /*[clinic input] | ||
| 22 | + module _tokenizer | ||
| 23 | + class _tokenizer.tokenizeriter "tokenizeriterobject *" "_tokenize_get_state_by_type(type)->TokenizerIter" | ||
| 24 | + [clinic start generated code]*/ | ||
| 25 | + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=96d98ee2fef7a8bc]*/ | ||
| 26 | + | ||
| 27 | + typedef struct { | ||
| 28 | + PyObject_HEAD | ||
| 29 | + struct tok_state* tok; | ||
| 30 | + } tokenizeriterobject; | ||
| 31 | + | ||
| 32 | + /*[clinic input] | ||
| 33 | + @classmethod | ||
| 34 | + _tokenizer.tokenizeriter.__new__ as tokenizeriter_new | ||
| 35 | + | ||
| 36 | + source: str | ||
| 37 | + [clinic start generated code]*/ | ||
| 38 | + | ||
| 39 | + static PyObject * | ||
| 40 | + tokenizeriter_new_impl(PyTypeObject *type, const char *source) | ||
| 41 | + /*[clinic end generated code: output=7fd9f46cf9263cbb input=4384b368407375c6]*/ | ||
| 42 | + { | ||
| 43 | + tokenizeriterobject* self = (tokenizeriterobject*)type->tp_alloc(type, 0); | ||
| 44 | + if (self == NULL) { | ||
| 45 | + return NULL; | ||
| 46 | + } | ||
| 47 | + PyObject* filename = PyUnicode_FromString("<string>"); | ||
| 48 | + if (filename == NULL) { | ||
| 49 | + return NULL; | ||
| 50 | + } | ||
| 51 | + self->tok = PyTokenizer_FromUTF8(source, 1); | ||
| 52 | + if (self->tok == NULL) { | ||
| 53 | + return NULL; | ||
| 54 | + } | ||
| 55 | + self->tok->filename = filename; | ||
| 56 | + return (PyObject*)self; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + static PyObject* | ||
| 60 | + tokenizeriter_next(tokenizeriterobject* it) | ||
| 61 | + { | ||
| 62 | + const char* start; | ||
| 63 | + const char* end; | ||
| 64 | + int type = PyTokenizer_Get(it->tok, &start, &end); | ||
| 65 | + if (type == ERRORTOKEN && PyErr_Occurred()) { | ||
| 66 | + return NULL; | ||
| 67 | + } | ||
| 68 | + if (type == ERRORTOKEN || type == ENDMARKER) { | ||
| 69 | + PyErr_SetString(PyExc_StopIteration, "EOF"); | ||
| 70 | + return NULL; | ||
| 71 | + } | ||
| 72 | + PyObject* str = NULL; | ||
| 73 | + if (start == NULL || end == NULL) { | ||
| 74 | + str = PyUnicode_FromString(""); | ||
| 75 | + } else { | ||
| 76 | + str = PyUnicode_FromStringAndSize(start, end - start); | ||
| 77 | + } | ||
| 78 | + if (str == NULL) { | ||
| 79 | + return NULL; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + Py_ssize_t size = it->tok->inp - it->tok->buf; | ||
| 83 | + PyObject* line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace"); | ||
| 84 | + if (line == NULL) { | ||
| 85 | + Py_DECREF(str); | ||
| 86 | + return NULL; | ||
| 87 | + } | ||
| 88 | + const char* line_start = type == STRING ? it->tok->multi_line_start : it->tok->line_start; | ||
| 89 | + int lineno = type == STRING ? it->tok->first_lineno : it->tok->lineno; | ||
| 90 | + int end_lineno = it->tok->lineno; | ||
| 91 | + int col_offset = -1; | ||
| 92 | + int end_col_offset = -1; | ||
| 93 | + if (start != NULL && start >= line_start) { | ||
| 94 | + col_offset = (int)(start - line_start); | ||
| 95 | + } | ||
| 96 | + if (end != NULL && end >= it->tok->line_start) { | ||
| 97 | + end_col_offset = (int)(end - it->tok->line_start); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + return Py_BuildValue("(NiiiiiN)", str, type, lineno, end_lineno, col_offset, end_col_offset, line); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + static void | ||
| 104 | + tokenizeriter_dealloc(tokenizeriterobject* it) | ||
| 105 | + { | ||
| 106 | + PyTypeObject* tp = Py_TYPE(it); | ||
| 107 | + PyTokenizer_Free(it->tok); | ||
| 108 | + tp->tp_free(it); | ||
| 109 | + Py_DECREF(tp); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + static PyType_Slot tokenizeriter_slots[] = { | ||
| 113 | + {Py_tp_new, tokenizeriter_new}, | ||
| 114 | + {Py_tp_dealloc, tokenizeriter_dealloc}, | ||
| 115 | + {Py_tp_getattro, PyObject_GenericGetAttr}, | ||
| 116 | + {Py_tp_iter, PyObject_SelfIter}, | ||
| 117 | + {Py_tp_iternext, tokenizeriter_next}, | ||
| 118 | + {0, NULL}, | ||
| 119 | + }; | ||
| 120 | + | ||
| 121 | + static PyType_Spec tokenizeriter_spec = { | ||
| 122 | + .name = "_tokenize.TokenizerIter", | ||
| 123 | + .basicsize = sizeof(tokenizeriterobject), | ||
| 124 | + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), | ||
| 125 | + .slots = tokenizeriter_slots, | ||
| 126 | + }; | ||
| 127 | + | ||
| 128 | + | ||
| 129 | + static int | ||
| 130 | + tokenizemodule_exec(PyObject* m) | ||
| 131 | + { | ||
| 132 | + tokenize_state* state = get_tokenize_state(m); | ||
| 133 | + if (state == NULL) { | ||
| 134 | + return -1; | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + state->TokenizerIter = (PyTypeObject *)PyType_FromModuleAndSpec( | ||
| 138 | + m, &tokenizeriter_spec, NULL); | ||
| 139 | + if (state->TokenizerIter == NULL) { | ||
| 140 | + return -1; | ||
| 141 | + } | ||
| 142 | + if (PyModule_AddType(m, state->TokenizerIter) < 0) { | ||
| 143 | + return -1; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + return 0; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + static PyMethodDef tokenize_methods[] = { | ||
| 150 | + {NULL, NULL, 0, NULL} /* Sentinel */ | ||
| 151 | + }; | ||
| 152 | + | ||
| 153 | + static PyModuleDef_Slot tokenizemodule_slots[] = { | ||
| 154 | + {Py_mod_exec, tokenizemodule_exec}, | ||
| 155 | + {0, NULL} | ||
| 156 | + }; | ||
| 157 | + | ||
| 158 | + static int | ||
| 159 | + tokenizemodule_traverse(PyObject *m, visitproc visit, void *arg) | ||
| 160 | + { | ||
| 161 | + tokenize_state *state = get_tokenize_state(m); | ||
| 162 | + Py_VISIT(state->TokenizerIter); | ||
| 163 | + return 0; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + static int | ||
| 167 | + tokenizemodule_clear(PyObject *m) | ||
| 168 | + { | ||
| 169 | + tokenize_state *state = get_tokenize_state(m); | ||
| 170 | + Py_CLEAR(state->TokenizerIter); | ||
| 171 | + return 0; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + static void | ||
| 175 | + tokenizemodule_free(void *m) | ||
| 176 | + { | ||
| 177 | + tokenizemodule_clear((PyObject *)m); | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + static struct PyModuleDef _tokenizemodule = { | ||
| 181 | + PyModuleDef_HEAD_INIT, | ||
| 182 | + .m_name = "_tokenize", | ||
| 183 | + .m_size = sizeof(tokenize_state), | ||
| 184 | + .m_slots = tokenizemodule_slots, | ||
| 185 | + .m_methods = tokenize_methods, | ||
| 186 | + .m_traverse = tokenizemodule_traverse, | ||
| 187 | + .m_clear = tokenizemodule_clear, | ||
| 188 | + .m_free = tokenizemodule_free, | ||
| 189 | + }; | ||
| 190 | + | ||
| 191 | + PyMODINIT_FUNC | ||
| 192 | + PyInit__tokenize(void) | ||
| 193 | + { | ||
| 194 | + return PyModuleDef_Init(&_tokenizemodule); | ||
| 195 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -80,6 +80,7 @@ static const char* _Py_stdlib_module_names[] = { | |||
| 80 | 80 | "_thread", | |
| 81 | 81 | "_threading_local", | |
| 82 | 82 | "_tkinter", | |
| 83 | + "_tokenize", | ||
| 83 | 84 | "_tracemalloc", | |
| 84 | 85 | "_typing", | |
| 85 | 86 | "_uuid", | |
| Back | FazBrowse Home | New Git URL |
0 commit comments