Back to index

python3.2  3.2.2
Defines | Functions | Variables
symtable.c File Reference
#include "Python.h"
#include "Python-ast.h"
#include "code.h"
#include "symtable.h"
#include "structmember.h"

Go to the source code of this file.

Defines

#define GLOBAL_AFTER_ASSIGN   "name '%.400s' is assigned to before global declaration"
#define NONLOCAL_AFTER_ASSIGN   "name '%.400s' is assigned to before nonlocal declaration"
#define GLOBAL_AFTER_USE   "name '%.400s' is used prior to global declaration"
#define NONLOCAL_AFTER_USE   "name '%.400s' is used prior to nonlocal declaration"
#define IMPORT_STAR_WARNING   "import * only allowed at module level"
#define RETURN_VAL_IN_GENERATOR   "'return' with argument inside generator"
#define OFF(x)   offsetof(PySTEntryObject, x)
#define GET_IDENTIFIER(VAR)   ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
#define DUPLICATE_ARGUMENT   "duplicate argument '%U' in function definition"
#define SET_SCOPE(DICT, NAME, I)
#define VISIT(ST, TYPE, V)
#define VISIT_IN_BLOCK(ST, TYPE, V, S)
#define VISIT_SEQ(ST, TYPE, SEQ)
#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S)
#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START)
#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S)
#define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS)

Functions

static PySTEntryObjectste_new (struct symtable *st, identifier name, _Py_block_ty block, void *key, int lineno, int col_offset)
static PyObjectste_repr (PySTEntryObject *ste)
static void ste_dealloc (PySTEntryObject *ste)
static int symtable_analyze (struct symtable *st)
static int symtable_warn (struct symtable *st, char *msg, int lineno)
static int symtable_enter_block (struct symtable *st, identifier name, _Py_block_ty block, void *ast, int lineno, int col_offset)
static int symtable_exit_block (struct symtable *st, void *ast)
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_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_slice (struct symtable *st, slice_ty)
static int symtable_visit_params (struct symtable *st, asdl_seq *args)
static int symtable_visit_argannotations (struct symtable *st, asdl_seq *args)
static int symtable_implicit_arg (struct symtable *st, int pos)
static int symtable_visit_annotations (struct symtable *st, stmt_ty s)
static struct symtablesymtable_new (void)
struct symtablePySymtable_Build (mod_ty mod, const char *filename, PyFutureFeatures *future)
void PySymtable_Free (struct symtable *st)
PySTEntryObjectPySymtable_Lookup (struct symtable *st, void *key)
int PyST_GetScope (PySTEntryObject *ste, PyObject *name)
static int analyze_name (PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, PyObject *bound, PyObject *local, PyObject *free, PyObject *global)
static int analyze_cells (PyObject *scopes, PyObject *free, const char *restricted)
static int check_unoptimized (const PySTEntryObject *ste)
static int update_symbols (PyObject *symbols, PyObject *scopes, PyObject *bound, PyObject *free, int classflag)
static int analyze_child_block (PySTEntryObject *entry, PyObject *bound, PyObject *free, PyObject *global, PyObject *child_free)
static int analyze_block (PySTEntryObject *ste, PyObject *bound, PyObject *free, PyObject *global)
static long symtable_lookup (struct symtable *st, PyObject *name)
static int symtable_add_def (struct symtable *st, PyObject *name, int flag)
static int symtable_new_tmpname (struct symtable *st)
static int symtable_handle_comprehension (struct symtable *st, expr_ty e, identifier scope_name, asdl_seq *generators, expr_ty elt, expr_ty value)

Variables

static PyMemberDef ste_memberlist []
PyTypeObject PySTEntry_Type
static identifier top = NULL
static identifier lambda = NULL
static identifier genexpr = NULL
static identifier listcomp = NULL
static identifier setcomp = NULL
static identifier dictcomp = NULL
static identifier __class__ = NULL
static identifier __locals__ = NULL

Define Documentation

#define DUPLICATE_ARGUMENT   "duplicate argument '%U' in function definition"

Definition at line 197 of file symtable.c.

#define GET_IDENTIFIER (   VAR)    ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))

Definition at line 194 of file symtable.c.

#define GLOBAL_AFTER_ASSIGN   "name '%.400s' is assigned to before global declaration"

Definition at line 8 of file symtable.c.

#define GLOBAL_AFTER_USE   "name '%.400s' is used prior to global declaration"

Definition at line 14 of file symtable.c.

#define IMPORT_STAR_WARNING   "import * only allowed at module level"

Definition at line 20 of file symtable.c.

#define NONLOCAL_AFTER_ASSIGN   "name '%.400s' is assigned to before nonlocal declaration"

Definition at line 11 of file symtable.c.

#define NONLOCAL_AFTER_USE   "name '%.400s' is used prior to nonlocal declaration"

Definition at line 17 of file symtable.c.

#define OFF (   x)    offsetof(PySTEntryObject, x)

Definition at line 110 of file symtable.c.

#define RETURN_VAL_IN_GENERATOR   "'return' with argument inside generator"

Definition at line 22 of file symtable.c.

#define SET_SCOPE (   DICT,
  NAME,
  I 
)
Value:
{ \
    PyObject *o = PyLong_FromLong(I); \
    if (!o) \
        return 0; \
    if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
        Py_DECREF(o); \
        return 0; \
    } \
    Py_DECREF(o); \
}

Definition at line 369 of file symtable.c.

#define VISIT (   ST,
  TYPE,
 
)
Value:
if (!symtable_visit_ ## TYPE((ST), (V))) \
        return 0;

Definition at line 1022 of file symtable.c.

#define VISIT_IN_BLOCK (   ST,
  TYPE,
  V,
  S 
)
Value:
if (!symtable_visit_ ## TYPE((ST), (V))) { \
        symtable_exit_block((ST), (S)); \
        return 0; \
    }

Definition at line 1026 of file symtable.c.

#define VISIT_KWONLYDEFAULTS (   ST,
  KW_DEFAULTS 
)
Value:
{ \
    int i = 0; \
    asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \
    for (i = 0; i < asdl_seq_LEN(seq); i++) { \
        expr_ty elt = (expr_ty)asdl_seq_GET(seq, i); \
        if (!elt) continue; /* can be NULL */ \
        if (!symtable_visit_expr((ST), elt)) \
            return 0; \
    } \
}

Definition at line 1076 of file symtable.c.

