#include "Python.h"
#include "pycore_ast.h"
#include "pycore_parser.h"
#include "pycore_pystate.h"
#include "pycore_symtable.h"
#define _PY_DUMP_SYMTABLE …
#define GLOBAL_PARAM …
#define NONLOCAL_PARAM …
#define GLOBAL_AFTER_ASSIGN …
#define NONLOCAL_AFTER_ASSIGN …
#define GLOBAL_AFTER_USE …
#define NONLOCAL_AFTER_USE …
#define GLOBAL_ANNOT …
#define NONLOCAL_ANNOT …
#define IMPORT_STAR_WARNING …
#define NAMED_EXPR_COMP_IN_CLASS …
#define NAMED_EXPR_COMP_IN_TYPEVAR_BOUND …
#define NAMED_EXPR_COMP_IN_TYPEALIAS …
#define NAMED_EXPR_COMP_IN_TYPEPARAM …
#define NAMED_EXPR_COMP_CONFLICT …
#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT …
#define NAMED_EXPR_COMP_ITER_EXPR …
#define ANNOTATION_NOT_ALLOWED …
#define EXPR_NOT_ALLOWED_IN_TYPE_VARIABLE …
#define EXPR_NOT_ALLOWED_IN_TYPE_ALIAS …
#define EXPR_NOT_ALLOWED_IN_TYPE_PARAMETERS …
#define DUPLICATE_TYPE_PARAM …
#define ASYNC_WITH_OUTSIDE_ASYNC_FUNC …
#define ASYNC_FOR_OUTSIDE_ASYNC_FUNC …
#define LOCATION(x) …
#define SET_ERROR_LOCATION(FNAME, L) …
#define IS_ASYNC_DEF(st) …
static PySTEntryObject *
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
void *key, _Py_SourceLocation loc)
{ … }
static PyObject *
ste_repr(PySTEntryObject *ste)
{ … }
static void
ste_dealloc(PySTEntryObject *ste)
{ … }
#define OFF(x) …
static PyMemberDef ste_memberlist[] = …;
PyTypeObject PySTEntry_Type = …;
static int symtable_analyze(struct symtable *st);
static int symtable_enter_block(struct symtable *st, identifier name,
_Py_block_ty block, void *ast, _Py_SourceLocation loc);
static int symtable_exit_block(struct symtable *st);
static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
static int symtable_visit_expr(struct symtable *st, expr_ty s);
static int symtable_visit_type_param(struct symtable *st, type_param_ty s);
static int symtable_visit_genexp(struct symtable *st, expr_ty s);
static int symtable_visit_listcomp(struct symtable *st, expr_ty s);
static int symtable_visit_setcomp(struct symtable *st, expr_ty s);
static int symtable_visit_dictcomp(struct symtable *st, expr_ty s);
static int symtable_visit_arguments(struct symtable *st, arguments_ty);
static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
static int symtable_visit_alias(struct symtable *st, alias_ty);
static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
static int symtable_visit_keyword(struct symtable *st, keyword_ty);
static int symtable_visit_params(struct symtable *st, asdl_arg_seq *args);
static int symtable_visit_annotation(struct symtable *st, expr_ty annotation, void *key);
static int symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args);
static int symtable_implicit_arg(struct symtable *st, int pos);
static int symtable_visit_annotations(struct symtable *st, stmt_ty, arguments_ty, expr_ty,
struct _symtable_entry *parent_ste);
static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
static int symtable_visit_match_case(struct symtable *st, match_case_ty m);
static int symtable_visit_pattern(struct symtable *st, pattern_ty s);
static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty);
static int symtable_raise_if_not_coroutine(struct symtable *st, const char *msg, _Py_SourceLocation loc);
static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty);
static int symtable_add_def(struct symtable *st, PyObject *name, int flag, _Py_SourceLocation loc);
#if _PY_DUMP_SYMTABLE
static void _dump_symtable(PySTEntryObject* ste, PyObject* prefix)
{
const char *blocktype = "";
switch (ste->ste_type) {
case FunctionBlock: blocktype = "FunctionBlock"; break;
case ClassBlock: blocktype = "ClassBlock"; break;
case ModuleBlock: blocktype = "ModuleBlock"; break;
case AnnotationBlock: blocktype = "AnnotationBlock"; break;
case TypeVariableBlock: blocktype = "TypeVariableBlock"; break;
case TypeAliasBlock: blocktype = "TypeAliasBlock"; break;
case TypeParametersBlock: blocktype = "TypeParametersBlock"; break;
}
const char *comptype = "";
switch (ste->ste_comprehension) {
case ListComprehension: comptype = " ListComprehension"; break;
case DictComprehension: comptype = " DictComprehension"; break;
case SetComprehension: comptype = " SetComprehension"; break;
case GeneratorExpression: comptype = " GeneratorExpression"; break;
case NoComprehension: break;
}
PyObject* msg = PyUnicode_FromFormat(
(
"%U=== Symtable for %U ===\n"
"%U%s%s\n"
"%U%s%s%s%s%s%s%s%s%s%s%s\n"
"%Ulineno: %d col_offset: %d\n"
"%U--- Symbols ---\n"
),
prefix,
ste->ste_name,
prefix,
blocktype,
comptype,
prefix,
ste->ste_nested ? " nested" : "",
ste->ste_generator ? " generator" : "",
ste->ste_coroutine ? " coroutine" : "",
ste->ste_varargs ? " varargs" : "",
ste->ste_varkeywords ? " varkeywords" : "",
ste->ste_returns_value ? " returns_value" : "",
ste->ste_needs_class_closure ? " needs_class_closure" : "",
ste->ste_needs_classdict ? " needs_classdict" : "",
ste->ste_comp_inlined ? " comp_inlined" : "",
ste->ste_comp_iter_target ? " comp_iter_target" : "",
ste->ste_can_see_class_scope ? " can_see_class_scope" : "",
prefix,
ste->ste_loc.lineno,
ste->ste_loc.col_offset,
prefix
);
assert(msg != NULL);
printf("%s", PyUnicode_AsUTF8(msg));
Py_DECREF(msg);
PyObject *name, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(ste->ste_symbols, &pos, &name, &value)) {
int scope = _PyST_GetScope(ste, name);
long flags = _PyST_GetSymbol(ste, name);
printf("%s %s: ", PyUnicode_AsUTF8(prefix), PyUnicode_AsUTF8(name));
if (flags & DEF_GLOBAL) printf(" DEF_GLOBAL");
if (flags & DEF_LOCAL) printf(" DEF_LOCAL");
if (flags & DEF_PARAM) printf(" DEF_PARAM");
if (flags & DEF_NONLOCAL) printf(" DEF_NONLOCAL");
if (flags & USE) printf(" USE");
if (flags & DEF_FREE_CLASS) printf(" DEF_FREE_CLASS");
if (flags & DEF_IMPORT) printf(" DEF_IMPORT");
if (flags & DEF_ANNOT) printf(" DEF_ANNOT");
if (flags & DEF_COMP_ITER) printf(" DEF_COMP_ITER");
if (flags & DEF_TYPE_PARAM) printf(" DEF_TYPE_PARAM");
if (flags & DEF_COMP_CELL) printf(" DEF_COMP_CELL");
switch (scope) {
case LOCAL: printf(" LOCAL"); break;
case GLOBAL_EXPLICIT: printf(" GLOBAL_EXPLICIT"); break;
case GLOBAL_IMPLICIT: printf(" GLOBAL_IMPLICIT"); break;
case FREE: printf(" FREE"); break;
case CELL: printf(" CELL"); break;
}
printf("\n");
}
printf("%s--- Children ---\n", PyUnicode_AsUTF8(prefix));
PyObject *new_prefix = PyUnicode_FromFormat(" %U", prefix);
assert(new_prefix != NULL);
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(ste->ste_children); i++) {
PyObject *child = PyList_GetItem(ste->ste_children, i);
assert(child != NULL && PySTEntry_Check(child));
_dump_symtable((PySTEntryObject *)child, new_prefix);
}
Py_DECREF(new_prefix);
}
static void dump_symtable(PySTEntryObject* ste)
{
PyObject *empty = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
assert(empty != NULL);
_dump_symtable(ste, empty);
Py_DECREF(empty);
}
#endif
#define DUPLICATE_ARGUMENT …
static struct symtable *
symtable_new(void)
{ … }
struct symtable *
_PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future)
{ … }
void
_PySymtable_Free(struct symtable *st)
{ … }
PySTEntryObject *
_PySymtable_Lookup(struct symtable *st, void *key)
{ … }
int
_PySymtable_LookupOptional(struct symtable *st, void *key,
PySTEntryObject **out)
{ … }
long
_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name)
{ … }
int
_PyST_GetScope(PySTEntryObject *ste, PyObject *name)
{ … }
int
_PyST_IsFunctionLike(PySTEntryObject *ste)
{ … }
static int
error_at_directive(PySTEntryObject *ste, PyObject *name)
{ … }
#define SET_SCOPE …
static int
analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
PyObject *bound, PyObject *local, PyObject *free,
PyObject *global, PyObject *type_params, PySTEntryObject *class_entry)
{ … }
static int
is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
{ … }
static int
inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
PyObject *scopes, PyObject *comp_free,
PyObject *inlined_cells)
{ … }
#undef SET_SCOPE
static int
analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
{ … }
static int
drop_class_free(PySTEntryObject *ste, PyObject *free)
{ … }
static int
update_symbols(PyObject *symbols, PyObject *scopes,
PyObject *bound, PyObject *free,
PyObject *inlined_cells, int classflag)
{ … }
static int
analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
PyObject *global, PyObject *type_params,
PySTEntryObject *class_entry, PyObject **child_free);
static int
analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
PyObject *global, PyObject *type_params,
PySTEntryObject *class_entry)
{ … }
static int
analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
PyObject *global, PyObject *type_params,
PySTEntryObject *class_entry, PyObject** child_free)
{ … }
static int
symtable_analyze(struct symtable *st)
{ … }
static int
symtable_exit_block(struct symtable *st)
{ … }
static int
symtable_enter_existing_block(struct symtable *st, PySTEntryObject* ste)
{ … }
static int
symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
void *ast, _Py_SourceLocation loc)
{ … }
static long
symtable_lookup_entry(struct symtable *st, PySTEntryObject *ste, PyObject *name)
{ … }
static long
symtable_lookup(struct symtable *st, PyObject *name)
{ … }
static int
symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste,
_Py_SourceLocation loc)
{ … }
static int
check_name(struct symtable *st, PyObject *name, _Py_SourceLocation loc,
expr_context_ty ctx)
{ … }
static int
check_keywords(struct symtable *st, asdl_keyword_seq *keywords)
{ … }
static int
check_kwd_patterns(struct symtable *st, pattern_ty p)
{ … }
static int
symtable_add_def_ctx(struct symtable *st, PyObject *name, int flag,
_Py_SourceLocation loc, expr_context_ty ctx)
{ … }
static int
symtable_add_def(struct symtable *st, PyObject *name, int flag,
_Py_SourceLocation loc)
{ … }
static int
symtable_enter_type_param_block(struct symtable *st, identifier name,
void *ast, int has_defaults, int has_kwdefaults,
enum _stmt_kind kind, _Py_SourceLocation loc)
{ … }
#define VISIT(ST, TYPE, V) …
#define VISIT_SEQ(ST, TYPE, SEQ) …
#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) …
#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) …
#define ENTER_RECURSIVE(ST) …
#define LEAVE_RECURSIVE(ST) …
static int
symtable_record_directive(struct symtable *st, identifier name, _Py_SourceLocation loc)
{ … }
static int
has_kwonlydefaults(asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
{ … }
static int
check_import_from(struct symtable *st, stmt_ty s)
{ … }
static bool
allows_top_level_await(struct symtable *st)
{ … }
static void
maybe_set_ste_coroutine_for_module(struct symtable *st, stmt_ty s)
{ … }
static int
symtable_visit_stmt(struct symtable *st, stmt_ty s)
{ … }
static int
symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
{ … }
static int
symtable_handle_namedexpr(struct symtable *st, expr_ty e)
{ … }
static int
symtable_visit_expr(struct symtable *st, expr_ty e)
{ … }
static int
symtable_visit_type_param_bound_or_default(
struct symtable *st, expr_ty e, identifier name,
void *key, const char *ste_scope_info)
{ … }
static int
symtable_visit_type_param(struct symtable *st, type_param_ty tp)
{ … }
static int
symtable_visit_pattern(struct symtable *st, pattern_ty p)
{ … }
static int
symtable_implicit_arg(struct symtable *st, int pos)
{ … }
static int
symtable_visit_params(struct symtable *st, asdl_arg_seq *args)
{ … }
static int
symtable_visit_annotation(struct symtable *st, expr_ty annotation, void *key)
{ … }
static int
symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args)
{ … }
static int
symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_ty returns,
struct _symtable_entry *function_ste)
{ … }
static int
symtable_visit_arguments(struct symtable *st, arguments_ty a)
{ … }
static int
symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
{ … }
static int
symtable_visit_withitem(struct symtable *st, withitem_ty item)
{ … }
static int
symtable_visit_match_case(struct symtable *st, match_case_ty m)
{ … }
static int
symtable_visit_alias(struct symtable *st, alias_ty a)
{ … }
static int
symtable_visit_comprehension(struct symtable *st, comprehension_ty lc)
{ … }
static int
symtable_visit_keyword(struct symtable *st, keyword_ty k)
{ … }
static int
symtable_handle_comprehension(struct symtable *st, expr_ty e,
identifier scope_name, asdl_comprehension_seq *generators,
expr_ty elt, expr_ty value)
{ … }
static int
symtable_visit_genexp(struct symtable *st, expr_ty e)
{ … }
static int
symtable_visit_listcomp(struct symtable *st, expr_ty e)
{ … }
static int
symtable_visit_setcomp(struct symtable *st, expr_ty e)
{ … }
static int
symtable_visit_dictcomp(struct symtable *st, expr_ty e)
{ … }
static int
symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e)
{ … }
static int
symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) { … }
static int
symtable_raise_if_not_coroutine(struct symtable *st, const char *msg, _Py_SourceLocation loc) { … }
struct symtable *
_Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
int start, PyCompilerFlags *flags)
{ … }
PyObject *
_Py_MaybeMangle(PyObject *privateobj, PySTEntryObject *ste, PyObject *name)
{ … }
PyObject *
_Py_Mangle(PyObject *privateobj, PyObject *ident)
{ … }