1#
2#   Symbol Table
3#
4
5from __future__ import absolute_import
6
7import re
8import copy
9import operator
10
11try:
12    import __builtin__ as builtins
13except ImportError:  # Py3
14    import builtins
15
16from .Errors import warning, error, InternalError
17from .StringEncoding import EncodedString
18from . import Options, Naming
19from . import PyrexTypes
20from .PyrexTypes import py_object_type, unspecified_type
21from .TypeSlots import (
22    pyfunction_signature, pymethod_signature, richcmp_special_methods,
23    get_special_method_signature, get_property_accessor_signature)
24from . import Future
25
26from . import Code
27
28iso_c99_keywords = set(
29['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
30    'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
31    'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof',
32    'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
33    'volatile', 'while',
34    '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict'])
35
36
37def c_safe_identifier(cname):
38    # There are some C limitations on struct entry names.
39    if ((cname[:2] == '__' and not (cname.startswith(Naming.pyrex_prefix)
40                                    or cname in ('__weakref__', '__dict__')))
41            or cname in iso_c99_keywords):
42        cname = Naming.pyrex_prefix + cname
43    return cname
44
45
46class BufferAux(object):
47    writable_needed = False
48
49    def __init__(self, buflocal_nd_var, rcbuf_var):
50        self.buflocal_nd_var = buflocal_nd_var
51        self.rcbuf_var = rcbuf_var
52
53    def __repr__(self):
54        return "<BufferAux %r>" % self.__dict__
55
56
57class Entry(object):
58    # A symbol table entry in a Scope or ModuleNamespace.
59    #
60    # name             string     Python name of entity
61    # cname            string     C name of entity
62    # type             PyrexType  Type of entity
63    # doc              string     Doc string
64    # annotation       ExprNode   PEP 484/526 annotation
65    # init             string     Initial value
66    # visibility       'private' or 'public' or 'extern'
67    # is_builtin       boolean    Is an entry in the Python builtins dict
68    # is_cglobal       boolean    Is a C global variable
69    # is_pyglobal      boolean    Is a Python module-level variable
70    #                               or class attribute during
71    #                               class construction
72    # is_member        boolean    Is an assigned class member
73    # is_pyclass_attr  boolean    Is a name in a Python class namespace
74    # is_variable      boolean    Is a variable
75    # is_cfunction     boolean    Is a C function
76    # is_cmethod       boolean    Is a C method of an extension type
77    # is_builtin_cmethod boolean  Is a C method of a builtin type (implies is_cmethod)
78    # is_unbound_cmethod boolean  Is an unbound C method of an extension type
79    # is_final_cmethod   boolean  Is non-overridable C method
80    # is_inline_cmethod  boolean  Is inlined C method
81    # is_anonymous     boolean    Is a anonymous pyfunction entry
82    # is_type          boolean    Is a type definition
83    # is_cclass        boolean    Is an extension class
84    # is_cpp_class     boolean    Is a C++ class
85    # is_const         boolean    Is a constant
86    # is_property      boolean    Is a property of an extension type:
87    # doc_cname        string or None  C const holding the docstring
88    # getter_cname     string          C func for getting property
89    # setter_cname     string          C func for setting or deleting property
90    # is_self_arg      boolean    Is the "self" arg of an exttype method
91    # is_arg           boolean    Is the arg of a method
92    # is_local         boolean    Is a local variable
93    # in_closure       boolean    Is referenced in an inner scope
94    # in_subscope      boolean    Belongs to a generator expression scope
95    # is_readonly      boolean    Can't be assigned to
96    # func_cname       string     C func implementing Python func
97    # func_modifiers   [string]   C function modifiers ('inline')
98    # pos              position   Source position where declared
99    # namespace_cname  string     If is_pyglobal, the C variable
100    #                               holding its home namespace
101    # pymethdef_cname  string     PyMethodDef structure
102    # signature        Signature  Arg & return types for Python func
103    # as_variable      Entry      Alternative interpretation of extension
104    #                               type name or builtin C function as a variable
105    # xdecref_cleanup  boolean    Use Py_XDECREF for error cleanup
106    # in_cinclude      boolean    Suppress C declaration code
107    # enum_values      [Entry]    For enum types, list of values
108    # qualified_name   string     "modname.funcname" or "modname.classname"
109    #                               or "modname.classname.funcname"
110    # is_declared_generic  boolean  Is declared as PyObject * even though its
111    #                                 type is an extension type
112    # as_module        None       Module scope, if a cimported module
113    # is_inherited     boolean    Is an inherited attribute of an extension type
114    # pystring_cname   string     C name of Python version of string literal
115    # is_interned      boolean    For string const entries, value is interned
116    # is_identifier    boolean    For string const entries, value is an identifier
117    # used             boolean
118    # is_special       boolean    Is a special method or property accessor
119    #                               of an extension type
120    # defined_in_pxd   boolean    Is defined in a .pxd file (not just declared)
121    # api              boolean    Generate C API for C class or function
122    # utility_code     string     Utility code needed when this entry is used
123    #
124    # buffer_aux       BufferAux or None  Extra information needed for buffer variables
125    # inline_func_in_pxd boolean  Hacky special case for inline function in pxd file.
126    #                             Ideally this should not be necessary.
127    # might_overflow   boolean    In an arithmetic expression that could cause
128    #                             overflow (used for type inference).
129    # utility_code_definition     For some Cython builtins, the utility code
130    #                             which contains the definition of the entry.
131    #                             Currently only supported for CythonScope entries.
132    # error_on_uninitialized      Have Control Flow issue an error when this entry is
133    #                             used uninitialized
134    # cf_used          boolean    Entry is used
135    # is_fused_specialized boolean Whether this entry of a cdef or def function
136    #                              is a specialization
137
138    # TODO: utility_code and utility_code_definition serves the same purpose...
139
140    inline_func_in_pxd = False
141    borrowed = 0
142    init = ""
143    annotation = None
144    visibility = 'private'
145    is_builtin = 0
146    is_cglobal = 0
147    is_pyglobal = 0
148    is_member = 0
149    is_pyclass_attr = 0
150    is_variable = 0
151    is_cfunction = 0
152    is_cmethod = 0
153    is_builtin_cmethod = False
154    is_unbound_cmethod = 0
155    is_final_cmethod = 0
156    is_inline_cmethod = 0
157    is_anonymous = 0
158    is_type = 0
159    is_cclass = 0
160    is_cpp_class = 0
161    is_const = 0
162    is_property = 0
163    doc_cname = None
164    getter_cname = None
165    setter_cname = None
166    is_self_arg = 0
167    is_arg = 0
168    is_local = 0
169    in_closure = 0
170    from_closure = 0
171    in_subscope = 0
172    is_declared_generic = 0
173    is_readonly = 0
174    pyfunc_cname = None
175    func_cname = None
176    func_modifiers = []
177    final_func_cname = None
178    doc = None
179    as_variable = None
180    xdecref_cleanup = 0
181    in_cinclude = 0
182    as_module = None
183    is_inherited = 0
184    pystring_cname = None
185    is_identifier = 0
186    is_interned = 0
187    used = 0
188    is_special = 0
189    defined_in_pxd = 0
190    is_implemented = 0
191    api = 0
192    utility_code = None
193    is_overridable = 0
194    buffer_aux = None
195    prev_entry = None
196    might_overflow = 0
197    fused_cfunction = None
198    is_fused_specialized = False
199    utility_code_definition = None
200    needs_property = False
201    in_with_gil_block = 0
202    from_cython_utility_code = None
203    error_on_uninitialized = False
204    cf_used = True
205    outer_entry = None
206
207    def __init__(self, name, cname, type, pos = None, init = None):
208        self.name = name
209        self.cname = cname
210        self.type = type
211        self.pos = pos
212        self.init = init
213        self.overloaded_alternatives = []
214        self.cf_assignments = []
215        self.cf_references = []
216        self.inner_entries = []
217        self.defining_entry = self
218
219    def __repr__(self):
220        return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type)
221
222    def already_declared_here(self):
223        error(self.pos, "Previous declaration is here")
224
225    def redeclared(self, pos):
226        error(pos, "'%s' does not match previous declaration" % self.name)
227        self.already_declared_here()
228
229    def all_alternatives(self):
230        return [self] + self.overloaded_alternatives
231
232    def all_entries(self):
233        return [self] + self.inner_entries
234
235    def __lt__(left, right):
236        if isinstance(left, Entry) and isinstance(right, Entry):
237            return (left.name, left.cname) < (right.name, right.cname)
238        else:
239            return NotImplemented
240
241
242class InnerEntry(Entry):
243    """
244    An entry in a closure scope that represents the real outer Entry.
245    """
246    from_closure = True
247
248    def __init__(self, outer_entry, scope):
249        Entry.__init__(self, outer_entry.name,
250                       outer_entry.cname,
251                       outer_entry.type,
252                       outer_entry.pos)
253        self.outer_entry = outer_entry
254        self.scope = scope
255
256        # share state with (outermost) defining entry
257        outermost_entry = outer_entry
258        while outermost_entry.outer_entry:
259            outermost_entry = outermost_entry.outer_entry
260        self.defining_entry = outermost_entry
261        self.inner_entries = outermost_entry.inner_entries
262        self.cf_assignments = outermost_entry.cf_assignments
263        self.cf_references = outermost_entry.cf_references
264        self.overloaded_alternatives = outermost_entry.overloaded_alternatives
265        self.inner_entries.append(self)
266
267    def __getattr__(self, name):
268        if name.startswith('__'):
269            # we wouldn't have been called if it was there
270            raise AttributeError(name)
271        return getattr(self.defining_entry, name)
272
273    def all_entries(self):
274        return self.defining_entry.all_entries()
275
276
277class Scope(object):
278    # name              string             Unqualified name
279    # outer_scope       Scope or None      Enclosing scope
280    # entries           {string : Entry}   Python name to entry, non-types
281    # const_entries     [Entry]            Constant entries
282    # type_entries      [Entry]            Struct/union/enum/typedef/exttype entries
283    # sue_entries       [Entry]            Struct/union/enum entries
284    # arg_entries       [Entry]            Function argument entries
285    # var_entries       [Entry]            User-defined variable entries
286    # pyfunc_entries    [Entry]            Python function entries
287    # cfunc_entries     [Entry]            C function entries
288    # c_class_entries   [Entry]            All extension type entries
289    # cname_to_entry    {string : Entry}   Temp cname to entry mapping
290    # return_type       PyrexType or None  Return type of function owning scope
291    # is_builtin_scope  boolean            Is the builtin scope of Python/Cython
292    # is_py_class_scope boolean            Is a Python class scope
293    # is_c_class_scope  boolean            Is an extension type scope
294    # is_closure_scope  boolean            Is a closure scope
295    # is_passthrough    boolean            Outer scope is passed directly
296    # is_cpp_class_scope  boolean          Is a C++ class scope
297    # is_property_scope boolean            Is a extension type property scope
298    # scope_prefix      string             Disambiguator for C names
299    # in_cinclude       boolean            Suppress C declaration code
300    # qualified_name    string             "modname" or "modname.classname"
301    #                                        Python strings in this scope
302    # nogil             boolean            In a nogil section
303    # directives        dict               Helper variable for the recursive
304    #                                      analysis, contains directive values.
305    # is_internal       boolean            Is only used internally (simpler setup)
306
307    is_builtin_scope = 0
308    is_py_class_scope = 0
309    is_c_class_scope = 0
310    is_closure_scope = 0
311    is_genexpr_scope = 0
312    is_passthrough = 0
313    is_cpp_class_scope = 0
314    is_property_scope = 0
315    is_module_scope = 0
316    is_internal = 0
317    scope_prefix = ""
318    in_cinclude = 0
319    nogil = 0
320    fused_to_specific = None
321    return_type = None
322
323    def __init__(self, name, outer_scope, parent_scope):
324        # The outer_scope is the next scope in the lookup chain.
325        # The parent_scope is used to derive the qualified name of this scope.
326        self.name = name
327        self.outer_scope = outer_scope
328        self.parent_scope = parent_scope
329        mangled_name = "%d%s_" % (len(name), name.replace('.', '_dot_'))
330        qual_scope = self.qualifying_scope()
331        if qual_scope:
332            self.qualified_name = qual_scope.qualify_name(name)
333            self.scope_prefix = qual_scope.scope_prefix + mangled_name
334        else:
335            self.qualified_name = EncodedString(name)
336            self.scope_prefix = mangled_name
337        self.entries = {}
338        self.subscopes = set()
339        self.const_entries = []
340        self.type_entries = []
341        self.sue_entries = []
342        self.arg_entries = []
343        self.var_entries = []
344        self.pyfunc_entries = []
345        self.cfunc_entries = []
346        self.c_class_entries = []
347        self.defined_c_classes = []
348        self.imported_c_classes = {}
349        self.cname_to_entry = {}
350        self.string_to_entry = {}
351        self.identifier_to_entry = {}
352        self.num_to_entry = {}
353        self.obj_to_entry = {}
354        self.buffer_entries = []
355        self.lambda_defs = []
356        self.id_counters = {}
357
358    def __deepcopy__(self, memo):
359        return self
360
361    def merge_in(self, other, merge_unused=True, whitelist=None):
362        # Use with care...
363        entries = []
364        for name, entry in other.entries.items():
365            if not whitelist or name in whitelist:
366                if entry.used or merge_unused:
367                    entries.append((name, entry))
368
369        self.entries.update(entries)
370
371        for attr in ('const_entries',
372                     'type_entries',
373                     'sue_entries',
374                     'arg_entries',
375                     'var_entries',
376                     'pyfunc_entries',
377                     'cfunc_entries',
378                     'c_class_entries'):
379            self_entries = getattr(self, attr)
380            names = set(e.name for e in self_entries)
381            for entry in getattr(other, attr):
382                if (entry.used or merge_unused) and entry.name not in names:
383                    self_entries.append(entry)
384
385    def __str__(self):
386        return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
387
388    def qualifying_scope(self):
389        return self.parent_scope
390
391    def mangle(self, prefix, name = None):
392        if name:
393            return "%s%s%s" % (prefix, self.scope_prefix, name)
394        else:
395            return self.parent_scope.mangle(prefix, self.name)
396
397    def mangle_internal(self, name):
398        # Mangle an internal name so as not to clash with any
399        # user-defined name in this scope.
400        prefix = "%s%s_" % (Naming.pyrex_prefix, name)
401        return self.mangle(prefix)
402        #return self.parent_scope.mangle(prefix, self.name)
403
404    def mangle_class_private_name(self, name):
405        if self.parent_scope:
406            return self.parent_scope.mangle_class_private_name(name)
407        return name
408
409    def next_id(self, name=None):
410        # Return a cname fragment that is unique for this module
411        counters = self.global_scope().id_counters
412        try:
413            count = counters[name] + 1
414        except KeyError:
415            count = 0
416        counters[name] = count
417        if name:
418            if not count:
419                # unique names don't need a suffix, reoccurrences will get one
420                return name
421            return '%s%d' % (name, count)
422        else:
423            return '%d' % count
424
425    def global_scope(self):
426        """ Return the module-level scope containing this scope. """
427        return self.outer_scope.global_scope()
428
429    def builtin_scope(self):
430        """ Return the module-level scope containing this scope. """
431        return self.outer_scope.builtin_scope()
432
433    def iter_local_scopes(self):
434        yield self
435        if self.subscopes:
436            for scope in sorted(self.subscopes, key=operator.attrgetter('scope_prefix')):
437                yield scope
438
439    def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0, create_wrapper = 0):
440        # Create new entry, and add to dictionary if
441        # name is not None. Reports a warning if already
442        # declared.
443        if type.is_buffer and not isinstance(self, LocalScope): # and not is_type:
444            error(pos, 'Buffer types only allowed as function local variables')
445        if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
446            # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
447            warning(pos, "'%s' is a reserved name in C." % cname, -1)
448        entries = self.entries
449        if name and name in entries and not shadow:
450            old_entry = entries[name]
451
452            # Reject redeclared C++ functions only if they have the same type signature.
453            cpp_override_allowed = False
454            if type.is_cfunction and old_entry.type.is_cfunction and self.is_cpp():
455                for alt_entry in old_entry.all_alternatives():
456                    if type == alt_entry.type:
457                        if name == '<init>' and not type.args:
458                            # Cython pre-declares the no-args constructor - allow later user definitions.
459                            cpp_override_allowed = True
460                        break
461                else:
462                    cpp_override_allowed = True
463
464            if cpp_override_allowed:
465                # C++ function/method overrides with different signatures are ok.
466                pass
467            elif self.is_cpp_class_scope and entries[name].is_inherited:
468                # Likewise ignore inherited classes.
469                pass
470            elif visibility == 'extern':
471                # Silenced outside of "cdef extern" blocks, until we have a safe way to
472                # prevent pxd-defined cpdef functions from ending up here.
473                warning(pos, "'%s' redeclared " % name, 1 if self.in_cinclude else 0)
474            elif visibility != 'ignore':
475                error(pos, "'%s' redeclared " % name)
476                entries[name].already_declared_here()
477        entry = Entry(name, cname, type, pos = pos)
478        entry.in_cinclude = self.in_cinclude
479        entry.create_wrapper = create_wrapper
480        if name:
481            entry.qualified_name = self.qualify_name(name)
482#            if name in entries and self.is_cpp():
483#                entries[name].overloaded_alternatives.append(entry)
484#            else:
485#                entries[name] = entry
486            if not shadow:
487                entries[name] = entry
488
489        if type.is_memoryviewslice:
490            from . import MemoryView
491            entry.init = MemoryView.memslice_entry_init
492
493        entry.scope = self
494        entry.visibility = visibility
495        return entry
496
497    def qualify_name(self, name):
498        return EncodedString("%s.%s" % (self.qualified_name, name))
499
500    def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0, create_wrapper = 0):
501        # Add an entry for a named constant.
502        if not cname:
503            if self.in_cinclude or (visibility == 'public' or api):
504                cname = name
505            else:
506                cname = self.mangle(Naming.enum_prefix, name)
507        entry = self.declare(name, cname, type, pos, visibility, create_wrapper = create_wrapper)
508        entry.is_const = 1
509        entry.value_node = value
510        return entry
511
512    def declare_type(self, name, type, pos,
513            cname = None, visibility = 'private', api = 0, defining = 1,
514            shadow = 0, template = 0):
515        # Add an entry for a type definition.
516        if not cname:
517            cname = name
518        entry = self.declare(name, cname, type, pos, visibility, shadow,
519                             is_type=True)
520        entry.is_type = 1
521        entry.api = api
522        if defining:
523            self.type_entries.append(entry)
524
525        if not template:
526            type.entry = entry
527
528        # here we would set as_variable to an object representing this type
529        return entry
530
531    def declare_typedef(self, name, base_type, pos, cname = None,
532                        visibility = 'private', api = 0):
533        if not cname:
534            if self.in_cinclude or (visibility != 'private' or api):
535                cname = name
536            else:
537                cname = self.mangle(Naming.type_prefix, name)
538        try:
539            if self.is_cpp_class_scope:
540                namespace = self.outer_scope.lookup(self.name).type
541            else:
542                namespace = None
543            type = PyrexTypes.create_typedef_type(name, base_type, cname,
544                                                  (visibility == 'extern'),
545                                                  namespace)
546        except ValueError as e:
547            error(pos, e.args[0])
548            type = PyrexTypes.error_type
549        entry = self.declare_type(name, type, pos, cname,
550                                  visibility = visibility, api = api)
551        type.qualified_name = entry.qualified_name
552        return entry
553
554    def declare_struct_or_union(self, name, kind, scope,
555                                typedef_flag, pos, cname = None,
556                                visibility = 'private', api = 0,
557                                packed = False):
558        # Add an entry for a struct or union definition.
559        if not cname:
560            if self.in_cinclude or (visibility == 'public' or api):
561                cname = name
562            else:
563                cname = self.mangle(Naming.type_prefix, name)
564        entry = self.lookup_here(name)
565        if not entry:
566            type = PyrexTypes.CStructOrUnionType(
567                name, kind, scope, typedef_flag, cname, packed)
568            entry = self.declare_type(name, type, pos, cname,
569                visibility = visibility, api = api,
570                defining = scope is not None)
571            self.sue_entries.append(entry)
572            type.entry = entry
573        else:
574            if not (entry.is_type and entry.type.is_struct_or_union
575                    and entry.type.kind == kind):
576                warning(pos, "'%s' redeclared  " % name, 0)
577            elif scope and entry.type.scope:
578                warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
579            else:
580                self.check_previous_typedef_flag(entry, typedef_flag, pos)
581                self.check_previous_visibility(entry, visibility, pos)
582                if scope:
583                    entry.type.scope = scope
584                    self.type_entries.append(entry)
585        if self.is_cpp_class_scope:
586            entry.type.namespace = self.outer_scope.lookup(self.name).type
587        return entry
588
589    def declare_cpp_class(self, name, scope,
590            pos, cname = None, base_classes = (),
591            visibility = 'extern', templates = None):
592        if cname is None:
593            if self.in_cinclude or (visibility != 'private'):
594                cname = name
595            else:
596                cname = self.mangle(Naming.type_prefix, name)
597        base_classes = list(base_classes)
598        entry = self.lookup_here(name)
599        if not entry:
600            type = PyrexTypes.CppClassType(
601                name, scope, cname, base_classes, templates = templates)
602            entry = self.declare_type(name, type, pos, cname,
603                visibility = visibility, defining = scope is not None)
604            self.sue_entries.append(entry)
605        else:
606            if not (entry.is_type and entry.type.is_cpp_class):
607                error(pos, "'%s' redeclared " % name)
608                entry.already_declared_here()
609                return None
610            elif scope and entry.type.scope:
611                warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
612            else:
613                if scope:
614                    entry.type.scope = scope
615                    self.type_entries.append(entry)
616            if base_classes:
617                if entry.type.base_classes and entry.type.base_classes != base_classes:
618                    error(pos, "Base type does not match previous declaration")
619                    entry.already_declared_here()
620                else:
621                    entry.type.base_classes = base_classes
622            if templates or entry.type.templates:
623                if templates != entry.type.templates:
624                    error(pos, "Template parameters do not match previous declaration")
625                    entry.already_declared_here()
626
627        def declare_inherited_attributes(entry, base_classes):
628            for base_class in base_classes:
629                if base_class is PyrexTypes.error_type:
630                    continue
631                if base_class.scope is None:
632                    error(pos, "Cannot inherit from incomplete type")
633                else:
634                    declare_inherited_attributes(entry, base_class.base_classes)
635                    entry.type.scope.declare_inherited_cpp_attributes(base_class)
636        if scope:
637            declare_inherited_attributes(entry, base_classes)
638            scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos)
639        if self.is_cpp_class_scope:
640            entry.type.namespace = self.outer_scope.lookup(self.name).type
641        return entry
642
643    def check_previous_typedef_flag(self, entry, typedef_flag, pos):
644        if typedef_flag != entry.type.typedef_flag:
645            error(pos, "'%s' previously declared using '%s'" % (
646                entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
647
648    def check_previous_visibility(self, entry, visibility, pos):
649        if entry.visibility != visibility:
650            error(pos, "'%s' previously declared as '%s'" % (
651                entry.name, entry.visibility))
652
653    def declare_enum(self, name, pos, cname, typedef_flag,
654            visibility = 'private', api = 0, create_wrapper = 0):
655        if name:
656            if not cname:
657                if (self.in_cinclude or visibility == 'public'
658                    or visibility == 'extern' or api):
659                    cname = name
660                else:
661                    cname = self.mangle(Naming.type_prefix, name)
662            if self.is_cpp_class_scope:
663                namespace = self.outer_scope.lookup(self.name).type
664            else:
665                namespace = None
666            type = PyrexTypes.CEnumType(name, cname, typedef_flag, namespace)
667        else:
668            type = PyrexTypes.c_anon_enum_type
669        entry = self.declare_type(name, type, pos, cname = cname,
670            visibility = visibility, api = api)
671        entry.create_wrapper = create_wrapper
672        entry.enum_values = []
673        self.sue_entries.append(entry)
674        return entry
675
676    def declare_tuple_type(self, pos, components):
677        return self.outer_scope.declare_tuple_type(pos, components)
678
679    def declare_var(self, name, type, pos,
680                    cname = None, visibility = 'private',
681                    api = 0, in_pxd = 0, is_cdef = 0):
682        # Add an entry for a variable.
683        if not cname:
684            if visibility != 'private' or api:
685                cname = name
686            else:
687                cname = self.mangle(Naming.var_prefix, name)
688        if type.is_cpp_class and visibility != 'extern':
689            type.check_nullary_constructor(pos)
690        entry = self.declare(name, cname, type, pos, visibility)
691        entry.is_variable = 1
692        if in_pxd and visibility != 'extern':
693            entry.defined_in_pxd = 1
694            entry.used = 1
695        if api:
696            entry.api = 1
697            entry.used = 1
698        return entry
699
700    def declare_builtin(self, name, pos):
701        return self.outer_scope.declare_builtin(name, pos)
702
703    def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
704        if entry and not entry.type.is_cfunction:
705            error(pos, "'%s' already declared" % name)
706            error(entry.pos, "Previous declaration is here")
707        entry = self.declare_var(name, py_object_type, pos, visibility=visibility)
708        entry.signature = pyfunction_signature
709        self.pyfunc_entries.append(entry)
710        return entry
711
712    def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
713        # Add an entry for a Python function.
714        entry = self.lookup_here(name)
715        if not allow_redefine:
716            return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
717        if entry:
718            if entry.type.is_unspecified:
719                entry.type = py_object_type
720            elif entry.type is not py_object_type:
721                return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
722        else: # declare entry stub
723            self.declare_var(name, py_object_type, pos, visibility=visibility)
724        entry = self.declare_var(None, py_object_type, pos,
725                                 cname=name, visibility='private')
726        entry.name = EncodedString(name)
727        entry.qualified_name = self.qualify_name(name)
728        entry.signature = pyfunction_signature
729        entry.is_anonymous = True
730        return entry
731
732    def declare_lambda_function(self, lambda_name, pos):
733        # Add an entry for an anonymous Python function.
734        func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
735        pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
736        qualified_name = self.qualify_name(lambda_name)
737
738        entry = self.declare(None, func_cname, py_object_type, pos, 'private')
739        entry.name = lambda_name
740        entry.qualified_name = qualified_name
741        entry.pymethdef_cname = pymethdef_cname
742        entry.func_cname = func_cname
743        entry.signature = pyfunction_signature
744        entry.is_anonymous = True
745        return entry
746
747    def add_lambda_def(self, def_node):
748        self.lambda_defs.append(def_node)
749
750    def register_pyfunction(self, entry):
751        self.pyfunc_entries.append(entry)
752
753    def declare_cfunction(self, name, type, pos,
754                          cname=None, visibility='private', api=0, in_pxd=0,
755                          defining=0, modifiers=(), utility_code=None, overridable=False):
756        # Add an entry for a C function.
757        if not cname:
758            if visibility != 'private' or api:
759                cname = name
760            else:
761                cname = self.mangle(Naming.func_prefix, name)
762        entry = self.lookup_here(name)
763        if entry:
764            if not in_pxd and visibility != entry.visibility and visibility == 'extern':
765                # Previously declared, but now extern => treat this
766                # as implementing the function, using the new cname
767                defining = True
768                visibility = entry.visibility
769                entry.cname = cname
770                entry.func_cname = cname
771            if visibility != 'private' and visibility != entry.visibility:
772                warning(pos, "Function '%s' previously declared as '%s', now as '%s'" % (name, entry.visibility, visibility), 1)
773            if overridable != entry.is_overridable:
774                warning(pos, "Function '%s' previously declared as '%s'" % (
775                    name, 'cpdef' if overridable else 'cdef'), 1)
776            if entry.type.same_as(type):
777                # Fix with_gil vs nogil.
778                entry.type = entry.type.with_with_gil(type.with_gil)
779            else:
780                if visibility == 'extern' and entry.visibility == 'extern':
781                    can_override = False
782                    if self.is_cpp():
783                        can_override = True
784                    elif cname:
785                        # if all alternatives have different cnames,
786                        # it's safe to allow signature overrides
787                        for alt_entry in entry.all_alternatives():
788                            if not alt_entry.cname or cname == alt_entry.cname:
789                                break # cname not unique!
790                        else:
791                            can_override = True
792                    if can_override:
793                        temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
794                        temp.overloaded_alternatives = entry.all_alternatives()
795                        entry = temp
796                    else:
797                        warning(pos, "Function signature does not match previous declaration", 1)
798                        entry.type = type
799                elif not in_pxd and entry.defined_in_pxd and type.compatible_signature_with(entry.type):
800                    # TODO: check that this was done by a signature optimisation and not a user error.
801                    #warning(pos, "Function signature does not match previous declaration", 1)
802                    entry.type = type
803                else:
804                    error(pos, "Function signature does not match previous declaration")
805        else:
806            entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
807            entry.func_cname = cname
808            entry.is_overridable = overridable
809        if in_pxd and visibility != 'extern':
810            entry.defined_in_pxd = 1
811        if api:
812            entry.api = 1
813        if not defining and not in_pxd and visibility != 'extern':
814            error(pos, "Non-extern C function '%s' declared but not defined" % name)
815        if defining:
816            entry.is_implemented = True
817        if modifiers:
818            entry.func_modifiers = modifiers
819        if utility_code:
820            assert not entry.utility_code, "duplicate utility code definition in entry %s (%s)" % (name, cname)
821            entry.utility_code = utility_code
822        if overridable:
823            # names of cpdef functions can be used as variables and can be assigned to
824            var_entry = Entry(name, cname, py_object_type)   # FIXME: cname?
825            var_entry.qualified_name = self.qualify_name(name)
826            var_entry.is_variable = 1
827            var_entry.is_pyglobal = 1
828            var_entry.scope = entry.scope
829            entry.as_variable = var_entry
830        type.entry = entry
831        return entry
832
833    def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False):
834        # Add a C function entry without giving it a func_cname.
835        entry = self.declare(name, cname, type, pos, visibility)
836        entry.is_cfunction = 1
837        if modifiers:
838            entry.func_modifiers = modifiers
839        if inherited or type.is_fused:
840            self.cfunc_entries.append(entry)
841        else:
842            # For backwards compatibility reasons, we must keep all non-fused methods
843            # before all fused methods, but separately for each type.
844            i = len(self.cfunc_entries)
845            for cfunc_entry in reversed(self.cfunc_entries):
846                if cfunc_entry.is_inherited or not cfunc_entry.type.is_fused:
847                    break
848                i -= 1
849            self.cfunc_entries.insert(i, entry)
850        return entry
851
852    def find(self, name, pos):
853        # Look up name, report error if not found.
854        entry = self.lookup(name)
855        if entry:
856            return entry
857        else:
858            error(pos, "'%s' is not declared" % name)
859
860    def find_imported_module(self, path, pos):
861        # Look up qualified name, must be a module, report error if not found.
862        # Path is a list of names.
863        scope = self
864        for name in path:
865            entry = scope.find(name, pos)
866            if not entry:
867                return None
868            if entry.as_module:
869                scope = entry.as_module
870            else:
871                error(pos, "'%s' is not a cimported module" % '.'.join(path))
872                return None
873        return scope
874
875    def lookup(self, name):
876        # Look up name in this scope or an enclosing one.
877        # Return None if not found.
878        return (self.lookup_here(name)
879            or (self.outer_scope and self.outer_scope.lookup(name))
880            or None)
881
882    def lookup_here(self, name):
883        # Look up in this scope only, return None if not found.
884        return self.entries.get(name, None)
885
886    def lookup_target(self, name):
887        # Look up name in this scope only. Declare as Python
888        # variable if not found.
889        entry = self.lookup_here(name)
890        if not entry:
891            entry = self.declare_var(name, py_object_type, None)
892        return entry
893
894    def lookup_type(self, name):
895        entry = self.lookup(name)
896        if entry and entry.is_type:
897            if entry.type.is_fused and self.fused_to_specific:
898                return entry.type.specialize(self.fused_to_specific)
899            return entry.type
900
901    def lookup_operator(self, operator, operands):
902        if operands[0].type.is_cpp_class:
903            obj_type = operands[0].type
904            method = obj_type.scope.lookup("operator%s" % operator)
905            if method is not None:
906                arg_types = [arg.type for arg in operands[1:]]
907                res = PyrexTypes.best_match([arg.type for arg in operands[1:]],
908                                            method.all_alternatives())
909                if res is not None:
910                    return res
911        function = self.lookup("operator%s" % operator)
912        function_alternatives = []
913        if function is not None:
914            function_alternatives = function.all_alternatives()
915
916        # look-up nonmember methods listed within a class
917        method_alternatives = []
918        if len(operands)==2: # binary operators only
919            for n in range(2):
920                if operands[n].type.is_cpp_class:
921                    obj_type = operands[n].type
922                    method = obj_type.scope.lookup("operator%s" % operator)
923                    if method is not None:
924                        method_alternatives += method.all_alternatives()
925
926        if (not method_alternatives) and (not function_alternatives):
927            return None
928
929        # select the unique alternatives
930        all_alternatives = list(set(method_alternatives + function_alternatives))
931
932        return PyrexTypes.best_match([arg.type for arg in operands],
933                                     all_alternatives)
934
935    def lookup_operator_for_types(self, pos, operator, types):
936        from .Nodes import Node
937        class FakeOperand(Node):
938            pass
939        operands = [FakeOperand(pos, type=type) for type in types]
940        return self.lookup_operator(operator, operands)
941
942    def use_utility_code(self, new_code):
943        self.global_scope().use_utility_code(new_code)
944
945    def use_entry_utility_code(self, entry):
946        self.global_scope().use_entry_utility_code(entry)
947
948    def defines_any(self, names):
949        # Test whether any of the given names are defined in this scope.
950        for name in names:
951            if name in self.entries:
952                return 1
953        return 0
954
955    def defines_any_special(self, names):
956        # Test whether any of the given names are defined as special methods in this scope.
957        for name in names:
958            if name in self.entries and self.entries[name].is_special:
959                return 1
960        return 0
961
962    def infer_types(self):
963        from .TypeInference import get_type_inferer
964        get_type_inferer().infer_types(self)
965
966    def is_cpp(self):
967        outer = self.outer_scope
968        if outer is None:
969            return False
970        else:
971            return outer.is_cpp()
972
973    def add_include_file(self, filename, verbatim_include=None, late=False):
974        self.outer_scope.add_include_file(filename, verbatim_include, late)
975
976
977class PreImportScope(Scope):
978
979    namespace_cname = Naming.preimport_cname
980
981    def __init__(self):
982        Scope.__init__(self, Options.pre_import, None, None)
983
984    def declare_builtin(self, name, pos):
985        entry = self.declare(name, name, py_object_type, pos, 'private')
986        entry.is_variable = True
987        entry.is_pyglobal = True
988        return entry
989
990
991class BuiltinScope(Scope):
992    #  The builtin namespace.
993
994    is_builtin_scope = True
995
996    def __init__(self):
997        if Options.pre_import is None:
998            Scope.__init__(self, "__builtin__", None, None)
999        else:
1000            Scope.__init__(self, "__builtin__", PreImportScope(), None)
1001        self.type_names = {}
1002
1003        for name, definition in sorted(self.builtin_entries.items()):
1004            cname, type = definition
1005            self.declare_var(name, type, None, cname)
1006
1007    def lookup(self, name, language_level=None, str_is_str=None):
1008        # 'language_level' and 'str_is_str' are passed by ModuleScope
1009        if name == 'str':
1010            if str_is_str is None:
1011                str_is_str = language_level in (None, 2)
1012            if not str_is_str:
1013                name = 'unicode'
1014        return Scope.lookup(self, name)
1015
1016    def declare_builtin(self, name, pos):
1017        if not hasattr(builtins, name):
1018            if self.outer_scope is not None:
1019                return self.outer_scope.declare_builtin(name, pos)
1020            else:
1021                if Options.error_on_unknown_names:
1022                    error(pos, "undeclared name not builtin: %s" % name)
1023                else:
1024                    warning(pos, "undeclared name not builtin: %s" % name, 2)
1025
1026    def declare_builtin_cfunction(self, name, type, cname, python_equiv=None, utility_code=None):
1027        # If python_equiv == "*", the Python equivalent has the same name
1028        # as the entry, otherwise it has the name specified by python_equiv.
1029        name = EncodedString(name)
1030        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
1031                                       utility_code=utility_code)
1032        if python_equiv:
1033            if python_equiv == "*":
1034                python_equiv = name
1035            else:
1036                python_equiv = EncodedString(python_equiv)
1037            var_entry = Entry(python_equiv, python_equiv, py_object_type)
1038            var_entry.qualified_name = self.qualify_name(name)
1039            var_entry.is_variable = 1
1040            var_entry.is_builtin = 1
1041            var_entry.utility_code = utility_code
1042            var_entry.scope = entry.scope
1043            entry.as_variable = var_entry
1044        return entry
1045
1046    def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None):
1047        name = EncodedString(name)
1048        type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname)
1049        scope = CClassScope(name, outer_scope=None, visibility='extern')
1050        scope.directives = {}
1051        if name == 'bool':
1052            type.is_final_type = True
1053        type.set_scope(scope)
1054        self.type_names[name] = 1
1055        entry = self.declare_type(name, type, None, visibility='extern')
1056        entry.utility_code = utility_code
1057
1058        var_entry = Entry(name = entry.name,
1059            type = self.lookup('type').type, # make sure "type" is the first type declared...
1060            pos = entry.pos,
1061            cname = entry.type.typeptr_cname)
1062        var_entry.qualified_name = self.qualify_name(name)
1063        var_entry.is_variable = 1
1064        var_entry.is_cglobal = 1
1065        var_entry.is_readonly = 1
1066        var_entry.is_builtin = 1
1067        var_entry.utility_code = utility_code
1068        var_entry.scope = self
1069        if Options.cache_builtins:
1070            var_entry.is_const = True
1071        entry.as_variable = var_entry
1072
1073        return type
1074
1075    def builtin_scope(self):
1076        return self
1077
1078    builtin_entries = {
1079
1080        "type":   ["((PyObject*)&PyType_Type)", py_object_type],
1081
1082        "bool":   ["((PyObject*)&PyBool_Type)", py_object_type],
1083        "int":    ["((PyObject*)&PyInt_Type)", py_object_type],
1084        "long":   ["((PyObject*)&PyLong_Type)", py_object_type],
1085        "float":  ["((PyObject*)&PyFloat_Type)", py_object_type],
1086        "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
1087
1088        "bytes":  ["((PyObject*)&PyBytes_Type)", py_object_type],
1089        "bytearray":   ["((PyObject*)&PyByteArray_Type)", py_object_type],
1090        "str":    ["((PyObject*)&PyString_Type)", py_object_type],
1091        "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
1092
1093        "tuple":  ["((PyObject*)&PyTuple_Type)", py_object_type],
1094        "list":   ["((PyObject*)&PyList_Type)", py_object_type],
1095        "dict":   ["((PyObject*)&PyDict_Type)", py_object_type],
1096        "set":    ["((PyObject*)&PySet_Type)", py_object_type],
1097        "frozenset":   ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
1098
1099        "slice":  ["((PyObject*)&PySlice_Type)", py_object_type],
1100#        "file":   ["((PyObject*)&PyFile_Type)", py_object_type],  # not in Py3
1101
1102        "None":   ["Py_None", py_object_type],
1103        "False":  ["Py_False", py_object_type],
1104        "True":   ["Py_True", py_object_type],
1105    }
1106
1107const_counter = 1 # As a temporary solution for compiling code in pxds
1108
1109class ModuleScope(Scope):
1110    # module_name          string             Python name of the module
1111    # module_cname         string             C name of Python module object
1112    # #module_dict_cname   string             C name of module dict object
1113    # method_table_cname   string             C name of method table
1114    # doc                  string             Module doc string
1115    # doc_cname            string             C name of module doc string
1116    # utility_code_list    [UtilityCode]      Queuing utility codes for forwarding to Code.py
1117    # c_includes           {key: IncludeCode} C headers or verbatim code to be generated
1118    #                                         See process_include() for more documentation
1119    # string_to_entry      {string : Entry}   Map string const to entry
1120    # identifier_to_entry  {string : Entry}   Map identifier string const to entry
1121    # context              Context
1122    # parent_module        Scope              Parent in the import namespace
1123    # module_entries       {string : Entry}   For cimport statements
1124    # type_names           {string : 1}       Set of type names (used during parsing)
1125    # included_files       [string]           Cython sources included with 'include'
1126    # pxd_file_loaded      boolean            Corresponding .pxd file has been processed
1127    # cimported_modules    [ModuleScope]      Modules imported with cimport
1128    # types_imported       {PyrexType}        Set of types for which import code generated
1129    # has_import_star      boolean            Module contains import *
1130    # cpp                  boolean            Compiling a C++ file
1131    # is_cython_builtin    boolean            Is this the Cython builtin scope (or a child scope)
1132    # is_package           boolean            Is this a package module? (__init__)
1133
1134    is_module_scope = 1
1135    has_import_star = 0
1136    is_cython_builtin = 0
1137    old_style_globals = 0
1138
1139    def __init__(self, name, parent_module, context):
1140        from . import Builtin
1141        self.parent_module = parent_module
1142        outer_scope = Builtin.builtin_scope
1143        Scope.__init__(self, name, outer_scope, parent_module)
1144        if name == "__init__":
1145            # Treat Spam/__init__.pyx specially, so that when Python loads
1146            # Spam/__init__.so, initSpam() is defined.
1147            self.module_name = parent_module.module_name
1148            self.is_package = True
1149        else:
1150            self.module_name = name
1151            self.is_package = False
1152        self.module_name = EncodedString(self.module_name)
1153        self.context = context
1154        self.module_cname = Naming.module_cname
1155        self.module_dict_cname = Naming.moddict_cname
1156        self.method_table_cname = Naming.methtable_cname
1157        self.doc = ""
1158        self.doc_cname = Naming.moddoc_cname
1159        self.utility_code_list = []
1160        self.module_entries = {}
1161        self.c_includes = {}
1162        self.type_names = dict(outer_scope.type_names)
1163        self.pxd_file_loaded = 0
1164        self.cimported_modules = []
1165        self.types_imported = set()
1166        self.included_files = []
1167        self.has_extern_class = 0
1168        self.cached_builtins = []
1169        self.undeclared_cached_builtins = []
1170        self.namespace_cname = self.module_cname
1171        self._cached_tuple_types = {}
1172        for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__',
1173                         '__spec__', '__loader__', '__package__', '__cached__']:
1174            self.declare_var(EncodedString(var_name), py_object_type, None)
1175        self.process_include(Code.IncludeCode("Python.h", initial=True))
1176
1177    def qualifying_scope(self):
1178        return self.parent_module
1179
1180    def global_scope(self):
1181        return self
1182
1183    def lookup(self, name, language_level=None, str_is_str=None):
1184        entry = self.lookup_here(name)
1185        if entry is not None:
1186            return entry
1187
1188        if language_level is None:
1189            language_level = self.context.language_level if self.context is not None else 3
1190        if str_is_str is None:
1191            str_is_str = language_level == 2 or (
1192                self.context is not None and Future.unicode_literals not in self.context.future_directives)
1193
1194        return self.outer_scope.lookup(name, language_level=language_level, str_is_str=str_is_str)
1195
1196    def declare_tuple_type(self, pos, components):
1197        components = tuple(components)
1198        try:
1199            ttype = self._cached_tuple_types[components]
1200        except KeyError:
1201            ttype = self._cached_tuple_types[components] = PyrexTypes.c_tuple_type(components)
1202        cname = ttype.cname
1203        entry = self.lookup_here(cname)
1204        if not entry:
1205            scope = StructOrUnionScope(cname)
1206            for ix, component in enumerate(components):
1207                scope.declare_var(name="f%s" % ix, type=component, pos=pos)
1208            struct_entry = self.declare_struct_or_union(
1209                cname + '_struct', 'struct', scope, typedef_flag=True, pos=pos, cname=cname)
1210            self.type_entries.remove(struct_entry)
1211            ttype.struct_entry = struct_entry
1212            entry = self.declare_type(cname, ttype, pos, cname)
1213        ttype.entry = entry
1214        return entry
1215
1216    def declare_builtin(self, name, pos):
1217        if not hasattr(builtins, name) \
1218               and name not in Code.non_portable_builtins_map \
1219               and name not in Code.uncachable_builtins:
1220            if self.has_import_star:
1221                entry = self.declare_var(name, py_object_type, pos)
1222                return entry
1223            else:
1224                if Options.error_on_unknown_names:
1225                    error(pos, "undeclared name not builtin: %s" % name)
1226                else:
1227                    warning(pos, "undeclared name not builtin: %s" % name, 2)
1228                # unknown - assume it's builtin and look it up at runtime
1229                entry = self.declare(name, None, py_object_type, pos, 'private')
1230                entry.is_builtin = 1
1231                return entry
1232        if Options.cache_builtins:
1233            for entry in self.cached_builtins:
1234                if entry.name == name:
1235                    return entry
1236        if name == 'globals' and not self.old_style_globals:
1237            return self.outer_scope.lookup('__Pyx_Globals')
1238        else:
1239            entry = self.declare(None, None, py_object_type, pos, 'private')
1240        if Options.cache_builtins and name not in Code.uncachable_builtins:
1241            entry.is_builtin = 1
1242            entry.is_const = 1 # cached
1243            entry.name = name
1244            entry.cname = Naming.builtin_prefix + name
1245            self.cached_builtins.append(entry)
1246            self.undeclared_cached_builtins.append(entry)
1247        else:
1248            entry.is_builtin = 1
1249            entry.name = name
1250        entry.qualified_name = self.builtin_scope().qualify_name(name)
1251        return entry
1252
1253    def find_module(self, module_name, pos, relative_level=-1):
1254        # Find a module in the import namespace, interpreting
1255        # relative imports relative to this module's parent.
1256        # Finds and parses the module's .pxd file if the module
1257        # has not been referenced before.
1258        relative_to = None
1259        absolute_fallback = False
1260        if relative_level is not None and relative_level > 0:
1261            # explicit relative cimport
1262            # error of going beyond top-level is handled in cimport node
1263            relative_to = self
1264            while relative_level > 0 and relative_to:
1265                relative_to = relative_to.parent_module
1266                relative_level -= 1
1267        elif relative_level != 0:
1268            # -1 or None: try relative cimport first, then absolute
1269            relative_to = self.parent_module
1270            absolute_fallback = True
1271
1272        module_scope = self.global_scope()
1273        return module_scope.context.find_module(
1274            module_name, relative_to=relative_to, pos=pos, absolute_fallback=absolute_fallback)
1275
1276    def find_submodule(self, name):
1277        # Find and return scope for a submodule of this module,
1278        # creating a new empty one if necessary. Doesn't parse .pxd.
1279        if '.' in name:
1280            name, submodule = name.split('.', 1)
1281        else:
1282            submodule = None
1283        scope = self.lookup_submodule(name)
1284        if not scope:
1285            scope = ModuleScope(name, parent_module=self, context=self.context)
1286            self.module_entries[name] = scope
1287        if submodule:
1288            scope = scope.find_submodule(submodule)
1289        return scope
1290
1291    def lookup_submodule(self, name):
1292        # Return scope for submodule of this module, or None.
1293        if '.' in name:
1294            name, submodule = name.split('.', 1)
1295        else:
1296            submodule = None
1297        module = self.module_entries.get(name, None)
1298        if submodule and module is not None:
1299            module = module.lookup_submodule(submodule)
1300        return module
1301
1302    def add_include_file(self, filename, verbatim_include=None, late=False):
1303        """
1304        Add `filename` as include file. Add `verbatim_include` as
1305        verbatim text in the C file.
1306        Both `filename` and `verbatim_include` can be `None` or empty.
1307        """
1308        inc = Code.IncludeCode(filename, verbatim_include, late=late)
1309        self.process_include(inc)
1310
1311    def process_include(self, inc):
1312        """
1313        Add `inc`, which is an instance of `IncludeCode`, to this
1314        `ModuleScope`. This either adds a new element to the
1315        `c_includes` dict or it updates an existing entry.
1316
1317        In detail: the values of the dict `self.c_includes` are
1318        instances of `IncludeCode` containing the code to be put in the
1319        generated C file. The keys of the dict are needed to ensure
1320        uniqueness in two ways: if an include file is specified in
1321        multiple "cdef extern" blocks, only one `#include` statement is
1322        generated. Second, the same include might occur multiple times
1323        if we find it through multiple "cimport" paths. So we use the
1324        generated code (of the form `#include "header.h"`) as dict key.
1325
1326        If verbatim code does not belong to any include file (i.e. it
1327        was put in a `cdef extern from *` block), then we use a unique
1328        dict key: namely, the `sortkey()`.
1329
1330        One `IncludeCode` object can contain multiple pieces of C code:
1331        one optional "main piece" for the include file and several other
1332        pieces for the verbatim code. The `IncludeCode.dict_update`
1333        method merges the pieces of two different `IncludeCode` objects
1334        if needed.
1335        """
1336        key = inc.mainpiece()
1337        if key is None:
1338            key = inc.sortkey()
1339        inc.dict_update(self.c_includes, key)
1340        inc = self.c_includes[key]
1341
1342    def add_imported_module(self, scope):
1343        if scope not in self.cimported_modules:
1344            for inc in scope.c_includes.values():
1345                self.process_include(inc)
1346            self.cimported_modules.append(scope)
1347            for m in scope.cimported_modules:
1348                self.add_imported_module(m)
1349
1350    def add_imported_entry(self, name, entry, pos):
1351        if entry.is_pyglobal:
1352            # Allow cimports to follow imports.
1353            entry.is_variable = True
1354        if entry not in self.entries:
1355            self.entries[name] = entry
1356        else:
1357            warning(pos, "'%s' redeclared  " % name, 0)
1358
1359    def declare_module(self, name, scope, pos):
1360        # Declare a cimported module. This is represented as a
1361        # Python module-level variable entry with a module
1362        # scope attached to it. Reports an error and returns
1363        # None if previously declared as something else.
1364        entry = self.lookup_here(name)
1365        if entry:
1366            if entry.is_pyglobal and entry.as_module is scope:
1367                return entry # Already declared as the same module
1368            if not (entry.is_pyglobal and not entry.as_module):
1369                # SAGE -- I put this here so Pyrex
1370                # cimport's work across directories.
1371                # Currently it tries to multiply define
1372                # every module appearing in an import list.
1373                # It shouldn't be an error for a module
1374                # name to appear again, and indeed the generated
1375                # code compiles fine.
1376                return entry
1377        else:
1378            entry = self.declare_var(name, py_object_type, pos)
1379            entry.is_variable = 0
1380        entry.as_module = scope
1381        self.add_imported_module(scope)
1382        return entry
1383
1384    def declare_var(self, name, type, pos,
1385                    cname = None, visibility = 'private',
1386                    api = 0, in_pxd = 0, is_cdef = 0):
1387        # Add an entry for a global variable. If it is a Python
1388        # object type, and not declared with cdef, it will live
1389        # in the module dictionary, otherwise it will be a C
1390        # global variable.
1391        if not visibility in ('private', 'public', 'extern'):
1392            error(pos, "Module-level variable cannot be declared %s" % visibility)
1393        if not is_cdef:
1394            if type is unspecified_type:
1395                type = py_object_type
1396            if not (type.is_pyobject and not type.is_extension_type):
1397                raise InternalError(
1398                    "Non-cdef global variable is not a generic Python object")
1399
1400        if not cname:
1401            defining = not in_pxd
1402            if visibility == 'extern' or (visibility == 'public' and defining):
1403                cname = name
1404            else:
1405                cname = self.mangle(Naming.var_prefix, name)
1406
1407        entry = self.lookup_here(name)
1408        if entry and entry.defined_in_pxd:
1409            #if visibility != 'private' and visibility != entry.visibility:
1410            #    warning(pos, "Variable '%s' previously declared as '%s'" % (name, entry.visibility), 1)
1411            if not entry.type.same_as(type):
1412                if visibility == 'extern' and entry.visibility == 'extern':
1413                    warning(pos, "Variable '%s' type does not match previous declaration" % name, 1)
1414                    entry.type = type
1415                #else:
1416                #    error(pos, "Variable '%s' type does not match previous declaration" % name)
1417            if entry.visibility != "private":
1418                mangled_cname = self.mangle(Naming.var_prefix, name)
1419                if entry.cname == mangled_cname:
1420                    cname = name
1421                    entry.cname = name
1422            if not entry.is_implemented:
1423                entry.is_implemented = True
1424                return entry
1425
1426        entry = Scope.declare_var(self, name, type, pos,
1427                                  cname=cname, visibility=visibility,
1428                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1429        if is_cdef:
1430            entry.is_cglobal = 1
1431            if entry.type.declaration_value:
1432                entry.init = entry.type.declaration_value
1433            self.var_entries.append(entry)
1434        else:
1435            entry.is_pyglobal = 1
1436        if Options.cimport_from_pyx:
1437            entry.used = 1
1438        return entry
1439
1440    def declare_cfunction(self, name, type, pos,
1441                          cname=None, visibility='private', api=0, in_pxd=0,
1442                          defining=0, modifiers=(), utility_code=None, overridable=False):
1443        if not defining and 'inline' in modifiers:
1444            # TODO(github/1736): Make this an error.
1445            warning(pos, "Declarations should not be declared inline.", 1)
1446        # Add an entry for a C function.
1447        if not cname:
1448            if visibility == 'extern' or (visibility == 'public' and defining):
1449                cname = name
1450            else:
1451                cname = self.mangle(Naming.func_prefix, name)
1452        if visibility == 'extern' and type.optional_arg_count:
1453            error(pos, "Extern functions cannot have default arguments values.")
1454        entry = self.lookup_here(name)
1455        if entry and entry.defined_in_pxd:
1456            if entry.visibility != "private":
1457                mangled_cname = self.mangle(Naming.var_prefix, name)
1458                if entry.cname == mangled_cname:
1459                    cname = name
1460                    entry.cname = cname
1461                    entry.func_cname = cname
1462        entry = Scope.declare_cfunction(
1463            self, name, type, pos,
1464            cname=cname, visibility=visibility, api=api, in_pxd=in_pxd,
1465            defining=defining, modifiers=modifiers, utility_code=utility_code,
1466            overridable=overridable)
1467        return entry
1468
1469    def declare_global(self, name, pos):
1470        entry = self.lookup_here(name)
1471        if not entry:
1472            self.declare_var(name, py_object_type, pos)
1473
1474    def use_utility_code(self, new_code):
1475        if new_code is not None:
1476            self.utility_code_list.append(new_code)
1477
1478    def use_entry_utility_code(self, entry):
1479        if entry is None:
1480            return
1481        if entry.utility_code:
1482            self.utility_code_list.append(entry.utility_code)
1483        if entry.utility_code_definition:
1484            self.utility_code_list.append(entry.utility_code_definition)
1485
1486    def declare_c_class(self, name, pos, defining=0, implementing=0,
1487            module_name=None, base_type=None, objstruct_cname=None,
1488            typeobj_cname=None, typeptr_cname=None, visibility='private',
1489            typedef_flag=0, api=0, check_size=None,
1490            buffer_defaults=None, shadow=0):
1491        # If this is a non-extern typedef class, expose the typedef, but use
1492        # the non-typedef struct internally to avoid needing forward
1493        # declarations for anonymous structs.
1494        if typedef_flag and visibility != 'extern':
1495            if not (visibility == 'public' or api):
1496                warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
1497            objtypedef_cname = objstruct_cname
1498            typedef_flag = 0
1499        else:
1500            objtypedef_cname = None
1501        #
1502        #  Look for previous declaration as a type
1503        #
1504        entry = self.lookup_here(name)
1505        if entry and not shadow:
1506            type = entry.type
1507            if not (entry.is_type and type.is_extension_type):
1508                entry = None # Will cause redeclaration and produce an error
1509            else:
1510                scope = type.scope
1511                if typedef_flag and (not scope or scope.defined):
1512                    self.check_previous_typedef_flag(entry, typedef_flag, pos)
1513                if (scope and scope.defined) or (base_type and type.base_type):
1514                    if base_type and base_type is not type.base_type:
1515                        error(pos, "Base type does not match previous declaration")
1516                if base_type and not type.base_type:
1517                    type.base_type = base_type
1518        #
1519        #  Make a new entry if needed
1520        #
1521        if not entry or shadow:
1522            type = PyrexTypes.PyExtensionType(
1523                name, typedef_flag, base_type, visibility == 'extern', check_size=check_size)
1524            type.pos = pos
1525            type.buffer_defaults = buffer_defaults
1526            if objtypedef_cname is not None:
1527                type.objtypedef_cname = objtypedef_cname
1528            if visibility == 'extern':
1529                type.module_name = module_name
1530            else:
1531                type.module_name = self.qualified_name
1532            if typeptr_cname:
1533                type.typeptr_cname = typeptr_cname
1534            else:
1535                type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1536            entry = self.declare_type(name, type, pos, visibility = visibility,
1537                defining = 0, shadow = shadow)
1538            entry.is_cclass = True
1539            if objstruct_cname:
1540                type.objstruct_cname = objstruct_cname
1541            elif not entry.in_cinclude:
1542                type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1543            else:
1544                error(entry.pos,
1545                    "Object name required for 'public' or 'extern' C class")
1546            self.attach_var_entry_to_c_class(entry)
1547            self.c_class_entries.append(entry)
1548        #
1549        #  Check for re-definition and create scope if needed
1550        #
1551        if not type.scope:
1552            if defining or implementing:
1553                scope = CClassScope(name = name, outer_scope = self,
1554                    visibility = visibility)
1555                scope.directives = self.directives.copy()
1556                if base_type and base_type.scope:
1557                    scope.declare_inherited_c_attributes(base_type.scope)
1558                type.set_scope(scope)
1559                self.type_entries.append(entry)
1560        else:
1561            if defining and type.scope.defined:
1562                error(pos, "C class '%s' already defined" % name)
1563            elif implementing and type.scope.implemented:
1564                error(pos, "C class '%s' already implemented" % name)
1565        #
1566        #  Fill in options, checking for compatibility with any previous declaration
1567        #
1568        if defining:
1569            entry.defined_in_pxd = 1
1570        if implementing:   # So that filenames in runtime exceptions refer to
1571            entry.pos = pos  # the .pyx file and not the .pxd file
1572        if visibility != 'private' and entry.visibility != visibility:
1573            error(pos, "Class '%s' previously declared as '%s'"
1574                % (name, entry.visibility))
1575        if api:
1576            entry.api = 1
1577        if objstruct_cname:
1578            if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1579                error(pos, "Object struct name differs from previous declaration")
1580            type.objstruct_cname = objstruct_cname
1581        if typeobj_cname:
1582            if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1583                    error(pos, "Type object name differs from previous declaration")
1584            type.typeobj_cname = typeobj_cname
1585
1586        if self.directives.get('final'):
1587            entry.type.is_final_type = True
1588
1589        # cdef classes are always exported, but we need to set it to
1590        # distinguish between unused Cython utility code extension classes
1591        entry.used = True
1592
1593        #
1594        # Return new or existing entry
1595        #
1596        return entry
1597
1598    def allocate_vtable_names(self, entry):
1599        #  If extension type has a vtable, allocate vtable struct and
1600        #  slot names for it.
1601        type = entry.type
1602        if type.base_type and type.base_type.vtabslot_cname:
1603            #print "...allocating vtabslot_cname because base type has one" ###
1604            type.vtabslot_cname = "%s.%s" % (
1605                Naming.obj_base_cname, type.base_type.vtabslot_cname)
1606        elif type.scope and type.scope.cfunc_entries:
1607            # one special case here: when inheriting from builtin
1608            # types, the methods may also be built-in, in which
1609            # case they won't need a vtable
1610            entry_count = len(type.scope.cfunc_entries)
1611            base_type = type.base_type
1612            while base_type:
1613                # FIXME: this will break if we ever get non-inherited C methods
1614                if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
1615                    break
1616                if base_type.is_builtin_type:
1617                    # builtin base type defines all methods => no vtable needed
1618                    return
1619                base_type = base_type.base_type
1620            #print "...allocating vtabslot_cname because there are C methods" ###
1621            type.vtabslot_cname = Naming.vtabslot_cname
1622        if type.vtabslot_cname:
1623            #print "...allocating other vtable related cnames" ###
1624            type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1625            type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1626
1627    def check_c_classes_pxd(self):
1628        # Performs post-analysis checking and finishing up of extension types
1629        # being implemented in this module. This is called only for the .pxd.
1630        #
1631        # Checks all extension types declared in this scope to
1632        # make sure that:
1633        #
1634        #    * The extension type is fully declared
1635        #
1636        # Also allocates a name for the vtable if needed.
1637        #
1638        for entry in self.c_class_entries:
1639            # Check defined
1640            if not entry.type.scope:
1641                error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
1642
1643    def check_c_class(self, entry):
1644        type = entry.type
1645        name = entry.name
1646        visibility = entry.visibility
1647        # Check defined
1648        if not type.scope:
1649            error(entry.pos, "C class '%s' is declared but not defined" % name)
1650        # Generate typeobj_cname
1651        if visibility != 'extern' and not type.typeobj_cname:
1652            type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1653        ## Generate typeptr_cname
1654        #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1655        # Check C methods defined
1656        if type.scope:
1657            for method_entry in type.scope.cfunc_entries:
1658                if not method_entry.is_inherited and not method_entry.func_cname:
1659                    error(method_entry.pos, "C method '%s' is declared but not defined" %
1660                        method_entry.name)
1661        # Allocate vtable name if necessary
1662        if type.vtabslot_cname:
1663            #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1664            type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1665
1666    def check_c_classes(self):
1667        # Performs post-analysis checking and finishing up of extension types
1668        # being implemented in this module. This is called only for the main
1669        # .pyx file scope, not for cimported .pxd scopes.
1670        #
1671        # Checks all extension types declared in this scope to
1672        # make sure that:
1673        #
1674        #    * The extension type is implemented
1675        #    * All required object and type names have been specified or generated
1676        #    * All non-inherited C methods are implemented
1677        #
1678        # Also allocates a name for the vtable if needed.
1679        #
1680        debug_check_c_classes = 0
1681        if debug_check_c_classes:
1682            print("Scope.check_c_classes: checking scope " + self.qualified_name)
1683        for entry in self.c_class_entries:
1684            if debug_check_c_classes:
1685                print("...entry %s %s" % (entry.name, entry))
1686                print("......type = ",  entry.type)
1687                print("......visibility = ", entry.visibility)
1688            self.check_c_class(entry)
1689
1690    def check_c_functions(self):
1691        # Performs post-analysis checking making sure all
1692        # defined c functions are actually implemented.
1693        for name, entry in self.entries.items():
1694            if entry.is_cfunction:
1695                if (entry.defined_in_pxd
1696                        and entry.scope is self
1697                        and entry.visibility != 'extern'
1698                        and not entry.in_cinclude
1699                        and not entry.is_implemented):
1700                    error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1701
1702    def attach_var_entry_to_c_class(self, entry):
1703        # The name of an extension class has to serve as both a type
1704        # name and a variable name holding the type object. It is
1705        # represented in the symbol table by a type entry with a
1706        # variable entry attached to it. For the variable entry,
1707        # we use a read-only C global variable whose name is an
1708        # expression that refers to the type object.
1709        from . import Builtin
1710        var_entry = Entry(name = entry.name,
1711            type = Builtin.type_type,
1712            pos = entry.pos,
1713            cname = entry.type.typeptr_cname)
1714        var_entry.qualified_name = entry.qualified_name
1715        var_entry.is_variable = 1
1716        var_entry.is_cglobal = 1
1717        var_entry.is_readonly = 1
1718        var_entry.scope = entry.scope
1719        entry.as_variable = var_entry
1720
1721    def is_cpp(self):
1722        return self.cpp
1723
1724    def infer_types(self):
1725        from .TypeInference import PyObjectTypeInferer
1726        PyObjectTypeInferer().infer_types(self)
1727
1728
1729class LocalScope(Scope):
1730
1731    # Does the function have a 'with gil:' block?
1732    has_with_gil_block = False
1733
1734    # Transient attribute, used for symbol table variable declarations
1735    _in_with_gil_block = False
1736
1737    def __init__(self, name, outer_scope, parent_scope = None):
1738        if parent_scope is None:
1739            parent_scope = outer_scope
1740        Scope.__init__(self, name, outer_scope, parent_scope)
1741
1742    def mangle(self, prefix, name):
1743        return prefix + name
1744
1745    def declare_arg(self, name, type, pos):
1746        # Add an entry for an argument of a function.
1747        cname = self.mangle(Naming.var_prefix, name)
1748        entry = self.declare(name, cname, type, pos, 'private')
1749        entry.is_variable = 1
1750        if type.is_pyobject:
1751            entry.init = "0"
1752        entry.is_arg = 1
1753        #entry.borrowed = 1 # Not using borrowed arg refs for now
1754        self.arg_entries.append(entry)
1755        return entry
1756
1757    def declare_var(self, name, type, pos,
1758                    cname = None, visibility = 'private',
1759                    api = 0, in_pxd = 0, is_cdef = 0):
1760        # Add an entry for a local variable.
1761        if visibility in ('public', 'readonly'):
1762            error(pos, "Local variable cannot be declared %s" % visibility)
1763        entry = Scope.declare_var(self, name, type, pos,
1764                                  cname=cname, visibility=visibility,
1765                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1766        if entry.type.declaration_value:
1767            entry.init = entry.type.declaration_value
1768        entry.is_local = 1
1769
1770        entry.in_with_gil_block = self._in_with_gil_block
1771        self.var_entries.append(entry)
1772        return entry
1773
1774    def declare_global(self, name, pos):
1775        # Pull entry from global scope into local scope.
1776        if self.lookup_here(name):
1777            warning(pos, "'%s' redeclared  ", 0)
1778        else:
1779            entry = self.global_scope().lookup_target(name)
1780            self.entries[name] = entry
1781
1782    def declare_nonlocal(self, name, pos):
1783        # Pull entry from outer scope into local scope
1784        orig_entry = self.lookup_here(name)
1785        if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1786            error(pos, "'%s' redeclared as nonlocal" % name)
1787            orig_entry.already_declared_here()
1788        else:
1789            entry = self.lookup(name)
1790            if entry is None or not entry.from_closure:
1791                error(pos, "no binding for nonlocal '%s' found" % name)
1792
1793    def lookup(self, name):
1794        # Look up name in this scope or an enclosing one.
1795        # Return None if not found.
1796        entry = Scope.lookup(self, name)
1797        if entry is not None:
1798            entry_scope = entry.scope
1799            while entry_scope.is_genexpr_scope:
1800                entry_scope = entry_scope.outer_scope
1801            if entry_scope is not self and entry_scope.is_closure_scope:
1802                if hasattr(entry.scope, "scope_class"):
1803                    raise InternalError("lookup() after scope class created.")
1804                # The actual c fragment for the different scopes differs
1805                # on the outside and inside, so we make a new entry
1806                entry.in_closure = True
1807                inner_entry = InnerEntry(entry, self)
1808                inner_entry.is_variable = True
1809                self.entries[name] = inner_entry
1810                return inner_entry
1811        return entry
1812
1813    def mangle_closure_cnames(self, outer_scope_cname):
1814        for scope in self.iter_local_scopes():
1815            for entry in scope.entries.values():
1816                if entry.from_closure:
1817                    cname = entry.outer_entry.cname
1818                    if self.is_passthrough:
1819                        entry.cname = cname
1820                    else:
1821                        if cname.startswith(Naming.cur_scope_cname):
1822                            cname = cname[len(Naming.cur_scope_cname)+2:]
1823                        entry.cname = "%s->%s" % (outer_scope_cname, cname)
1824                elif entry.in_closure:
1825                    entry.original_cname = entry.cname
1826                    entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
1827
1828
1829class GeneratorExpressionScope(Scope):
1830    """Scope for generator expressions and comprehensions.  As opposed
1831    to generators, these can be easily inlined in some cases, so all
1832    we really need is a scope that holds the loop variable(s).
1833    """
1834    is_genexpr_scope = True
1835
1836    def __init__(self, outer_scope):
1837        parent_scope = outer_scope
1838        # TODO: also ignore class scopes?
1839        while parent_scope.is_genexpr_scope:
1840            parent_scope = parent_scope.parent_scope
1841        name = parent_scope.global_scope().next_id(Naming.genexpr_id_ref)
1842        Scope.__init__(self, name, outer_scope, parent_scope)
1843        self.directives = outer_scope.directives
1844        self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
1845
1846        # Class/ExtType scopes are filled at class creation time, i.e. from the
1847        # module init function or surrounding function.
1848        while outer_scope.is_genexpr_scope or outer_scope.is_c_class_scope or outer_scope.is_py_class_scope:
1849            outer_scope = outer_scope.outer_scope
1850        self.var_entries = outer_scope.var_entries  # keep declarations outside
1851        outer_scope.subscopes.add(self)
1852
1853    def mangle(self, prefix, name):
1854        return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
1855
1856    def declare_var(self, name, type, pos,
1857                    cname = None, visibility = 'private',
1858                    api = 0, in_pxd = 0, is_cdef = True):
1859        if type is unspecified_type:
1860            # if the outer scope defines a type for this variable, inherit it
1861            outer_entry = self.outer_scope.lookup(name)
1862            if outer_entry and outer_entry.is_variable:
1863                type = outer_entry.type # may still be 'unspecified_type' !
1864        # the parent scope needs to generate code for the variable, but
1865        # this scope must hold its name exclusively
1866        cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id()))
1867        entry = self.declare(name, cname, type, pos, visibility)
1868        entry.is_variable = True
1869        if self.parent_scope.is_module_scope:
1870            entry.is_cglobal = True
1871        else:
1872            entry.is_local = True
1873        entry.in_subscope = True
1874        self.var_entries.append(entry)
1875        self.entries[name] = entry
1876        return entry
1877
1878    def declare_pyfunction(self, name, pos, allow_redefine=False):
1879        return self.outer_scope.declare_pyfunction(
1880            name, pos, allow_redefine)
1881
1882    def declare_lambda_function(self, func_cname, pos):
1883        return self.outer_scope.declare_lambda_function(func_cname, pos)
1884
1885    def add_lambda_def(self, def_node):
1886        return self.outer_scope.add_lambda_def(def_node)
1887
1888
1889class ClosureScope(LocalScope):
1890
1891    is_closure_scope = True
1892
1893    def __init__(self, name, scope_name, outer_scope, parent_scope=None):
1894        LocalScope.__init__(self, name, outer_scope, parent_scope)
1895        self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name)
1896
1897#    def mangle_closure_cnames(self, scope_var):
1898#        for entry in self.entries.values() + self.temp_entries:
1899#            entry.in_closure = 1
1900#        LocalScope.mangle_closure_cnames(self, scope_var)
1901
1902#    def mangle(self, prefix, name):
1903#        return "%s->%s" % (self.cur_scope_cname, name)
1904#        return "%s->%s" % (self.closure_cname, name)
1905
1906    def declare_pyfunction(self, name, pos, allow_redefine=False):
1907        return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private')
1908
1909
1910class StructOrUnionScope(Scope):
1911    #  Namespace of a C struct or union.
1912
1913    def __init__(self, name="?"):
1914        Scope.__init__(self, name, None, None)
1915
1916    def declare_var(self, name, type, pos,
1917                    cname = None, visibility = 'private',
1918                    api = 0, in_pxd = 0, is_cdef = 0,
1919                    allow_pyobject=False, allow_memoryview=False):
1920        # Add an entry for an attribute.
1921        if not cname:
1922            cname = name
1923            if visibility == 'private':
1924                cname = c_safe_identifier(cname)
1925        if type.is_cfunction:
1926            type = PyrexTypes.CPtrType(type)
1927        entry = self.declare(name, cname, type, pos, visibility)
1928        entry.is_variable = 1
1929        self.var_entries.append(entry)
1930        if type.is_pyobject and not allow_pyobject:
1931            error(pos, "C struct/union member cannot be a Python object")
1932        elif type.is_memoryviewslice and not allow_memoryview:
1933            # Memory views wrap their buffer owner as a Python object.
1934            error(pos, "C struct/union member cannot be a memory view")
1935        if visibility != 'private':
1936            error(pos, "C struct/union member cannot be declared %s" % visibility)
1937        return entry
1938
1939    def declare_cfunction(self, name, type, pos,
1940                          cname=None, visibility='private', api=0, in_pxd=0,
1941                          defining=0, modifiers=(), overridable=False):  # currently no utility code ...
1942        if overridable:
1943            error(pos, "C struct/union member cannot be declared 'cpdef'")
1944        return self.declare_var(name, type, pos,
1945                                cname=cname, visibility=visibility)
1946
1947
1948class ClassScope(Scope):
1949    #  Abstract base class for namespace of
1950    #  Python class or extension type.
1951    #
1952    #  class_name     string   Python name of the class
1953    #  scope_prefix   string   Additional prefix for names
1954    #                          declared in the class
1955    #  doc    string or None   Doc string
1956
1957    def __init__(self, name, outer_scope):
1958        Scope.__init__(self, name, outer_scope, outer_scope)
1959        self.class_name = name
1960        self.doc = None
1961
1962    def lookup(self, name):
1963        entry = Scope.lookup(self, name)
1964        if entry:
1965            return entry
1966        if name == "classmethod":
1967            # We don't want to use the builtin classmethod here 'cause it won't do the
1968            # right thing in this scope (as the class members aren't still functions).
1969            # Don't want to add a cfunction to this scope 'cause that would mess with
1970            # the type definition, so we just return the right entry.
1971            entry = Entry(
1972                "classmethod",
1973                "__Pyx_Method_ClassMethod",
1974                PyrexTypes.CFuncType(
1975                    py_object_type,
1976                    [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1977            entry.utility_code_definition = Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c")
1978            self.use_entry_utility_code(entry)
1979            entry.is_cfunction = 1
1980        return entry
1981
1982
1983class PyClassScope(ClassScope):
1984    #  Namespace of a Python class.
1985    #
1986    #  class_obj_cname     string   C variable holding class object
1987
1988    is_py_class_scope = 1
1989
1990    def mangle_class_private_name(self, name):
1991        return self.mangle_special_name(name)
1992
1993    def mangle_special_name(self, name):
1994        if name and name.startswith('__') and not name.endswith('__'):
1995            name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name))
1996        return name
1997
1998    def lookup_here(self, name):
1999        name = self.mangle_special_name(name)
2000        return ClassScope.lookup_here(self, name)
2001
2002    def declare_var(self, name, type, pos,
2003                    cname = None, visibility = 'private',
2004                    api = 0, in_pxd = 0, is_cdef = 0):
2005        name = self.mangle_special_name(name)
2006        if type is unspecified_type:
2007            type = py_object_type
2008        # Add an entry for a class attribute.
2009        entry = Scope.declare_var(self, name, type, pos,
2010                                  cname=cname, visibility=visibility,
2011                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
2012        entry.is_pyglobal = 1
2013        entry.is_pyclass_attr = 1
2014        return entry
2015
2016    def declare_nonlocal(self, name, pos):
2017        # Pull entry from outer scope into local scope
2018        orig_entry = self.lookup_here(name)
2019        if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
2020            error(pos, "'%s' redeclared as nonlocal" % name)
2021            orig_entry.already_declared_here()
2022        else:
2023            entry = self.lookup(name)
2024            if entry is None:
2025                error(pos, "no binding for nonlocal '%s' found" % name)
2026            else:
2027                # FIXME: this works, but it's unclear if it's the
2028                # right thing to do
2029                self.entries[name] = entry
2030
2031    def declare_global(self, name, pos):
2032        # Pull entry from global scope into local scope.
2033        if self.lookup_here(name):
2034            warning(pos, "'%s' redeclared  ", 0)
2035        else:
2036            entry = self.global_scope().lookup_target(name)
2037            self.entries[name] = entry
2038
2039    def add_default_value(self, type):
2040        return self.outer_scope.add_default_value(type)
2041
2042
2043class CClassScope(ClassScope):
2044    #  Namespace of an extension type.
2045    #
2046    #  parent_type           CClassType
2047    #  #typeobj_cname        string or None
2048    #  #objstruct_cname      string
2049    #  method_table_cname    string
2050    #  getset_table_cname    string
2051    #  has_pyobject_attrs    boolean  Any PyObject attributes?
2052    #  has_memoryview_attrs  boolean  Any memory view attributes?
2053    #  has_cpp_class_attrs   boolean  Any (non-pointer) C++ attributes?
2054    #  has_cyclic_pyobject_attrs    boolean  Any PyObject attributes that may need GC?
2055    #  property_entries      [Entry]
2056    #  defined               boolean  Defined in .pxd file
2057    #  implemented           boolean  Defined in .pyx file
2058    #  inherited_var_entries [Entry]  Adapted var entries from base class
2059
2060    is_c_class_scope = 1
2061    is_closure_class_scope = False
2062
2063    has_pyobject_attrs = False
2064    has_memoryview_attrs = False
2065    has_cpp_class_attrs = False
2066    has_cyclic_pyobject_attrs = False
2067    defined = False
2068    implemented = False
2069
2070    def __init__(self, name, outer_scope, visibility):
2071        ClassScope.__init__(self, name, outer_scope)
2072        if visibility != 'extern':
2073            self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
2074            self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
2075        self.property_entries = []
2076        self.inherited_var_entries = []
2077
2078    def needs_gc(self):
2079        # If the type or any of its base types have Python-valued
2080        # C attributes, then it needs to participate in GC.
2081        if self.has_cyclic_pyobject_attrs and not self.directives.get('no_gc', False):
2082            return True
2083        base_type = self.parent_type.base_type
2084        if base_type and base_type.scope is not None:
2085            return base_type.scope.needs_gc()
2086        elif self.parent_type.is_builtin_type:
2087            return not self.parent_type.is_gc_simple
2088        return False
2089
2090    def needs_tp_clear(self):
2091        """
2092        Do we need to generate an implementation for the tp_clear slot? Can
2093        be disabled to keep references for the __dealloc__ cleanup function.
2094        """
2095        return self.needs_gc() and not self.directives.get('no_gc_clear', False)
2096
2097    def get_refcounted_entries(self, include_weakref=False,
2098                               include_gc_simple=True):
2099        py_attrs = []
2100        py_buffers = []
2101        memoryview_slices = []
2102
2103        for entry in self.var_entries:
2104            if entry.type.is_pyobject:
2105                if include_weakref or (self.is_closure_class_scope or entry.name != "__weakref__"):
2106                    if include_gc_simple or not entry.type.is_gc_simple:
2107                        py_attrs.append(entry)
2108            elif entry.type == PyrexTypes.c_py_buffer_type:
2109                py_buffers.append(entry)
2110            elif entry.type.is_memoryviewslice:
2111                memoryview_slices.append(entry)
2112
2113        have_entries = py_attrs or py_buffers or memoryview_slices
2114        return have_entries, (py_attrs, py_buffers, memoryview_slices)
2115
2116    def declare_var(self, name, type, pos,
2117                    cname = None, visibility = 'private',
2118                    api = 0, in_pxd = 0, is_cdef = 0):
2119        if is_cdef:
2120            # Add an entry for an attribute.
2121            if self.defined:
2122                error(pos,
2123                    "C attributes cannot be added in implementation part of"
2124                    " extension type defined in a pxd")
2125            if not self.is_closure_class_scope and get_special_method_signature(name):
2126                error(pos,
2127                    "The name '%s' is reserved for a special method."
2128                        % name)
2129            if not cname:
2130                cname = name
2131                if visibility == 'private':
2132                    cname = c_safe_identifier(cname)
2133            if type.is_cpp_class and visibility != 'extern':
2134                type.check_nullary_constructor(pos)
2135                self.use_utility_code(Code.UtilityCode("#include <new>"))
2136            entry = self.declare(name, cname, type, pos, visibility)
2137            entry.is_variable = 1
2138            self.var_entries.append(entry)
2139            if type.is_memoryviewslice:
2140                self.has_memoryview_attrs = True
2141            elif type.is_cpp_class:
2142                self.has_cpp_class_attrs = True
2143            elif type.is_pyobject and (self.is_closure_class_scope or name != '__weakref__'):
2144                self.has_pyobject_attrs = True
2145                if (not type.is_builtin_type
2146                        or not type.scope or type.scope.needs_gc()):
2147                    self.has_cyclic_pyobject_attrs = True
2148            if visibility not in ('private', 'public', 'readonly'):
2149                error(pos,
2150                    "Attribute of extension type cannot be declared %s" % visibility)
2151            if visibility in ('public', 'readonly'):
2152                # If the field is an external typedef, we cannot be sure about the type,
2153                # so do conversion ourself rather than rely on the CPython mechanism (through
2154                # a property; made in AnalyseDeclarationsTransform).
2155                entry.needs_property = True
2156                if not self.is_closure_class_scope and name == "__weakref__":
2157                    error(pos, "Special attribute __weakref__ cannot be exposed to Python")
2158                if not (type.is_pyobject or type.can_coerce_to_pyobject(self)):
2159                    # we're not testing for coercion *from* Python here - that would fail later
2160                    error(pos, "C attribute of type '%s' cannot be accessed from Python" % type)
2161            else:
2162                entry.needs_property = False
2163            return entry
2164        else:
2165            if type is unspecified_type:
2166                type = py_object_type
2167            # Add an entry for a class attribute.
2168            entry = Scope.declare_var(self, name, type, pos,
2169                                      cname=cname, visibility=visibility,
2170                                      api=api, in_pxd=in_pxd, is_cdef=is_cdef)
2171            entry.is_member = 1
2172            entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
2173                                  # I keep it in for now. is_member should be enough
2174                                  # later on
2175            self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
2176            return entry
2177
2178    def declare_pyfunction(self, name, pos, allow_redefine=False):
2179        # Add an entry for a method.
2180        if name in richcmp_special_methods:
2181            if self.lookup_here('__richcmp__'):
2182                error(pos, "Cannot define both % and __richcmp__" % name)
2183        elif name == '__richcmp__':
2184            for n in richcmp_special_methods:
2185                if self.lookup_here(n):
2186                    error(pos, "Cannot define both % and __richcmp__" % n)
2187        if name == "__new__":
2188            error(pos, "__new__ method of extension type will change semantics "
2189                "in a future version of Pyrex and Cython. Use __cinit__ instead.")
2190        entry = self.declare_var(name, py_object_type, pos,
2191                                 visibility='extern')
2192        special_sig = get_special_method_signature(name)
2193        if special_sig:
2194            # Special methods get put in the method table with a particular
2195            # signature declared in advance.
2196            entry.signature = special_sig
2197            entry.is_special = 1
2198        else:
2199            entry.signature = pymethod_signature
2200            entry.is_special = 0
2201
2202        self.pyfunc_entries.append(entry)
2203        return entry
2204
2205    def lookup_here(self, name):
2206        if not self.is_closure_class_scope and name == "__new__":
2207            name = EncodedString("__cinit__")
2208        entry = ClassScope.lookup_here(self, name)
2209        if entry and entry.is_builtin_cmethod:
2210            if not self.parent_type.is_builtin_type:
2211                # For subtypes of builtin types, we can only return
2212                # optimised C methods if the type if final.
2213                # Otherwise, subtypes may choose to override the
2214                # method, but the optimisation would prevent the
2215                # subtype method from being called.
2216                if not self.parent_type.is_final_type:
2217                    return None
2218        return entry
2219
2220    def declare_cfunction(self, name, type, pos,
2221                          cname=None, visibility='private', api=0, in_pxd=0,
2222                          defining=0, modifiers=(), utility_code=None, overridable=False):
2223        if get_special_method_signature(name) and not self.parent_type.is_builtin_type:
2224            error(pos, "Special methods must be declared with 'def', not 'cdef'")
2225        args = type.args
2226        if not type.is_static_method:
2227            if not args:
2228                error(pos, "C method has no self argument")
2229            elif not self.parent_type.assignable_from(args[0].type):
2230                error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
2231                      (args[0].type, name, self.parent_type))
2232        entry = self.lookup_here(name)
2233        if cname is None:
2234            cname = c_safe_identifier(name)
2235        if entry:
2236            if not entry.is_cfunction:
2237                warning(pos, "'%s' redeclared  " % name, 0)
2238            else:
2239                if defining and entry.func_cname:
2240                    error(pos, "'%s' already defined" % name)
2241                #print "CClassScope.declare_cfunction: checking signature" ###
2242                if entry.is_final_cmethod and entry.is_inherited:
2243                    error(pos, "Overriding final methods is not allowed")
2244                elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
2245                    # Fix with_gil vs nogil.
2246                    entry.type = entry.type.with_with_gil(type.with_gil)
2247                elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
2248                    if (self.defined and not in_pxd
2249                        and not type.same_c_signature_as_resolved_type(entry.type, as_cmethod = 1, as_pxd_definition = 1)):
2250                        # TODO(robertwb): Make this an error.
2251                        warning(pos,
2252                            "Compatible but non-identical C method '%s' not redeclared "
2253                            "in definition part of extension type '%s'.  "
2254                            "This may cause incorrect vtables to be generated." % (
2255                                    name, self.class_name), 2)
2256                        warning(entry.pos, "Previous declaration is here", 2)
2257                    entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers)
2258                else:
2259                    error(pos, "Signature not compatible with previous declaration")
2260                    error(entry.pos, "Previous declaration is here")
2261        else:
2262            if self.defined:
2263                error(pos,
2264                    "C method '%s' not previously declared in definition part of"
2265                    " extension type '%s'" % (name, self.class_name))
2266            entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
2267        if defining:
2268            entry.func_cname = self.mangle(Naming.func_prefix, name)
2269        entry.utility_code = utility_code
2270        type.entry = entry
2271
2272        if u'inline' in modifiers:
2273            entry.is_inline_cmethod = True
2274
2275        if (self.parent_type.is_final_type or entry.is_inline_cmethod or
2276            self.directives.get('final')):
2277            entry.is_final_cmethod = True
2278            entry.final_func_cname = entry.func_cname
2279
2280        return entry
2281
2282    def add_cfunction(self, name, type, pos, cname, visibility, modifiers, inherited=False):
2283        # Add a cfunction entry without giving it a func_cname.
2284        prev_entry = self.lookup_here(name)
2285        entry = ClassScope.add_cfunction(self, name, type, pos, cname,
2286                                         visibility, modifiers, inherited=inherited)
2287        entry.is_cmethod = 1
2288        entry.prev_entry = prev_entry
2289        return entry
2290
2291    def declare_builtin_cfunction(self, name, type, cname, utility_code = None):
2292        # overridden methods of builtin types still have their Python
2293        # equivalent that must be accessible to support bound methods
2294        name = EncodedString(name)
2295        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
2296                                       utility_code=utility_code)
2297        var_entry = Entry(name, name, py_object_type)
2298        var_entry.qualified_name = name
2299        var_entry.is_variable = 1
2300        var_entry.is_builtin = 1
2301        var_entry.utility_code = utility_code
2302        var_entry.scope = entry.scope
2303        entry.as_variable = var_entry
2304        return entry
2305
2306    def declare_property(self, name, doc, pos):
2307        entry = self.lookup_here(name)
2308        if entry is None:
2309            entry = self.declare(name, name, py_object_type, pos, 'private')
2310        entry.is_property = 1
2311        entry.doc = doc
2312        entry.scope = PropertyScope(name,
2313            outer_scope = self.global_scope(), parent_scope = self)
2314        entry.scope.parent_type = self.parent_type
2315        self.property_entries.append(entry)
2316        return entry
2317
2318    def declare_inherited_c_attributes(self, base_scope):
2319        # Declare entries for all the C attributes of an
2320        # inherited type, with cnames modified appropriately
2321        # to work with this type.
2322        def adapt(cname):
2323            return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
2324
2325        entries = base_scope.inherited_var_entries + base_scope.var_entries
2326        for base_entry in entries:
2327            entry = self.declare(
2328                base_entry.name, adapt(base_entry.cname),
2329                base_entry.type, None, 'private')
2330            entry.is_variable = 1
2331            self.inherited_var_entries.append(entry)
2332
2333        # If the class defined in a pxd, specific entries have not been added.
2334        # Ensure now that the parent (base) scope has specific entries
2335        # Iterate over a copy as get_all_specialized_function_types() will mutate
2336        for base_entry in base_scope.cfunc_entries[:]:
2337            if base_entry.type.is_fused:
2338                base_entry.type.get_all_specialized_function_types()
2339
2340        for base_entry in base_scope.cfunc_entries:
2341            cname = base_entry.cname
2342            var_entry = base_entry.as_variable
2343            is_builtin = var_entry and var_entry.is_builtin
2344            if not is_builtin:
2345                cname = adapt(cname)
2346            entry = self.add_cfunction(base_entry.name, base_entry.type,
2347                                       base_entry.pos, cname,
2348                                       base_entry.visibility, base_entry.func_modifiers, inherited=True)
2349            entry.is_inherited = 1
2350            if base_entry.is_final_cmethod:
2351                entry.is_final_cmethod = True
2352                entry.is_inline_cmethod = base_entry.is_inline_cmethod
2353                if (self.parent_scope == base_scope.parent_scope or
2354                        entry.is_inline_cmethod):
2355                    entry.final_func_cname = base_entry.final_func_cname
2356            if is_builtin:
2357                entry.is_builtin_cmethod = True
2358                entry.as_variable = var_entry
2359            if base_entry.utility_code:
2360                entry.utility_code = base_entry.utility_code
2361
2362
2363class CppClassScope(Scope):
2364    #  Namespace of a C++ class.
2365
2366    is_cpp_class_scope = 1
2367
2368    default_constructor = None
2369    type = None
2370
2371    def __init__(self, name, outer_scope, templates=None):
2372        Scope.__init__(self, name, outer_scope, None)
2373        self.directives = outer_scope.directives
2374        self.inherited_var_entries = []
2375        if templates is not None:
2376            for T in templates:
2377                template_entry = self.declare(
2378                    T, T, PyrexTypes.TemplatePlaceholderType(T), None, 'extern')
2379                template_entry.is_type = 1
2380
2381    def declare_var(self, name, type, pos,
2382                    cname = None, visibility = 'extern',
2383                    api = 0, in_pxd = 0, is_cdef = 0, defining = 0):
2384        # Add an entry for an attribute.
2385        if not cname:
2386            cname = name
2387        entry = self.lookup_here(name)
2388        if defining and entry is not None:
2389            if entry.type.same_as(type):
2390                # Fix with_gil vs nogil.
2391                entry.type = entry.type.with_with_gil(type.with_gil)
2392            elif type.is_cfunction and type.compatible_signature_with(entry.type):
2393                entry.type = type
2394            else:
2395                error(pos, "Function signature does not match previous declaration")
2396        else:
2397            entry = self.declare(name, cname, type, pos, visibility)
2398        entry.is_variable = 1
2399        if type.is_cfunction and self.type:
2400            if not self.type.get_fused_types():
2401                entry.func_cname = "%s::%s" % (self.type.empty_declaration_code(), cname)
2402        if name != "this" and (defining or name != "<init>"):
2403            self.var_entries.append(entry)
2404        return entry
2405
2406    def declare_cfunction(self, name, type, pos,
2407                          cname=None, visibility='extern', api=0, in_pxd=0,
2408                          defining=0, modifiers=(), utility_code=None, overridable=False):
2409        class_name = self.name.split('::')[-1]
2410        if name in (class_name, '__init__') and cname is None:
2411            cname = "%s__init__%s" % (Naming.func_prefix, class_name)
2412            name = '<init>'
2413            type.return_type = PyrexTypes.CVoidType()
2414            # This is called by the actual constructor, but need to support
2415            # arguments that cannot by called by value.
2416            type.original_args = type.args
2417            def maybe_ref(arg):
2418                if arg.type.is_cpp_class and not arg.type.is_reference:
2419                    return PyrexTypes.CFuncTypeArg(
2420                        arg.name, PyrexTypes.c_ref_type(arg.type), arg.pos)
2421                else:
2422                    return arg
2423            type.args = [maybe_ref(arg) for arg in type.args]
2424        elif name == '__dealloc__' and cname is None:
2425            cname = "%s__dealloc__%s" % (Naming.func_prefix, class_name)
2426            name = '<del>'
2427            type.return_type = PyrexTypes.CVoidType()
2428        if name in ('<init>', '<del>') and type.nogil:
2429            for base in self.type.base_classes:
2430                base_entry = base.scope.lookup(name)
2431                if base_entry and not base_entry.type.nogil:
2432                    error(pos, "Constructor cannot be called without GIL unless all base constructors can also be called without GIL")
2433                    error(base_entry.pos, "Base constructor defined here.")
2434        prev_entry = self.lookup_here(name)
2435        entry = self.declare_var(name, type, pos,
2436                                 defining=defining,
2437                                 cname=cname, visibility=visibility)
2438        if prev_entry and not defining:
2439            entry.overloaded_alternatives = prev_entry.all_alternatives()
2440        entry.utility_code = utility_code
2441        type.entry = entry
2442        return entry
2443
2444    def declare_inherited_cpp_attributes(self, base_class):
2445        base_scope = base_class.scope
2446        template_type = base_class
2447        while getattr(template_type, 'template_type', None):
2448            template_type = template_type.template_type
2449        if getattr(template_type, 'templates', None):
2450            base_templates = [T.name for T in template_type.templates]
2451        else:
2452            base_templates = ()
2453        # Declare entries for all the C++ attributes of an
2454        # inherited type, with cnames modified appropriately
2455        # to work with this type.
2456        for base_entry in \
2457            base_scope.inherited_var_entries + base_scope.var_entries:
2458                #constructor/destructor is not inherited
2459                if base_entry.name in ("<init>", "<del>"):
2460                    continue
2461                #print base_entry.name, self.entries
2462                if base_entry.name in self.entries:
2463                    base_entry.name    # FIXME: is there anything to do in this case?
2464                entry = self.declare(base_entry.name, base_entry.cname,
2465                    base_entry.type, None, 'extern')
2466                entry.is_variable = 1
2467                entry.is_inherited = 1
2468                self.inherited_var_entries.append(entry)
2469        for base_entry in base_scope.cfunc_entries:
2470            entry = self.declare_cfunction(base_entry.name, base_entry.type,
2471                                           base_entry.pos, base_entry.cname,
2472                                           base_entry.visibility, api=0,
2473                                           modifiers=base_entry.func_modifiers,
2474                                           utility_code=base_entry.utility_code)
2475            entry.is_inherited = 1
2476        for base_entry in base_scope.type_entries:
2477            if base_entry.name not in base_templates:
2478                entry = self.declare_type(base_entry.name, base_entry.type,
2479                                          base_entry.pos, base_entry.cname,
2480                                          base_entry.visibility)
2481                entry.is_inherited = 1
2482
2483    def specialize(self, values, type_entry):
2484        scope = CppClassScope(self.name, self.outer_scope)
2485        scope.type = type_entry
2486        for entry in self.entries.values():
2487            if entry.is_type:
2488                scope.declare_type(entry.name,
2489                                   entry.type.specialize(values),
2490                                   entry.pos,
2491                                   entry.cname,
2492                                   template=1)
2493            elif entry.type.is_cfunction:
2494                for e in entry.all_alternatives():
2495                    scope.declare_cfunction(e.name,
2496                                            e.type.specialize(values),
2497                                            e.pos,
2498                                            e.cname,
2499                                            utility_code=e.utility_code)
2500            else:
2501                scope.declare_var(entry.name,
2502                                  entry.type.specialize(values),
2503                                  entry.pos,
2504                                  entry.cname,
2505                                  entry.visibility)
2506
2507        return scope
2508
2509
2510class PropertyScope(Scope):
2511    #  Scope holding the __get__, __set__ and __del__ methods for
2512    #  a property of an extension type.
2513    #
2514    #  parent_type   PyExtensionType   The type to which the property belongs
2515
2516    is_property_scope = 1
2517
2518    def declare_pyfunction(self, name, pos, allow_redefine=False):
2519        # Add an entry for a method.
2520        signature = get_property_accessor_signature(name)
2521        if signature:
2522            entry = self.declare(name, name, py_object_type, pos, 'private')
2523            entry.is_special = 1
2524            entry.signature = signature
2525            return entry
2526        else:
2527            error(pos, "Only __get__, __set__ and __del__ methods allowed "
2528                "in a property declaration")
2529            return None
2530
2531
2532class CConstScope(Scope):
2533
2534    def __init__(self, const_base_type_scope):
2535        Scope.__init__(
2536            self,
2537            'const_' + const_base_type_scope.name,
2538            const_base_type_scope.outer_scope,
2539            const_base_type_scope.parent_scope)
2540        self.const_base_type_scope = const_base_type_scope
2541
2542    def lookup_here(self, name):
2543        entry = self.const_base_type_scope.lookup_here(name)
2544        if entry is not None:
2545            entry = copy.copy(entry)
2546            entry.type = PyrexTypes.c_const_type(entry.type)
2547            return entry
2548
2549class TemplateScope(Scope):
2550    def __init__(self, name, outer_scope):
2551        Scope.__init__(self, name, outer_scope, None)
2552        self.directives = outer_scope.directives
2553