#define VISIT_SEQ (   ST,
  TYPE,
  SEQ 
)
Value:
{ \
    int i; \
    asdl_seq *seq = (SEQ); /* avoid variable capture */ \
    for (i = 0; i < asdl_seq_LEN(seq); i++) { \
        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
        if (!symtable_visit_ ## TYPE((ST), elt)) \
            return 0; \
    } \
}

Definition at line 1032 of file symtable.c.

#define VISIT_SEQ_IN_BLOCK (   ST,
  TYPE,
  SEQ,
  S 
)
Value:
{ \
    int i; \
    asdl_seq *seq = (SEQ); /* avoid variable capture */ \
    for (i = 0; i < asdl_seq_LEN(seq); i++) { \
        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
        if (!symtable_visit_ ## TYPE((ST), elt)) { \
            symtable_exit_block((ST), (S)); \
            return 0; \
        } \
    } \
}

Definition at line 1042 of file symtable.c.

#define VISIT_SEQ_TAIL (   ST,
  TYPE,
  SEQ,
  START 
)
Value:
{ \
    int i; \
    asdl_seq *seq = (SEQ); /* avoid variable capture */ \
    for (i = (START); i < asdl_seq_LEN(seq); i++) { \
        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
        if (!symtable_visit_ ## TYPE((ST), elt)) \
            return 0; \
    } \
}

Definition at line 1054 of file symtable.c.

#define VISIT_SEQ_TAIL_IN_BLOCK (   ST,
  TYPE,
  SEQ,
  START,
  S 
)
Value:
{ \
    int i; \
    asdl_seq *seq = (SEQ); /* avoid variable capture */ \
    for (i = (START); i < asdl_seq_LEN(seq); i++) { \
        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
        if (!symtable_visit_ ## TYPE((ST), elt)) { \
            symtable_exit_block((ST), (S)); \
            return 0; \
        } \
    } \
}

Definition at line 1064 of file symtable.c.


Function Documentation

static int analyze_block ( PySTEntryObject ste,
PyObject bound,
PyObject free,
PyObject global 
) [static]

Definition at line 658 of file symtable.c.

{
    PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL;
    PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL;
    PyObject *temp;
    int i, success = 0;
    Py_ssize_t pos = 0;

    local = PySet_New(NULL);  /* collect new names bound in block */
    if (!local)
        goto error;
    scopes = PyDict_New();  /* collect scopes defined for each name */
    if (!scopes)
        goto error;

    /* Allocate new global and bound variable dictionaries.  These
       dictionaries hold the names visible in nested blocks.  For
       ClassBlocks, the bound and global names are initialized
       before analyzing names, because class bindings aren't
       visible in methods.  For other blocks, they are initialized
       after names are analyzed.
     */

    /* TODO(jhylton): Package these dicts in a struct so that we
       can write reasonable helper functions?
    */
    newglobal = PySet_New(NULL);
    if (!newglobal)
        goto error;
    newfree = PySet_New(NULL);
    if (!newfree)
        goto error;
    newbound = PySet_New(NULL);
    if (!newbound)
        goto error;

    /* Class namespace has no effect on names visible in
       nested functions, so populate the global and bound
       sets to be passed to child blocks before analyzing
       this one.
     */
    if (ste->ste_type == ClassBlock) {
        /* Pass down known globals */
        temp = PyNumber_InPlaceOr(newglobal, global);
        if (!temp)
            goto error;
        Py_DECREF(temp);
        /* Pass down previously bound symbols */
        if (bound) {
            temp = PyNumber_InPlaceOr(newbound, bound);
            if (!temp)
                goto error;
            Py_DECREF(temp);
        }
    }

    while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
        long flags = PyLong_AS_LONG(v);
        if (!analyze_name(ste, scopes, name, flags,
                          bound, local, free, global))
            goto error;
    }

    /* Populate global and bound sets to be passed to children. */
    if (ste->ste_type != ClassBlock) {
        /* Add function locals to bound set */
        if (ste->ste_type == FunctionBlock) {
            temp = PyNumber_InPlaceOr(newbound, local);
            if (!temp)
                goto error;
            Py_DECREF(temp);
        }
        /* Pass down previously bound symbols */
        if (bound) {
            temp = PyNumber_InPlaceOr(newbound, bound);
            if (!temp)
                goto error;
            Py_DECREF(temp);
        }
        /* Pass down known globals */
        temp = PyNumber_InPlaceOr(newglobal, global);
        if (!temp)
            goto error;
        Py_DECREF(temp);
    }
    else {
        /* Special-case __class__ */
        if (!GET_IDENTIFIER(__class__))
            goto error;
        assert(PySet_Contains(local, __class__) == 1);
        if (PySet_Add(newbound, __class__) < 0)
            goto error;
    }

    /* Recursively call analyze_block() on each child block.

       newbound, newglobal now contain the names visible in
       nested blocks.  The free variables in the children will
       be collected in allfree.
    */
    allfree = PySet_New(NULL);
    if (!allfree)
        goto error;
    for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
        PyObject *c = PyList_GET_ITEM(ste->ste_children, i);
        PySTEntryObject* entry;
        assert(c && PySTEntry_Check(c));
        entry = (PySTEntryObject*)c;
        if (!analyze_child_block(entry, newbound, newfree, newglobal,
                                 allfree))
            goto error;
        /* Check if any children have free variables */
        if (entry->ste_free || entry->ste_child_free)
            ste->ste_child_free = 1;
    }

    temp = PyNumber_InPlaceOr(newfree, allfree);
    if (!temp)
        goto error;
    Py_DECREF(temp);

    /* Check if any local variables must be converted to cell variables */
    if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree,
                                                         NULL))
        goto error;
    else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree,
                                                           "__class__"))
        goto error;
    /* Records the results of the analysis in the symbol table entry */
    if (!update_symbols(ste->ste_symbols, scopes, bound, newfree,
                        ste->ste_type == ClassBlock))
        goto error;
    if (!check_unoptimized(ste))
        goto error;

    temp = PyNumber_InPlaceOr(free, newfree);
    if (!temp)
        goto error;
    Py_DECREF(temp);
    success = 1;
 error:
    Py_XDECREF(scopes);
    Py_XDECREF(local);
    Py_XDECREF(newbound);
    Py_XDECREF(newglobal);
    Py_XDECREF(newfree);
    Py_XDECREF(allfree);
    if (!success)
        assert(PyErr_Occurred());
    return success;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int analyze_cells ( PyObject scopes,
PyObject free,
const char *  restricted 
) [static]

Definition at line 483 of file symtable.c.

{
    PyObject *name, *v, *v_cell;
    int success = 0;
    Py_ssize_t pos = 0;

    v_cell = PyLong_FromLong(CELL);
    if (!v_cell)
        return 0;
    while (PyDict_Next(scopes, &pos, &name, &v)) {
        long scope;
        assert(PyLong_Check(v));
        scope = PyLong_AS_LONG(v);
        if (scope != LOCAL)
            continue;
        if (!PySet_Contains(free, name))
            continue;
        if (restricted != NULL &&
            PyUnicode_CompareWithASCIIString(name, restricted))
            continue;
        /* Replace LOCAL with CELL for this name, and remove
           from free. It is safe to replace the value of name
           in the dict, because it will not cause a resize.
         */
        if (PyDict_SetItem(scopes, name, v_cell) < 0)
            goto error;
        if (PySet_Discard(free, name) < 0)
            goto error;
    }
    success = 1;
 error:
    Py_DECREF(v_cell);
    return success;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int analyze_child_block ( PySTEntryObject entry,
PyObject bound,
PyObject free,
PyObject global,
PyObject child_free 
) [static]

Definition at line 812 of file symtable.c.

{
    PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL;
    PyObject *temp;

    /* Copy the bound and global dictionaries.

       These dictionary are used by all blocks enclosed by the
       current block.  The analyze_block() call modifies these
       dictionaries.

    */
    temp_bound = PySet_New(bound);
    if (!temp_bound)
        goto error;
    temp_free = PySet_New(free);
    if (!temp_free)
        goto error;
    temp_global = PySet_New(global);
    if (!temp_global)
        goto error;

    if (!analyze_block(entry, temp_bound, temp_free, temp_global))
        goto error;
    temp = PyNumber_InPlaceOr(child_free, temp_free);
    if (!temp)
        goto error;
    Py_DECREF(temp);
    Py_DECREF(temp_bound);
    Py_DECREF(temp_free);
    Py_DECREF(temp_global);
    return 1;
 error:
    Py_XDECREF(temp_bound);
    Py_XDECREF(temp_free);
    Py_XDECREF(temp_global);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int analyze_name ( PySTEntryObject ste,
PyObject scopes,
PyObject name,
long  flags,
PyObject bound,
PyObject local,
PyObject free,
PyObject global 
) [static]

Definition at line 388 of file symtable.c.

{
    if (flags & DEF_GLOBAL) {
        if (flags & DEF_PARAM) {
            PyErr_Format(PyExc_SyntaxError,
                        "name '%U' is parameter and global",
                        name);
            PyErr_SyntaxLocationEx(ste->ste_table->st_filename,
                                   ste->ste_lineno, ste->ste_col_offset);

            return 0;
        }
        if (flags & DEF_NONLOCAL) {
            PyErr_Format(PyExc_SyntaxError,
                         "name '%U' is nonlocal and global",
                         name);
            return 0;
        }
        SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
        if (PySet_Add(global, name) < 0)
            return 0;
        if (bound && (PySet_Discard(bound, name) < 0))
            return 0;
        return 1;
    }
    if (flags & DEF_NONLOCAL) {
        if (flags & DEF_PARAM) {
            PyErr_Format(PyExc_SyntaxError,
                         "name '%U' is parameter and nonlocal",
                         name);
            return 0;
        }
        if (!bound) {
            PyErr_Format(PyExc_SyntaxError,
                         "nonlocal declaration not allowed at module level");
            return 0;
        }
        if (!PySet_Contains(bound, name)) {
            PyErr_Format(PyExc_SyntaxError,
                         "no binding for nonlocal '%U' found",
                         name);

            return 0;
        }
        SET_SCOPE(scopes, name, FREE);
        ste->ste_free = 1;
        return PySet_Add(free, name) >= 0;
    }
    if (flags & DEF_BOUND) {
        SET_SCOPE(scopes, name, LOCAL);
        if (PySet_Add(local, name) < 0)
            return 0;
        if (PySet_Discard(global, name) < 0)
            return 0;
        return 1;
    }
    /* If an enclosing block has a binding for this name, it
       is a free variable rather than a global variable.
       Note that having a non-NULL bound implies that the block
       is nested.
    */
    if (bound && PySet_Contains(bound, name)) {
        SET_SCOPE(scopes, name, FREE);
        ste->ste_free = 1;
        return PySet_Add(free, name) >= 0;
    }
    /* If a parent has a global statement, then call it global
       explicit?  It could also be global implicit.
     */
    if (global && PySet_Contains(global, name)) {
        SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
        return 1;
    }
    if (ste->ste_nested)
        ste->ste_free = 1;
    SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_unoptimized ( const PySTEntryObject ste) [static]

Definition at line 520 of file symtable.c.

                                              {
    const char* trailer;

    if (ste->ste_type != FunctionBlock || !ste->ste_unoptimized
        || !(ste->ste_free || ste->ste_child_free))
        return 1;

    trailer = (ste->ste_child_free ?
                   "contains a nested function with free variables" :
                   "is a nested function");

    switch (ste->ste_unoptimized) {
    case OPT_TOPLEVEL: /* import * at top-level is fine */
        return 1;
    case OPT_IMPORT_STAR:
        PyErr_Format(PyExc_SyntaxError,
                     "import * is not allowed in function '%U' because it %s",
                     ste->ste_name, trailer);
        break;
    }

    PyErr_SyntaxLocationEx(ste->ste_table->st_filename, ste->ste_opt_lineno,
                           ste->ste_opt_col_offset);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PyST_GetScope ( PySTEntryObject ste,
PyObject name 
)

Definition at line 314 of file symtable.c.

{
    PyObject *v = PyDict_GetItem(ste->ste_symbols, name);
    if (!v)
        return 0;
    assert(PyLong_Check(v));
    return (PyLong_AS_LONG(v) >> SCOPE_OFFSET) & SCOPE_MASK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct symtable* PySymtable_Build ( mod_ty  mod,
const char *  filename,
PyFutureFeatures future 
) [read]

Definition at line 225 of file symtable.c.

{
    struct symtable *st = symtable_new();
    asdl_seq *seq;
    int i;

    if (st == NULL)
        return st;
    st->st_filename = filename;
    st->st_future = future;
    /* Make the initial symbol information gathering pass */
    if (!GET_IDENTIFIER(top) ||
        !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0)) {
        PySymtable_Free(st);
        return NULL;
    }

    st->st_top = st->st_cur;
    st->st_cur->ste_unoptimized = OPT_TOPLEVEL;
    switch (mod->kind) {
    case Module_kind:
        seq = mod->v.Module.body;
        for (i = 0; i < asdl_seq_LEN(seq); i++)
            if (!symtable_visit_stmt(st,
                        (stmt_ty)asdl_seq_GET(seq, i)))
                goto error;
        break;
    case Expression_kind:
        if (!symtable_visit_expr(st, mod->v.Expression.body))
            goto error;
        break;
    case Interactive_kind:
        seq = mod->v.Interactive.body;
        for (i = 0; i < asdl_seq_LEN(seq); i++)
            if (!symtable_visit_stmt(st,
                        (stmt_ty)asdl_seq_GET(seq, i)))
                goto error;
        break;
    case Suite_kind:
        PyErr_SetString(PyExc_RuntimeError,
                        "this compiler does not handle Suites");
        goto error;
    }
    if (!symtable_exit_block(st, (void *)mod)) {
        PySymtable_Free(st);
        return NULL;
    }
    /* Make the second symbol analysis pass */
    if (symtable_analyze(st))
        return st;
    PySymtable_Free(st);
    return NULL;
 error:
    (void) symtable_exit_block(st, (void *)mod);
    PySymtable_Free(st);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PySymtable_Free ( struct symtable st)

Definition at line 284 of file symtable.c.

{
    Py_XDECREF(st->st_blocks);
    Py_XDECREF(st->st_stack);
    PyMem_Free((void *)st);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PySTEntryObject* PySymtable_Lookup ( struct symtable st,
void key 
)

Definition at line 292 of file symtable.c.

{
    PyObject *k, *v;

    k = PyLong_FromVoidPtr(key);
    if (k == NULL)
        return NULL;
    v = PyDict_GetItem(st->st_blocks, k);
    if (v) {
        assert(PySTEntry_Check(v));
        Py_INCREF(v);
    }
    else {
        PyErr_SetString(PyExc_KeyError,
                        "unknown symbol table entry");
    }

    Py_DECREF(k);
    return (PySTEntryObject *)v;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ste_dealloc ( PySTEntryObject ste) [static]

Definition at line 99 of file symtable.c.

static PySTEntryObject* ste_new ( struct symtable st,
identifier  name,
_Py_block_ty  block,
void key,
int  lineno,
int  col_offset 
) [static]

Definition at line 27 of file symtable.c.

{
    PySTEntryObject *ste = NULL;
    PyObject *k;

    k = PyLong_FromVoidPtr(key);
    if (k == NULL)
        goto fail;
    ste = PyObject_New(PySTEntryObject, &PySTEntry_Type);
    if (ste == NULL)
        goto fail;
    ste->ste_table = st;
    ste->ste_id = k;

    ste->ste_name = name;
    Py_INCREF(name);

    ste->ste_symbols = NULL;
    ste->ste_varnames = NULL;
    ste->ste_children = NULL;

    ste->ste_symbols = PyDict_New();
    if (ste->ste_symbols == NULL)
        goto fail;

    ste->ste_varnames = PyList_New(0);
    if (ste->ste_varnames == NULL)
        goto fail;

    ste->ste_children = PyList_New(0);
    if (ste->ste_children == NULL)
        goto fail;

    ste->ste_type = block;
    ste->ste_unoptimized = 0;
    ste->ste_nested = 0;
    ste->ste_free = 0;
    ste->ste_varargs = 0;
    ste->ste_varkeywords = 0;
    ste->ste_opt_lineno = 0;
    ste->ste_opt_col_offset = 0;
    ste->ste_tmpname = 0;
    ste->ste_lineno = lineno;
    ste->ste_col_offset = col_offset;

    if (st->st_cur != NULL &&
        (st->st_cur->ste_nested ||
         st->st_cur->ste_type == FunctionBlock))
        ste->ste_nested = 1;
    ste->ste_child_free = 0;
    ste->ste_generator = 0;
    ste->ste_returns_value = 0;

    if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0)
        goto fail;

    return ste;
 fail:
    Py_XDECREF(ste);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* ste_repr ( PySTEntryObject ste) [static]

Definition at line 91 of file symtable.c.

{
    return PyUnicode_FromFormat("<symtable entry %U(%ld), line %d>",
                                ste->ste_name,
                                PyLong_AS_LONG(ste->ste_id), ste->ste_lineno);
}
static int symtable_add_def ( struct symtable st,
PyObject name,
int  flag 
) [static]

Definition at line 954 of file symtable.c.

{
    PyObject *o;
    PyObject *dict;
    long val;
    PyObject *mangled = _Py_Mangle(st->st_private, name);


    if (!mangled)
        return 0;
    dict = st->st_cur->ste_symbols;
    if ((o = PyDict_GetItem(dict, mangled))) {
        val = PyLong_AS_LONG(o);
        if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
            /* Is it better to use 'mangled' or 'name' here? */
            PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
            PyErr_SyntaxLocationEx(st->st_filename,
                                   st->st_cur->ste_lineno,
                                   st->st_cur->ste_col_offset);
            goto error;
        }
        val |= flag;
    } else
        val = flag;
    o = PyLong_FromLong(val);
    if (o == NULL)
        goto error;
    if (PyDict_SetItem(dict, mangled, o) < 0) {
        Py_DECREF(o);
        goto error;
    }
    Py_DECREF(o);

    if (flag & DEF_PARAM) {
        if (PyList_Append(st->st_cur->ste_varnames, mangled) < 0)
            goto error;
    } else      if (flag & DEF_GLOBAL) {
        /* XXX need to update DEF_GLOBAL for other flags too;
           perhaps only DEF_FREE_GLOBAL */
        val = flag;
        if ((o = PyDict_GetItem(st->st_global, mangled))) {
            val |= PyLong_AS_LONG(o);
        }
        o = PyLong_FromLong(val);
        if (o == NULL)
            goto error;
        if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
            Py_DECREF(o);
            goto error;
        }
        Py_DECREF(o);
    }
    Py_DECREF(mangled);
    return 1;

error:
    Py_DECREF(mangled);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_analyze ( struct symtable st) [static]

Definition at line 853 of file symtable.c.

{
    PyObject *free, *global;
    int r;

    free = PySet_New(NULL);
    if (!free)
        return 0;
    global = PySet_New(NULL);
    if (!global) {
        Py_DECREF(free);
        return 0;
    }
    r = analyze_block(st->st_top, NULL, free, global);
    Py_DECREF(free);
    Py_DECREF(global);
    return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_enter_block ( struct symtable st,
identifier  name,
_Py_block_ty  block,
void ast,
int  lineno,
int  col_offset 
) [static]

Definition at line 913 of file symtable.c.

{
    PySTEntryObject *prev = NULL;

    if (st->st_cur) {
        prev = st->st_cur;
        if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) {
            return 0;
        }
        Py_DECREF(st->st_cur);
    }
    st->st_cur = ste_new(st, name, block, ast, lineno, col_offset);
    if (st->st_cur == NULL)
        return 0;
    if (block == ModuleBlock)
        st->st_global = st->st_cur->ste_symbols;
    if (prev) {
        if (PyList_Append(prev->ste_children,
                          (PyObject *)st->st_cur) < 0) {
            return 0;
        }
    }
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_exit_block ( struct symtable st,
void ast 
) [static]

Definition at line 894 of file symtable.c.

{
    Py_ssize_t end;

    Py_CLEAR(st->st_cur);
    end = PyList_GET_SIZE(st->st_stack) - 1;
    if (end >= 0) {
        st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack,
                                                        end);
        if (st->st_cur == NULL)
            return 0;
        Py_INCREF(st->st_cur);
        if (PySequence_DelItem(st->st_stack, end) < 0)
            return 0;
    }
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_handle_comprehension ( struct symtable st,
expr_ty  e,
identifier  scope_name,
asdl_seq generators,
expr_ty  elt,
expr_ty  value 
) [static]

Definition at line 1626 of file symtable.c.

{
    int is_generator = (e->kind == GeneratorExp_kind);
    int needs_tmp = !is_generator;
    comprehension_ty outermost = ((comprehension_ty)
                                    asdl_seq_GET(generators, 0));
    /* Outermost iterator is evaluated in current scope */
    VISIT(st, expr, outermost->iter);
    /* Create comprehension scope for the rest */
    if (!scope_name ||
        !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e,
                              e->lineno, e->col_offset)) {
        return 0;
    }
    st->st_cur->ste_generator = is_generator;
    /* Outermost iter is received as an argument */
    if (!symtable_implicit_arg(st, 0)) {
        symtable_exit_block(st, (void *)e);
        return 0;
    }
    /* Allocate temporary name if needed */
    if (needs_tmp && !symtable_new_tmpname(st)) {
        symtable_exit_block(st, (void *)e);
        return 0;
    }
    VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
    VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
    VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
                            generators, 1, (void*)e);
    if (value)
        VISIT_IN_BLOCK(st, expr, value, (void*)e);
    VISIT_IN_BLOCK(st, expr, elt, (void*)e);
    return symtable_exit_block(st, (void *)e);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_implicit_arg ( struct symtable st,
int  pos 
) [static]

Definition at line 1442 of file symtable.c.

{
    PyObject *id = PyUnicode_FromFormat(".%d", pos);
    if (id == NULL)
        return 0;
    if (!symtable_add_def(st, id, DEF_PARAM)) {
        Py_DECREF(id);
        return 0;
    }
    Py_DECREF(id);
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long symtable_lookup ( struct symtable st,
PyObject name 
) [static]

Definition at line 940 of file symtable.c.

{
    PyObject *o;
    PyObject *mangled = _Py_Mangle(st->st_private, name);
    if (!mangled)
        return 0;
    o = PyDict_GetItem(st->st_cur->ste_symbols, mangled);
    Py_DECREF(mangled);
    if (!o)
        return 0;
    return PyLong_AsLong(o);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct symtable* symtable_new ( void  ) [static, read]

Definition at line 201 of file symtable.c.

{
    struct symtable *st;

    st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable));
    if (st == NULL)
        return NULL;

    st->st_filename = NULL;
    st->st_blocks = NULL;

    if ((st->st_stack = PyList_New(0)) == NULL)
        goto fail;
    if ((st->st_blocks = PyDict_New()) == NULL)
        goto fail;
    st->st_cur = NULL;
    st->st_private = NULL;
    return st;
 fail:
    PySymtable_Free(st);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_new_tmpname ( struct symtable st) [static]

Definition at line 1088 of file symtable.c.

{
    char tmpname[256];
    identifier tmp;

    PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
                  ++st->st_cur->ste_tmpname);
    tmp = PyUnicode_InternFromString(tmpname);
    if (!tmp)
        return 0;
    if (!symtable_add_def(st, tmp, DEF_LOCAL))
        return 0;
    Py_DECREF(tmp);
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_alias ( struct symtable st,
alias_ty  a 
) [static]

Definition at line 1545 of file symtable.c.

{
    /* Compute store_name, the name actually bound by the import
       operation.  It is different than a->name when a->name is a
       dotted package name (e.g. spam.eggs)
    */
    PyObject *store_name;
    PyObject *name = (a->asname == NULL) ? a->name : a->asname;
    const Py_UNICODE *base = PyUnicode_AS_UNICODE(name);
    Py_UNICODE *dot = Py_UNICODE_strchr(base, '.');
    if (dot) {
        store_name = PyUnicode_FromUnicode(base, dot - base);
        if (!store_name)
            return 0;
    }
    else {
        store_name = name;
        Py_INCREF(store_name);
    }
    if (PyUnicode_CompareWithASCIIString(name, "*")) {
        int r = symtable_add_def(st, store_name, DEF_IMPORT);
        Py_DECREF(store_name);
        return r;
    }
    else {
        if (st->st_cur->ste_type != ModuleBlock) {
            int lineno = st->st_cur->ste_lineno;
            int col_offset = st->st_cur->ste_col_offset;
            PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
            PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset);
            Py_DECREF(store_name);
            return 0;
        }
        st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
        Py_DECREF(store_name);
        return 1;
    }
}

Here is the call graph for this function:

static int symtable_visit_annotations ( struct symtable st,
stmt_ty  s 
) [static]

Definition at line 1490 of file symtable.c.

{
    arguments_ty a = s->v.FunctionDef.args;

    if (a->args && !symtable_visit_argannotations(st, a->args))
        return 0;
    if (a->varargannotation)
        VISIT(st, expr, a->varargannotation);
    if (a->kwargannotation)
        VISIT(st, expr, a->kwargannotation);
    if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs))
        return 0;
    if (s->v.FunctionDef.returns)
        VISIT(st, expr, s->v.FunctionDef.returns);
    return 1;
}

Here is the caller graph for this function:

static int symtable_visit_argannotations ( struct symtable st,
asdl_seq args 
) [static]

Definition at line 1473 of file symtable.c.

{
    int i;

    if (!args)
        return -1;

    for (i = 0; i < asdl_seq_LEN(args); i++) {
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
        if (arg->annotation)
            VISIT(st, expr, arg->annotation);
    }

    return 1;
}
static int symtable_visit_arguments ( struct symtable st,
arguments_ty  a 
) [static]

Definition at line 1508 of file symtable.c.

{
    /* skip default arguments inside function block
       XXX should ast be different?
    */
    if (a->args && !symtable_visit_params(st, a->args))
        return 0;
    if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))
        return 0;
    if (a->vararg) {
        if (!symtable_add_def(st, a->vararg, DEF_PARAM))
            return 0;
        st->st_cur->ste_varargs = 1;
    }
    if (a->kwarg) {
        if (!symtable_add_def(st, a->kwarg, DEF_PARAM))
            return 0;
        st->st_cur->ste_varkeywords = 1;
    }
    return 1;
}

Here is the call graph for this function:

static int symtable_visit_comprehension ( struct symtable st,
comprehension_ty  lc 
) [static]

Definition at line 1586 of file symtable.c.

{
    VISIT(st, expr, lc->target);
    VISIT(st, expr, lc->iter);
    VISIT_SEQ(st, expr, lc->ifs);
    return 1;
}
static int symtable_visit_dictcomp ( struct symtable st,
expr_ty  s 
) [static]

Definition at line 1688 of file symtable.c.

{
    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp),
                                         e->v.DictComp.generators,
                                         e->v.DictComp.key,
                                         e->v.DictComp.value);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_excepthandler ( struct symtable st,
excepthandler_ty  eh 
) [static]

Definition at line 1532 of file symtable.c.

{
    if (eh->v.ExceptHandler.type)
        VISIT(st, expr, eh->v.ExceptHandler.type);
    if (eh->v.ExceptHandler.name)
        if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL))
            return 0;
    VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body);
    return 1;
}

Here is the call graph for this function:

static int symtable_visit_expr ( struct symtable st,
expr_ty  s 
) [static]

Definition at line 1319 of file symtable.c.

{
    switch (e->kind) {
    case BoolOp_kind:
        VISIT_SEQ(st, expr, e->v.BoolOp.values);
        break;
    case BinOp_kind:
        VISIT(st, expr, e->v.BinOp.left);
        VISIT(st, expr, e->v.BinOp.right);
        break;
    case UnaryOp_kind:
        VISIT(st, expr, e->v.UnaryOp.operand);
        break;
    case Lambda_kind: {
        if (!GET_IDENTIFIER(lambda))
            return 0;
        if (e->v.Lambda.args->defaults)
            VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
        if (!symtable_enter_block(st, lambda,
                                  FunctionBlock, (void *)e, e->lineno,
                                  e->col_offset))
            return 0;
        VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
        VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
        if (!symtable_exit_block(st, (void *)e))
            return 0;
        break;
    }
    case IfExp_kind:
        VISIT(st, expr, e->v.IfExp.test);
        VISIT(st, expr, e->v.IfExp.body);
        VISIT(st, expr, e->v.IfExp.orelse);
        break;
    case Dict_kind:
        VISIT_SEQ(st, expr, e->v.Dict.keys);
        VISIT_SEQ(st, expr, e->v.Dict.values);
        break;
    case Set_kind:
        VISIT_SEQ(st, expr, e->v.Set.elts);
        break;
    case GeneratorExp_kind:
        if (!symtable_visit_genexp(st, e))
            return 0;
        break;
    case ListComp_kind:
        if (!symtable_visit_listcomp(st, e))
            return 0;
        break;
    case SetComp_kind:
        if (!symtable_visit_setcomp(st, e))
            return 0;
        break;
    case DictComp_kind:
        if (!symtable_visit_dictcomp(st, e))
            return 0;
        break;
    case Yield_kind:
        if (e->v.Yield.value)
            VISIT(st, expr, e->v.Yield.value);
        st->st_cur->ste_generator = 1;
        if (st->st_cur->ste_returns_value) {
            PyErr_SetString(PyExc_SyntaxError,
                RETURN_VAL_IN_GENERATOR);
            PyErr_SyntaxLocationEx(st->st_filename,
                                   e->lineno, e->col_offset);
            return 0;
        }
        break;
    case Compare_kind:
        VISIT(st, expr, e->v.Compare.left);
        VISIT_SEQ(st, expr, e->v.Compare.comparators);
        break;
    case Call_kind:
        VISIT(st, expr, e->v.Call.func);
        VISIT_SEQ(st, expr, e->v.Call.args);
        VISIT_SEQ(st, keyword, e->v.Call.keywords);
        if (e->v.Call.starargs)
            VISIT(st, expr, e->v.Call.starargs);
        if (e->v.Call.kwargs)
            VISIT(st, expr, e->v.Call.kwargs);
        break;
    case Num_kind:
    case Str_kind:
    case Bytes_kind:
    case Ellipsis_kind:
        /* Nothing to do here. */
        break;
    /* The following exprs can be assignment targets. */
    case Attribute_kind:
        VISIT(st, expr, e->v.Attribute.value);
        break;
    case Subscript_kind:
        VISIT(st, expr, e->v.Subscript.value);
        VISIT(st, slice, e->v.Subscript.slice);
        break;
    case Starred_kind:
        VISIT(st, expr, e->v.Starred.value);
        break;
    case Name_kind:
        if (!symtable_add_def(st, e->v.Name.id,
                              e->v.Name.ctx == Load ? USE : DEF_LOCAL))
            return 0;
        /* Special-case super: it counts as a use of __class__ */
        if (e->v.Name.ctx == Load &&
            st->st_cur->ste_type == FunctionBlock &&
            !PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) {
            if (!GET_IDENTIFIER(__class__) ||
                !symtable_add_def(st, __class__, USE))
                return 0;
        }
        break;
    /* child nodes of List and Tuple will have expr_context set */
    case List_kind:
        VISIT_SEQ(st, expr, e->v.List.elts);
        break;
    case Tuple_kind:
        VISIT_SEQ(st, expr, e->v.Tuple.elts);
        break;
    }
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_genexp ( struct symtable st,
expr_ty  s 
) [static]

Definition at line 1664 of file symtable.c.

{
    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
                                         e->v.GeneratorExp.generators,
                                         e->v.GeneratorExp.elt, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_keyword ( struct symtable st,
keyword_ty  k 
) [static]

Definition at line 1596 of file symtable.c.

{
    VISIT(st, expr, k->value);
    return 1;
}
static int symtable_visit_listcomp ( struct symtable st,
expr_ty  s 
) [static]

Definition at line 1672 of file symtable.c.

{
    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp),
                                         e->v.ListComp.generators,
                                         e->v.ListComp.elt, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_params ( struct symtable st,
asdl_seq args 
) [static]

Definition at line 1456 of file symtable.c.

{
    int i;

    if (!args)
        return -1;

    for (i = 0; i < asdl_seq_LEN(args); i++) {
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
        if (!symtable_add_def(st, arg->arg, DEF_PARAM))
            return 0;
    }

    return 1;
}

Here is the call graph for this function:

static int symtable_visit_setcomp ( struct symtable st,
expr_ty  s 
) [static]

Definition at line 1680 of file symtable.c.

{
    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp),
                                         e->v.SetComp.generators,
                                         e->v.SetComp.elt, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_visit_slice ( struct symtable st,
slice_ty  s 
) [static]

Definition at line 1604 of file symtable.c.

{
    switch (s->kind) {
    case Slice_kind:
        if (s->v.Slice.lower)
            VISIT(st, expr, s->v.Slice.lower)
        if (s->v.Slice.upper)
            VISIT(st, expr, s->v.Slice.upper)
        if (s->v.Slice.step)
            VISIT(st, expr, s->v.Slice.step)
        break;
    case ExtSlice_kind:
        VISIT_SEQ(st, slice, s->v.ExtSlice.dims)
        break;
    case Index_kind:
        VISIT(st, expr, s->v.Index.value)
        break;
    }
    return 1;
}
static int symtable_visit_stmt ( struct symtable st,
stmt_ty  s 
) [static]

Definition at line 1106 of file symtable.c.

{
    switch (s->kind) {
    case FunctionDef_kind:
        if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
            return 0;
        if (s->v.FunctionDef.args->defaults)
            VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
        if (s->v.FunctionDef.args->kw_defaults)
            VISIT_KWONLYDEFAULTS(st,
                               s->v.FunctionDef.args->kw_defaults);
        if (!symtable_visit_annotations(st, s))
            return 0;
        if (s->v.FunctionDef.decorator_list)
            VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
        if (!symtable_enter_block(st, s->v.FunctionDef.name,
                                  FunctionBlock, (void *)s, s->lineno,
                                  s->col_offset))
            return 0;
        VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
        if (!symtable_exit_block(st, s))
            return 0;
        break;
    case ClassDef_kind: {
        PyObject *tmp;
        if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
            return 0;
        VISIT_SEQ(st, expr, s->v.ClassDef.bases);
        VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
        if (s->v.ClassDef.starargs)
            VISIT(st, expr, s->v.ClassDef.starargs);
        if (s->v.ClassDef.kwargs)
            VISIT(st, expr, s->v.ClassDef.kwargs);
        if (s->v.ClassDef.decorator_list)
            VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
        if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
                                  (void *)s, s->lineno, s->col_offset))
            return 0;
        if (!GET_IDENTIFIER(__class__) ||
            !symtable_add_def(st, __class__, DEF_LOCAL) ||
            !GET_IDENTIFIER(__locals__) ||
            !symtable_add_def(st, __locals__, DEF_PARAM)) {
            symtable_exit_block(st, s);
            return 0;
        }
        tmp = st->st_private;
        st->st_private = s->v.ClassDef.name;
        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
        st->st_private = tmp;
        if (!symtable_exit_block(st, s))
            return 0;
        break;
    }
    case Return_kind:
        if (s->v.Return.value) {
            VISIT(st, expr, s->v.Return.value);
            st->st_cur->ste_returns_value = 1;
            if (st->st_cur->ste_generator) {
                PyErr_SetString(PyExc_SyntaxError,
                    RETURN_VAL_IN_GENERATOR);
                PyErr_SyntaxLocationEx(st->st_filename,
                                       s->lineno,
                                       s->col_offset);
                return 0;
            }
        }
        break;
    case Delete_kind:
        VISIT_SEQ(st, expr, s->v.Delete.targets);
        break;
    case Assign_kind:
        VISIT_SEQ(st, expr, s->v.Assign.targets);
        VISIT(st, expr, s->v.Assign.value);
        break;
    case AugAssign_kind:
        VISIT(st, expr, s->v.AugAssign.target);
        VISIT(st, expr, s->v.AugAssign.value);
        break;
    case For_kind:
        VISIT(st, expr, s->v.For.target);
        VISIT(st, expr, s->v.For.iter);
        VISIT_SEQ(st, stmt, s->v.For.body);
        if (s->v.For.orelse)
            VISIT_SEQ(st, stmt, s->v.For.orelse);
        break;
    case While_kind:
        VISIT(st, expr, s->v.While.test);
        VISIT_SEQ(st, stmt, s->v.While.body);
        if (s->v.While.orelse)
            VISIT_SEQ(st, stmt, s->v.While.orelse);
        break;
    case If_kind:
        /* XXX if 0: and lookup_yield() hacks */
        VISIT(st, expr, s->v.If.test);
        VISIT_SEQ(st, stmt, s->v.If.body);
        if (s->v.If.orelse)
            VISIT_SEQ(st, stmt, s->v.If.orelse);
        break;
    case Raise_kind:
        if (s->v.Raise.exc) {
            VISIT(st, expr, s->v.Raise.exc);
        if (s->v.Raise.cause) {
        VISIT(st, expr, s->v.Raise.cause);
        }
        }
        break;
    case TryExcept_kind:
        VISIT_SEQ(st, stmt, s->v.TryExcept.body);
        VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
        VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
        break;
    case TryFinally_kind:
        VISIT_SEQ(st, stmt, s->v.TryFinally.body);
        VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
        break;
    case Assert_kind:
        VISIT(st, expr, s->v.Assert.test);
        if (s->v.Assert.msg)
            VISIT(st, expr, s->v.Assert.msg);
        break;
    case Import_kind:
        VISIT_SEQ(st, alias, s->v.Import.names);
        /* XXX Don't have the lineno available inside
           visit_alias */
        if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) {
            st->st_cur->ste_opt_lineno = s->lineno;
            st->st_cur->ste_opt_col_offset = s->col_offset;
        }
        break;
    case ImportFrom_kind:
        VISIT_SEQ(st, alias, s->v.ImportFrom.names);
        /* XXX Don't have the lineno available inside
           visit_alias */
        if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) {
            st->st_cur->ste_opt_lineno = s->lineno;
            st->st_cur->ste_opt_col_offset = s->col_offset;
        }
        break;
    case Global_kind: {
        int i;
        asdl_seq *seq = s->v.Global.names;
        for (i = 0; i < asdl_seq_LEN(seq); i++) {
            identifier name = (identifier)asdl_seq_GET(seq, i);
            char *c_name = _PyUnicode_AsString(name);
            long cur = symtable_lookup(st, name);
            if (cur < 0)
                return 0;
            if (cur & (DEF_LOCAL | USE)) {
                char buf[256];
                if (cur & DEF_LOCAL)
                    PyOS_snprintf(buf, sizeof(buf),
                                  GLOBAL_AFTER_ASSIGN,
                                  c_name);
                else
                    PyOS_snprintf(buf, sizeof(buf),
                                  GLOBAL_AFTER_USE,
                                  c_name);
                if (!symtable_warn(st, buf, s->lineno))
                    return 0;
            }
            if (!symtable_add_def(st, name, DEF_GLOBAL))
                return 0;
        }
        break;
    }
    case Nonlocal_kind: {
        int i;
        asdl_seq *seq = s->v.Nonlocal.names;
        for (i = 0; i < asdl_seq_LEN(seq); i++) {
            identifier name = (identifier)asdl_seq_GET(seq, i);
            char *c_name = _PyUnicode_AsString(name);
            long cur = symtable_lookup(st, name);
            if (cur < 0)
                return 0;
            if (cur & (DEF_LOCAL | USE)) {
                char buf[256];
                if (cur & DEF_LOCAL)
                    PyOS_snprintf(buf, sizeof(buf),
                                  NONLOCAL_AFTER_ASSIGN,
                                  c_name);
                else
                    PyOS_snprintf(buf, sizeof(buf),
                                  NONLOCAL_AFTER_USE,
                                  c_name);
                if (!symtable_warn(st, buf, s->lineno))
                    return 0;
            }
            if (!symtable_add_def(st, name, DEF_NONLOCAL))
                return 0;
        }
        break;
    }
    case Expr_kind:
        VISIT(st, expr, s->v.Expr.value);
        break;
    case Pass_kind:
    case Break_kind:
    case Continue_kind:
        /* nothing to do here */
        break;
    case With_kind:
        VISIT(st, expr, s->v.With.context_expr);
        if (s->v.With.optional_vars) {
            VISIT(st, expr, s->v.With.optional_vars);
        }
        VISIT_SEQ(st, stmt, s->v.With.body);
        break;
    }
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symtable_warn ( struct symtable st,
char *  msg,
int  lineno 
) [static]

Definition at line 874 of file symtable.c.

{
    if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, st->st_filename,
                           lineno, NULL, NULL) < 0)     {
        if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
            PyErr_SetString(PyExc_SyntaxError, msg);
            PyErr_SyntaxLocationEx(st->st_filename, st->st_cur->ste_lineno,
                                   st->st_cur->ste_col_offset);
        }
        return 0;
    }
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int update_symbols ( PyObject symbols,
PyObject scopes,
PyObject bound,
PyObject free,
int  classflag 
) [static]

Definition at line 551 of file symtable.c.

{
    PyObject *name = NULL, *itr = NULL;
    PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL;
    Py_ssize_t pos = 0;

    /* Update scope information for all symbols in this scope */
    while (PyDict_Next(symbols, &pos, &name, &v)) {
        long scope, flags;
        assert(PyLong_Check(v));
        flags = PyLong_AS_LONG(v);
        v_scope = PyDict_GetItem(scopes, name);
        assert(v_scope && PyLong_Check(v_scope));
        scope = PyLong_AS_LONG(v_scope);
        flags |= (scope << SCOPE_OFFSET);
        v_new = PyLong_FromLong(flags);
        if (!v_new)
            return 0;
        if (PyDict_SetItem(symbols, name, v_new) < 0) {
            Py_DECREF(v_new);
            return 0;
        }
        Py_DECREF(v_new);
    }

    /* Record not yet resolved free variables from children (if any) */
    v_free = PyLong_FromLong(FREE << SCOPE_OFFSET);
    if (!v_free)
        return 0;

    itr = PyObject_GetIter(free);
    if (!itr)
        goto error;

    while ((name = PyIter_Next(itr))) {
        v = PyDict_GetItem(symbols, name);

        /* Handle symbol that already exists in this scope */
        if (v) {
            /* Handle a free variable in a method of
               the class that has the same name as a local
               or global in the class scope.
            */
            if  (classflag &&
                 PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) {
                long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS;
                v_new = PyLong_FromLong(flags);
                if (!v_new) {
                    goto error;
                }
                if (PyDict_SetItem(symbols, name, v_new) < 0) {
                    Py_DECREF(v_new);
                    goto error;
                }
                Py_DECREF(v_new);
            }
            /* It's a cell, or already free in this scope */
            Py_DECREF(name);
            continue;
        }
        /* Handle global symbol */
        if (!PySet_Contains(bound, name)) {
            Py_DECREF(name);
            continue;       /* it's a global */
        }
        /* Propagate new free symbol up the lexical stack */
        if (PyDict_SetItem(symbols, name, v_free) < 0) {
            goto error;
        }
        Py_DECREF(name);
    }
    Py_DECREF(itr);
    Py_DECREF(v_free);
    return 1;
error:
    Py_XDECREF(v_free);
    Py_XDECREF(itr);
    Py_XDECREF(name);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 192 of file symtable.c.

Definition at line 192 of file symtable.c.

identifier dictcomp = NULL [static]

Definition at line 191 of file symtable.c.

identifier genexpr = NULL [static]

Definition at line 190 of file symtable.c.

identifier lambda = NULL [static]

Definition at line 190 of file symtable.c.

identifier listcomp = NULL [static]

Definition at line 191 of file symtable.c.

Definition at line 125 of file symtable.c.

identifier setcomp = NULL [static]

Definition at line 191 of file symtable.c.

Initial value:
 {
    {"id",       T_OBJECT, OFF(ste_id), READONLY},
    {"name",     T_OBJECT, OFF(ste_name), READONLY},
    {"symbols",  T_OBJECT, OFF(ste_symbols), READONLY},
    {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
    {"children", T_OBJECT, OFF(ste_children), READONLY},
    {"optimized",T_INT,    OFF(ste_unoptimized), READONLY},
    {"nested",   T_INT,    OFF(ste_nested), READONLY},
    {"type",     T_INT,    OFF(ste_type), READONLY},
    {"lineno",   T_INT,    OFF(ste_lineno), READONLY},
    {NULL}
}

Definition at line 112 of file symtable.c.

identifier top = NULL [static]

Definition at line 190 of file symtable.c.