remove trailing whitespace
[cython.git] / Cython / Compiler / Symtab.py
1 #
2 #   Symbol Table
3 #
4
5 import re
6 from Cython import Utils
7 from Errors import warning, error, InternalError
8 from StringEncoding import EncodedString
9 import Options, Naming
10 import PyrexTypes
11 from PyrexTypes import py_object_type, unspecified_type
12 import TypeSlots
13 from TypeSlots import \
14     pyfunction_signature, pymethod_signature, \
15     get_special_method_signature, get_property_accessor_signature
16 import ControlFlow
17 import Code
18 import __builtin__ as builtins
19 try:
20     set
21 except NameError:
22     from sets import Set as set
23 import copy
24
25 possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
26 nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
27
28 iso_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 def c_safe_identifier(cname):
37     # There are some C limitations on struct entry names.
38     if ((cname[:2] == '__'
39          and not (cname.startswith(Naming.pyrex_prefix)
40                   or cname == '__weakref__'))
41         or cname in iso_c99_keywords):
42         cname = Naming.pyrex_prefix + cname
43     return cname
44
45 class BufferAux(object):
46     writable_needed = False
47
48     def __init__(self, buffer_info_var, stridevars, shapevars,
49                  suboffsetvars):
50         self.buffer_info_var = buffer_info_var
51         self.stridevars = stridevars
52         self.shapevars = shapevars
53         self.suboffsetvars = suboffsetvars
54
55     def __repr__(self):
56         return "<BufferAux %r>" % self.__dict__
57
58 class Entry(object):
59     # A symbol table entry in a Scope or ModuleNamespace.
60     #
61     # name             string     Python name of entity
62     # cname            string     C name of entity
63     # type             PyrexType  Type of entity
64     # doc              string     Doc string
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_unbound_cmethod boolean  Is an unbound C method of an extension type
78     # is_anonymous     boolean    Is a anonymous pyfunction entry
79     # is_type          boolean    Is a type definition
80     # is_cclass        boolean    Is an extension class
81     # is_cpp_class     boolean    Is a C++ class
82     # is_const         boolean    Is a constant
83     # is_property      boolean    Is a property of an extension type:
84     # doc_cname        string or None  C const holding the docstring
85     # getter_cname     string          C func for getting property
86     # setter_cname     string          C func for setting or deleting property
87     # is_self_arg      boolean    Is the "self" arg of an exttype method
88     # is_arg           boolean    Is the arg of a method
89     # is_local         boolean    Is a local variable
90     # in_closure       boolean    Is referenced in an inner scope
91     # is_readonly      boolean    Can't be assigned to
92     # func_cname       string     C func implementing Python func
93     # func_modifiers   [string]   C function modifiers ('inline')
94     # pos              position   Source position where declared
95     # namespace_cname  string     If is_pyglobal, the C variable
96     #                               holding its home namespace
97     # pymethdef_cname  string     PyMethodDef structure
98     # signature        Signature  Arg & return types for Python func
99     # init_to_none     boolean    True if initial value should be None
100     # as_variable      Entry      Alternative interpretation of extension
101     #                               type name or builtin C function as a variable
102     # xdecref_cleanup  boolean    Use Py_XDECREF for error cleanup
103     # in_cinclude      boolean    Suppress C declaration code
104     # enum_values      [Entry]    For enum types, list of values
105     # qualified_name   string     "modname.funcname" or "modname.classname"
106     #                               or "modname.classname.funcname"
107     # is_declared_generic  boolean  Is declared as PyObject * even though its
108     #                                 type is an extension type
109     # as_module        None       Module scope, if a cimported module
110     # is_inherited     boolean    Is an inherited attribute of an extension type
111     # pystring_cname   string     C name of Python version of string literal
112     # is_interned      boolean    For string const entries, value is interned
113     # is_identifier    boolean    For string const entries, value is an identifier
114     # used             boolean
115     # is_special       boolean    Is a special method or property accessor
116     #                               of an extension type
117     # defined_in_pxd   boolean    Is defined in a .pxd file (not just declared)
118     # api              boolean    Generate C API for C class or function
119     # utility_code     string     Utility code needed when this entry is used
120     #
121     # buffer_aux       BufferAux or None  Extra information needed for buffer variables
122     # inline_func_in_pxd boolean  Hacky special case for inline function in pxd file.
123     #                             Ideally this should not be necesarry.
124     # assignments      [ExprNode] List of expressions that get assigned to this entry.
125     # might_overflow   boolean    In an arithmetic expression that could cause
126     #                             overflow (used for type inference).
127
128     inline_func_in_pxd = False
129     borrowed = 0
130     init = ""
131     visibility = 'private'
132     is_builtin = 0
133     is_cglobal = 0
134     is_pyglobal = 0
135     is_member = 0
136     is_pyclass_attr = 0
137     is_variable = 0
138     is_cfunction = 0
139     is_cmethod = 0
140     is_unbound_cmethod = 0
141     is_anonymous = 0
142     is_type = 0
143     is_cclass = 0
144     is_cpp_class = 0
145     is_const = 0
146     is_property = 0
147     doc_cname = None
148     getter_cname = None
149     setter_cname = None
150     is_self_arg = 0
151     is_arg = 0
152     is_local = 0
153     in_closure = 0
154     from_closure = 0
155     is_declared_generic = 0
156     is_readonly = 0
157     func_cname = None
158     func_modifiers = []
159     doc = None
160     init_to_none = 0
161     as_variable = None
162     xdecref_cleanup = 0
163     in_cinclude = 0
164     as_module = None
165     is_inherited = 0
166     pystring_cname = None
167     is_identifier = 0
168     is_interned = 0
169     used = 0
170     is_special = 0
171     defined_in_pxd = 0
172     is_implemented = 0
173     api = 0
174     utility_code = None
175     is_overridable = 0
176     buffer_aux = None
177     prev_entry = None
178     might_overflow = 0
179
180     def __init__(self, name, cname, type, pos = None, init = None):
181         self.name = name
182         self.cname = cname
183         self.type = type
184         self.pos = pos
185         self.init = init
186         self.overloaded_alternatives = []
187         self.assignments = []
188
189     def __repr__(self):
190         return "Entry(name=%s, type=%s)" % (self.name, self.type)
191
192     def redeclared(self, pos):
193         error(pos, "'%s' does not match previous declaration" % self.name)
194         error(self.pos, "Previous declaration is here")
195
196     def all_alternatives(self):
197         return [self] + self.overloaded_alternatives
198
199 class Scope(object):
200     # name              string             Unqualified name
201     # outer_scope       Scope or None      Enclosing scope
202     # entries           {string : Entry}   Python name to entry, non-types
203     # const_entries     [Entry]            Constant entries
204     # type_entries      [Entry]            Struct/union/enum/typedef/exttype entries
205     # sue_entries       [Entry]            Struct/union/enum entries
206     # arg_entries       [Entry]            Function argument entries
207     # var_entries       [Entry]            User-defined variable entries
208     # pyfunc_entries    [Entry]            Python function entries
209     # cfunc_entries     [Entry]            C function entries
210     # c_class_entries   [Entry]            All extension type entries
211     # cname_to_entry    {string : Entry}   Temp cname to entry mapping
212     # int_to_entry      {int : Entry}      Temp cname to entry mapping
213     # return_type       PyrexType or None  Return type of function owning scope
214     # is_builtin_scope  boolean            Is the builtin scope of Python/Cython
215     # is_py_class_scope boolean            Is a Python class scope
216     # is_c_class_scope  boolean            Is an extension type scope
217     # is_closure_scope  boolean            Is a closure scope
218     # is_passthrough    boolean            Outer scope is passed directly
219     # is_cpp_class_scope  boolean          Is a C++ class scope
220     # is_property_scope boolean            Is a extension type property scope
221     # scope_prefix      string             Disambiguator for C names
222     # in_cinclude       boolean            Suppress C declaration code
223     # qualified_name    string             "modname" or "modname.classname"
224     # pystring_entries  [Entry]            String const entries newly used as
225     #                                        Python strings in this scope
226     # control_flow     ControlFlow  Used for keeping track of environment state
227     # nogil             boolean            In a nogil section
228     # directives       dict                Helper variable for the recursive
229     #                                      analysis, contains directive values.
230     # is_internal       boolean            Is only used internally (simpler setup)
231
232     is_builtin_scope = 0
233     is_py_class_scope = 0
234     is_c_class_scope = 0
235     is_closure_scope = 0
236     is_passthrough = 0
237     is_cpp_class_scope = 0
238     is_property_scope = 0
239     is_module_scope = 0
240     is_internal = 0
241     scope_prefix = ""
242     in_cinclude = 0
243     nogil = 0
244
245     def __init__(self, name, outer_scope, parent_scope):
246         # The outer_scope is the next scope in the lookup chain.
247         # The parent_scope is used to derive the qualified name of this scope.
248         self.name = name
249         self.outer_scope = outer_scope
250         self.parent_scope = parent_scope
251         mangled_name = "%d%s_" % (len(name), name)
252         qual_scope = self.qualifying_scope()
253         if qual_scope:
254             self.qualified_name = qual_scope.qualify_name(name)
255             self.scope_prefix = qual_scope.scope_prefix + mangled_name
256         else:
257             self.qualified_name = EncodedString(name)
258             self.scope_prefix = mangled_name
259         self.entries = {}
260         self.const_entries = []
261         self.type_entries = []
262         self.sue_entries = []
263         self.arg_entries = []
264         self.var_entries = []
265         self.pyfunc_entries = []
266         self.cfunc_entries = []
267         self.c_class_entries = []
268         self.defined_c_classes = []
269         self.imported_c_classes = {}
270         self.cname_to_entry = {}
271         self.string_to_entry = {}
272         self.identifier_to_entry = {}
273         self.num_to_entry = {}
274         self.obj_to_entry = {}
275         self.pystring_entries = []
276         self.buffer_entries = []
277         self.lambda_defs = []
278         self.control_flow = ControlFlow.LinearControlFlow()
279         self.return_type = None
280         self.id_counters = {}
281
282     def start_branching(self, pos):
283         self.control_flow = self.control_flow.start_branch(pos)
284
285     def next_branch(self, pos):
286         self.control_flow = self.control_flow.next_branch(pos)
287
288     def finish_branching(self, pos):
289         self.control_flow = self.control_flow.finish_branch(pos)
290
291     def __str__(self):
292         return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
293
294     def qualifying_scope(self):
295         return self.parent_scope
296
297     def mangle(self, prefix, name = None):
298         if name:
299             return "%s%s%s" % (prefix, self.scope_prefix, name)
300         else:
301             return self.parent_scope.mangle(prefix, self.name)
302
303     def mangle_internal(self, name):
304         # Mangle an internal name so as not to clash with any
305         # user-defined name in this scope.
306         prefix = "%s%s_" % (Naming.pyrex_prefix, name)
307         return self.mangle(prefix)
308         #return self.parent_scope.mangle(prefix, self.name)
309
310     def next_id(self, name=None):
311         # Return a cname fragment that is unique for this module
312         counters = self.global_scope().id_counters
313         try:
314             count = counters[name] + 1
315         except KeyError:
316             count = 0
317         counters[name] = count
318         if name:
319             if not count:
320                 # unique names don't need a suffix, reoccurrences will get one
321                 return name
322             return '%s%d' % (name, count)
323         else:
324             return '%d' % count
325
326     def global_scope(self):
327         # Return the module-level scope containing this scope.
328         return self.outer_scope.global_scope()
329
330     def builtin_scope(self):
331         # Return the module-level scope containing this scope.
332         return self.outer_scope.builtin_scope()
333
334     def declare(self, name, cname, type, pos, visibility, shadow = 0):
335         # Create new entry, and add to dictionary if
336         # name is not None. Reports a warning if already
337         # declared.
338         if type.is_buffer and not isinstance(self, LocalScope):
339             error(pos, ERR_BUF_LOCALONLY)
340         if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
341             # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
342             warning(pos, "'%s' is a reserved name in C." % cname, -1)
343         entries = self.entries
344         if name and name in entries and not shadow:
345             if visibility == 'extern':
346                 warning(pos, "'%s' redeclared " % name, 0)
347             elif visibility != 'ignore':
348                 error(pos, "'%s' redeclared " % name)
349         entry = Entry(name, cname, type, pos = pos)
350         entry.in_cinclude = self.in_cinclude
351         if name:
352             entry.qualified_name = self.qualify_name(name)
353 #            if name in entries and self.is_cpp():
354 #                entries[name].overloaded_alternatives.append(entry)
355 #            else:
356 #                entries[name] = entry
357             if not shadow:
358                 entries[name] = entry
359         entry.scope = self
360         entry.visibility = visibility
361         return entry
362
363     def qualify_name(self, name):
364         return EncodedString("%s.%s" % (self.qualified_name, name))
365
366     def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0):
367         # Add an entry for a named constant.
368         if not cname:
369             if self.in_cinclude or (visibility == 'public' or api):
370                 cname = name
371             else:
372                 cname = self.mangle(Naming.enum_prefix, name)
373         entry = self.declare(name, cname, type, pos, visibility)
374         entry.is_const = 1
375         entry.value_node = value
376         return entry
377
378     def declare_type(self, name, type, pos,
379             cname = None, visibility = 'private', api = 0, defining = 1, shadow = 0):
380         # Add an entry for a type definition.
381         if not cname:
382             cname = name
383         entry = self.declare(name, cname, type, pos, visibility, shadow)
384         entry.is_type = 1
385         entry.api = api
386         if defining:
387             self.type_entries.append(entry)
388         # here we would set as_variable to an object representing this type
389         return entry
390
391     def declare_typedef(self, name, base_type, pos, cname = None,
392                         visibility = 'private', api = 0):
393         if not cname:
394             if self.in_cinclude or (visibility == 'public' or api):
395                 cname = name
396             else:
397                 cname = self.mangle(Naming.type_prefix, name)
398         try:
399             type = PyrexTypes.create_typedef_type(name, base_type, cname,
400                                                   (visibility == 'extern'))
401         except ValueError, e:
402             error(pos, e.args[0])
403             type = PyrexTypes.error_type
404         entry = self.declare_type(name, type, pos, cname,
405                                   visibility = visibility, api = api)
406         type.qualified_name = entry.qualified_name
407         return entry
408
409     def declare_struct_or_union(self, name, kind, scope,
410                                 typedef_flag, pos, cname = None,
411                                 visibility = 'private', api = 0,
412                                 packed = False):
413         # Add an entry for a struct or union definition.
414         if not cname:
415             if self.in_cinclude or (visibility == 'public' or api):
416                 cname = name
417             else:
418                 cname = self.mangle(Naming.type_prefix, name)
419         entry = self.lookup_here(name)
420         if not entry:
421             type = PyrexTypes.CStructOrUnionType(
422                 name, kind, scope, typedef_flag, cname, packed)
423             entry = self.declare_type(name, type, pos, cname,
424                 visibility = visibility, api = api,
425                 defining = scope is not None)
426             self.sue_entries.append(entry)
427             type.entry = entry
428         else:
429             if not (entry.is_type and entry.type.is_struct_or_union
430                     and entry.type.kind == kind):
431                 warning(pos, "'%s' redeclared  " % name, 0)
432             elif scope and entry.type.scope:
433                 warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
434             else:
435                 self.check_previous_typedef_flag(entry, typedef_flag, pos)
436                 self.check_previous_visibility(entry, visibility, pos)
437                 if scope:
438                     entry.type.scope = scope
439                     self.type_entries.append(entry)
440         if not scope and not entry.type.scope:
441             self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
442         return entry
443
444     def declare_cpp_class(self, name, scope,
445             pos, cname = None, base_classes = [],
446             visibility = 'extern', templates = None):
447         if visibility != 'extern':
448             error(pos, "C++ classes may only be extern")
449         if cname is None:
450             cname = name
451         entry = self.lookup_here(name)
452         if not entry:
453             type = PyrexTypes.CppClassType(
454                 name, scope, cname, base_classes, templates = templates)
455             entry = self.declare_type(name, type, pos, cname,
456                 visibility = visibility, defining = scope is not None)
457         else:
458             if not (entry.is_type and entry.type.is_cpp_class):
459                 error(pos, "'%s' redeclared " % name)
460                 return None
461             elif scope and entry.type.scope:
462                 warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
463             else:
464                 if scope:
465                     entry.type.scope = scope
466                     self.type_entries.append(entry)
467         if templates is not None:
468             for T in templates:
469                 template_entry = entry.type.scope.declare(T.name, T.name, T, None, 'extern')
470                 template_entry.is_type = 1
471
472         def declare_inherited_attributes(entry, base_classes):
473             for base_class in base_classes:
474                 declare_inherited_attributes(entry, base_class.base_classes)
475                 entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
476         if entry.type.scope:
477             declare_inherited_attributes(entry, base_classes)
478         if self.is_cpp_class_scope:
479             entry.type.namespace = self.outer_scope.lookup(self.name).type
480         return entry
481
482     def check_previous_typedef_flag(self, entry, typedef_flag, pos):
483         if typedef_flag != entry.type.typedef_flag:
484             error(pos, "'%s' previously declared using '%s'" % (
485                 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
486
487     def check_previous_visibility(self, entry, visibility, pos):
488         if entry.visibility != visibility:
489             error(pos, "'%s' previously declared as '%s'" % (
490                 entry.name, entry.visibility))
491
492     def declare_enum(self, name, pos, cname, typedef_flag,
493             visibility = 'private', api = 0):
494         if name:
495             if not cname:
496                 if self.in_cinclude or (visibility == 'public' or api):
497                     cname = name
498                 else:
499                     cname = self.mangle(Naming.type_prefix, name)
500             type = PyrexTypes.CEnumType(name, cname, typedef_flag)
501         else:
502             type = PyrexTypes.c_anon_enum_type
503         entry = self.declare_type(name, type, pos, cname = cname,
504             visibility = visibility, api = api)
505         entry.enum_values = []
506         self.sue_entries.append(entry)
507         return entry
508
509     def declare_var(self, name, type, pos,
510                     cname = None, visibility = 'private', api = 0, is_cdef = 0):
511         # Add an entry for a variable.
512         if not cname:
513             if visibility != 'private':
514                 cname = name
515             else:
516                 cname = self.mangle(Naming.var_prefix, name)
517         if type.is_cpp_class and visibility != 'extern':
518             constructor = type.scope.lookup(u'<init>')
519             if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
520                 error(pos, "C++ class must have a default constructor to be stack allocated")
521         entry = self.declare(name, cname, type, pos, visibility)
522         entry.is_variable = 1
523         entry.api = api
524         self.control_flow.set_state((), (name, 'initialized'), False)
525         return entry
526
527     def declare_builtin(self, name, pos):
528         return self.outer_scope.declare_builtin(name, pos)
529
530     def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
531         if entry and not entry.type.is_cfunction:
532             error(pos, "'%s' already declared" % name)
533             error(entry.pos, "Previous declaration is here")
534         entry = self.declare_var(name, py_object_type, pos, visibility=visibility)
535         entry.signature = pyfunction_signature
536         self.pyfunc_entries.append(entry)
537         return entry
538
539     def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
540         # Add an entry for a Python function.
541         entry = self.lookup_here(name)
542         if not allow_redefine or Options.disable_function_redefinition:
543             return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
544         if entry:
545             if entry.type.is_unspecified:
546                 entry.type = py_object_type
547             elif entry.type is not py_object_type:
548                 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
549         else: # declare entry stub
550             self.declare_var(name, py_object_type, pos, visibility=visibility)
551         entry = self.declare_var(None, py_object_type, pos,
552                                  cname=name, visibility='private')
553         entry.name = EncodedString(name)
554         entry.qualified_name = self.qualify_name(name)
555         entry.signature = pyfunction_signature
556         entry.is_anonymous = True
557         return entry
558
559     def declare_lambda_function(self, lambda_name, pos):
560         # Add an entry for an anonymous Python function.
561         func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
562         pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
563         qualified_name = self.qualify_name(lambda_name)
564
565         entry = self.declare(None, func_cname, py_object_type, pos, 'private')
566         entry.name = lambda_name
567         entry.qualified_name = qualified_name
568         entry.pymethdef_cname = pymethdef_cname
569         entry.func_cname = func_cname
570         entry.signature = pyfunction_signature
571         entry.is_anonymous = True
572         return entry
573
574     def add_lambda_def(self, def_node):
575         self.lambda_defs.append(def_node)
576
577     def register_pyfunction(self, entry):
578         self.pyfunc_entries.append(entry)
579
580     def declare_cfunction(self, name, type, pos,
581                           cname = None, visibility = 'private', defining = 0,
582                           api = 0, in_pxd = 0, modifiers = (), utility_code = None):
583         # Add an entry for a C function.
584         if not cname:
585             if api or visibility != 'private':
586                 cname = name
587             else:
588                 cname = self.mangle(Naming.func_prefix, name)
589         entry = self.lookup_here(name)
590         if entry:
591             if visibility != 'private' and visibility != entry.visibility:
592                 warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
593             if not entry.type.same_as(type):
594                 if visibility == 'extern' and entry.visibility == 'extern':
595                     can_override = False
596                     if self.is_cpp():
597                         can_override = True
598                     elif cname:
599                         # if all alternatives have different cnames,
600                         # it's safe to allow signature overrides
601                         for alt_entry in entry.all_alternatives():
602                             if not alt_entry.cname or cname == alt_entry.cname:
603                                 break # cname not unique!
604                         else:
605                             can_override = True
606                     if can_override:
607                         temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
608                         temp.overloaded_alternatives = entry.all_alternatives()
609                         entry = temp
610                     else:
611                         warning(pos, "Function signature does not match previous declaration", 1)
612                         entry.type = type
613                 else:
614                     error(pos, "Function signature does not match previous declaration")
615         else:
616             entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
617             entry.func_cname = cname
618         if in_pxd and visibility != 'extern':
619             entry.defined_in_pxd = 1
620         if api:
621             entry.api = 1
622         if not defining and not in_pxd and visibility != 'extern':
623             error(pos, "Non-extern C function '%s' declared but not defined" % name)
624         if defining:
625             entry.is_implemented = True
626         if modifiers:
627             entry.func_modifiers = modifiers
628         entry.utility_code = utility_code
629         return entry
630
631     def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
632         # Add a C function entry without giving it a func_cname.
633         entry = self.declare(name, cname, type, pos, visibility)
634         entry.is_cfunction = 1
635         if modifiers:
636             entry.func_modifiers = modifiers
637         self.cfunc_entries.append(entry)
638         return entry
639
640     def find(self, name, pos):
641         # Look up name, report error if not found.
642         entry = self.lookup(name)
643         if entry:
644             return entry
645         else:
646             error(pos, "'%s' is not declared" % name)
647
648     def find_imported_module(self, path, pos):
649         # Look up qualified name, must be a module, report error if not found.
650         # Path is a list of names.
651         scope = self
652         for name in path:
653             entry = scope.find(name, pos)
654             if not entry:
655                 return None
656             if entry.as_module:
657                 scope = entry.as_module
658             else:
659                 error(pos, "'%s' is not a cimported module" % '.'.join(path))
660                 return None
661         return scope
662
663     def lookup(self, name):
664         # Look up name in this scope or an enclosing one.
665         # Return None if not found.
666         return (self.lookup_here(name)
667             or (self.outer_scope and self.outer_scope.lookup(name))
668             or None)
669
670     def lookup_here(self, name):
671         # Look up in this scope only, return None if not found.
672         return self.entries.get(name, None)
673
674     def lookup_target(self, name):
675         # Look up name in this scope only. Declare as Python
676         # variable if not found.
677         entry = self.lookup_here(name)
678         if not entry:
679             entry = self.declare_var(name, py_object_type, None)
680         return entry
681
682     def lookup_type(self, name):
683         entry = self.lookup(name)
684         if entry and entry.is_type:
685             return entry.type
686
687     def lookup_operator(self, operator, operands):
688         if operands[0].type.is_cpp_class:
689             obj_type = operands[0].type
690             method = obj_type.scope.lookup("operator%s" % operator)
691             if method is not None:
692                 res = PyrexTypes.best_match(operands[1:], method.all_alternatives())
693                 if res is not None:
694                     return res
695         function = self.lookup("operator%s" % operator)
696         if function is None:
697             return None
698         return PyrexTypes.best_match(operands, function.all_alternatives())
699
700     def use_utility_code(self, new_code):
701         self.global_scope().use_utility_code(new_code)
702
703     def generate_library_function_declarations(self, code):
704         # Generate extern decls for C library funcs used.
705         pass
706
707     def defines_any(self, names):
708         # Test whether any of the given names are
709         # defined in this scope.
710         for name in names:
711             if name in self.entries:
712                 return 1
713         return 0
714
715     def infer_types(self):
716         from TypeInference import get_type_inferer
717         get_type_inferer().infer_types(self)
718
719     def is_cpp(self):
720         outer = self.outer_scope
721         if outer is None:
722             return False
723         else:
724             return outer.is_cpp()
725
726 class PreImportScope(Scope):
727
728     namespace_cname = Naming.preimport_cname
729
730     def __init__(self):
731         Scope.__init__(self, Options.pre_import, None, None)
732
733     def declare_builtin(self, name, pos):
734         entry = self.declare(name, name, py_object_type, pos, 'private')
735         entry.is_variable = True
736         entry.is_pyglobal = True
737         return entry
738
739
740 class BuiltinScope(Scope):
741     #  The builtin namespace.
742
743     is_builtin_scope = True
744
745     def __init__(self):
746         if Options.pre_import is None:
747             Scope.__init__(self, "__builtin__", None, None)
748         else:
749             Scope.__init__(self, "__builtin__", PreImportScope(), None)
750         self.type_names = {}
751
752         for name, definition in self.builtin_entries.iteritems():
753             cname, type = definition
754             self.declare_var(name, type, None, cname)
755
756     def lookup(self, name, language_level=None):
757         # 'language_level' is passed by ModuleScope
758         if language_level == 3:
759             if name == 'str':
760                 name = 'unicode'
761         return Scope.lookup(self, name)
762
763     def declare_builtin(self, name, pos):
764         if not hasattr(builtins, name):
765             if self.outer_scope is not None:
766                 return self.outer_scope.declare_builtin(name, pos)
767             else:
768                 if Options.error_on_unknown_names:
769                     error(pos, "undeclared name not builtin: %s" % name)
770                 else:
771                     warning(pos, "undeclared name not builtin: %s" % name, 2)
772
773     def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
774             utility_code = None):
775         # If python_equiv == "*", the Python equivalent has the same name
776         # as the entry, otherwise it has the name specified by python_equiv.
777         name = EncodedString(name)
778         entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
779                                        utility_code = utility_code)
780         if python_equiv:
781             if python_equiv == "*":
782                 python_equiv = name
783             else:
784                 python_equiv = EncodedString(python_equiv)
785             var_entry = Entry(python_equiv, python_equiv, py_object_type)
786             var_entry.is_variable = 1
787             var_entry.is_builtin = 1
788             var_entry.utility_code = utility_code
789             entry.as_variable = var_entry
790         return entry
791
792     def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None):
793         name = EncodedString(name)
794         type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname)
795         scope = CClassScope(name, outer_scope=None, visibility='extern')
796         scope.directives = {}
797         if name == 'bool':
798             scope.directives['final'] = True
799         type.set_scope(scope)
800         self.type_names[name] = 1
801         entry = self.declare_type(name, type, None, visibility='extern')
802         entry.utility_code = utility_code
803
804         var_entry = Entry(name = entry.name,
805             type = self.lookup('type').type, # make sure "type" is the first type declared...
806             pos = entry.pos,
807             cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
808         var_entry.is_variable = 1
809         var_entry.is_cglobal = 1
810         var_entry.is_readonly = 1
811         var_entry.is_builtin = 1
812         var_entry.utility_code = utility_code
813         if Options.cache_builtins:
814             var_entry.is_const = True
815         entry.as_variable = var_entry
816
817         return type
818
819     def builtin_scope(self):
820         return self
821
822     builtin_entries = {
823
824         "type":   ["((PyObject*)&PyType_Type)", py_object_type],
825
826         "bool":   ["((PyObject*)&PyBool_Type)", py_object_type],
827         "int":    ["((PyObject*)&PyInt_Type)", py_object_type],
828         "long":   ["((PyObject*)&PyLong_Type)", py_object_type],
829         "float":  ["((PyObject*)&PyFloat_Type)", py_object_type],
830         "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
831
832         "bytes":  ["((PyObject*)&PyBytes_Type)", py_object_type],
833         "str":    ["((PyObject*)&PyString_Type)", py_object_type],
834         "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
835
836         "tuple":  ["((PyObject*)&PyTuple_Type)", py_object_type],
837         "list":   ["((PyObject*)&PyList_Type)", py_object_type],
838         "dict":   ["((PyObject*)&PyDict_Type)", py_object_type],
839         "set":    ["((PyObject*)&PySet_Type)", py_object_type],
840         "frozenset":   ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
841
842         "slice":  ["((PyObject*)&PySlice_Type)", py_object_type],
843 #        "file":   ["((PyObject*)&PyFile_Type)", py_object_type],  # not in Py3
844
845         "None":   ["Py_None", py_object_type],
846         "False":  ["Py_False", py_object_type],
847         "True":   ["Py_True", py_object_type],
848     }
849
850 const_counter = 1 # As a temporary solution for compiling code in pxds
851
852 class ModuleScope(Scope):
853     # module_name          string             Python name of the module
854     # module_cname         string             C name of Python module object
855     # #module_dict_cname   string             C name of module dict object
856     # method_table_cname   string             C name of method table
857     # doc                  string             Module doc string
858     # doc_cname            string             C name of module doc string
859     # utility_code_list    [UtilityCode]      Queuing utility codes for forwarding to Code.py
860     # python_include_files [string]           Standard  Python headers to be included
861     # include_files        [string]           Other C headers to be included
862     # string_to_entry      {string : Entry}   Map string const to entry
863     # identifier_to_entry  {string : Entry}   Map identifier string const to entry
864     # context              Context
865     # parent_module        Scope              Parent in the import namespace
866     # module_entries       {string : Entry}   For cimport statements
867     # type_names           {string : 1}       Set of type names (used during parsing)
868     # included_files       [string]           Cython sources included with 'include'
869     # pxd_file_loaded      boolean            Corresponding .pxd file has been processed
870     # cimported_modules    [ModuleScope]      Modules imported with cimport
871     # types_imported       {PyrexType : 1}    Set of types for which import code generated
872     # has_import_star      boolean            Module contains import *
873     # cpp                  boolean            Compiling a C++ file
874
875     is_module_scope = 1
876     has_import_star = 0
877
878     def __init__(self, name, parent_module, context):
879         self.parent_module = parent_module
880         outer_scope = context.find_submodule("__builtin__")
881         Scope.__init__(self, name, outer_scope, parent_module)
882         if name != "__init__":
883             self.module_name = name
884         else:
885             # Treat Spam/__init__.pyx specially, so that when Python loads
886             # Spam/__init__.so, initSpam() is defined.
887             self.module_name = parent_module.module_name
888         self.module_name = EncodedString(self.module_name)
889         self.context = context
890         self.module_cname = Naming.module_cname
891         self.module_dict_cname = Naming.moddict_cname
892         self.method_table_cname = Naming.methtable_cname
893         self.doc = ""
894         self.doc_cname = Naming.moddoc_cname
895         self.utility_code_list = []
896         self.module_entries = {}
897         self.python_include_files = ["Python.h"]
898         self.include_files = []
899         self.type_names = dict(outer_scope.type_names)
900         self.pxd_file_loaded = 0
901         self.cimported_modules = []
902         self.types_imported = {}
903         self.included_files = []
904         self.has_extern_class = 0
905         self.cached_builtins = []
906         self.undeclared_cached_builtins = []
907         self.namespace_cname = self.module_cname
908         for name in ['__builtins__', '__name__', '__file__', '__doc__']:
909             self.declare_var(EncodedString(name), py_object_type, None)
910
911     def qualifying_scope(self):
912         return self.parent_module
913
914     def global_scope(self):
915         return self
916
917     def lookup(self, name):
918         entry = self.lookup_here(name)
919         if entry is not None:
920             return entry
921         return self.outer_scope.lookup(name, language_level = self.context.language_level)
922
923     def declare_builtin(self, name, pos):
924         if not hasattr(builtins, name) \
925                and name not in Code.non_portable_builtins_map \
926                and name not in Code.uncachable_builtins:
927             if self.has_import_star:
928                 entry = self.declare_var(name, py_object_type, pos)
929                 return entry
930             else:
931                 if Options.error_on_unknown_names:
932                     error(pos, "undeclared name not builtin: %s" % name)
933                 else:
934                     warning(pos, "undeclared name not builtin: %s" % name, 2)
935                 # unknown - assume it's builtin and look it up at runtime
936                 entry = self.declare(name, None, py_object_type, pos, 'private')
937                 entry.is_builtin = 1
938                 return entry
939         if Options.cache_builtins:
940             for entry in self.cached_builtins:
941                 if entry.name == name:
942                     return entry
943         entry = self.declare(None, None, py_object_type, pos, 'private')
944         if Options.cache_builtins and name not in Code.uncachable_builtins:
945             entry.is_builtin = 1
946             entry.is_const = 1 # cached
947             entry.name = name
948             entry.cname = Naming.builtin_prefix + name
949             self.cached_builtins.append(entry)
950             self.undeclared_cached_builtins.append(entry)
951         else:
952             entry.is_builtin = 1
953             entry.name = name
954         return entry
955
956     def find_module(self, module_name, pos):
957         # Find a module in the import namespace, interpreting
958         # relative imports relative to this module's parent.
959         # Finds and parses the module's .pxd file if the module
960         # has not been referenced before.
961         return self.global_scope().context.find_module(
962             module_name, relative_to = self.parent_module, pos = pos)
963
964     def find_submodule(self, name):
965         # Find and return scope for a submodule of this module,
966         # creating a new empty one if necessary. Doesn't parse .pxd.
967         scope = self.lookup_submodule(name)
968         if not scope:
969             scope = ModuleScope(name,
970                 parent_module = self, context = self.context)
971             self.module_entries[name] = scope
972         return scope
973
974     def lookup_submodule(self, name):
975         # Return scope for submodule of this module, or None.
976         return self.module_entries.get(name, None)
977
978     def add_include_file(self, filename):
979         if filename not in self.python_include_files \
980             and filename not in self.include_files:
981                 self.include_files.append(filename)
982
983     def add_imported_module(self, scope):
984         if scope not in self.cimported_modules:
985             for filename in scope.include_files:
986                 self.add_include_file(filename)
987             self.cimported_modules.append(scope)
988             for m in scope.cimported_modules:
989                 self.add_imported_module(m)
990
991     def add_imported_entry(self, name, entry, pos):
992         if entry not in self.entries:
993             self.entries[name] = entry
994         else:
995             warning(pos, "'%s' redeclared  " % name, 0)
996
997     def declare_module(self, name, scope, pos):
998         # Declare a cimported module. This is represented as a
999         # Python module-level variable entry with a module
1000         # scope attached to it. Reports an error and returns
1001         # None if previously declared as something else.
1002         entry = self.lookup_here(name)
1003         if entry:
1004             if entry.is_pyglobal and entry.as_module is scope:
1005                 return entry # Already declared as the same module
1006             if not (entry.is_pyglobal and not entry.as_module):
1007                 # SAGE -- I put this here so Pyrex
1008                 # cimport's work across directories.
1009                 # Currently it tries to multiply define
1010                 # every module appearing in an import list.
1011                 # It shouldn't be an error for a module
1012                 # name to appear again, and indeed the generated
1013                 # code compiles fine.
1014                 return entry
1015                 warning(pos, "'%s' redeclared  " % name, 0)
1016                 return None
1017         else:
1018             entry = self.declare_var(name, py_object_type, pos)
1019         entry.as_module = scope
1020         self.add_imported_module(scope)
1021         return entry
1022
1023     def declare_var(self, name, type, pos,
1024                     cname = None, visibility = 'private', api = 0, is_cdef = 0):
1025         # Add an entry for a global variable. If it is a Python
1026         # object type, and not declared with cdef, it will live
1027         # in the module dictionary, otherwise it will be a C
1028         # global variable.
1029         entry = Scope.declare_var(self, name, type, pos,
1030                                   cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1031         if not visibility in ('private', 'public', 'extern'):
1032             error(pos, "Module-level variable cannot be declared %s" % visibility)
1033         if not is_cdef:
1034             if type is unspecified_type:
1035                 type = py_object_type
1036             if not (type.is_pyobject and not type.is_extension_type):
1037                 raise InternalError(
1038                     "Non-cdef global variable is not a generic Python object")
1039             entry.is_pyglobal = 1
1040         else:
1041             entry.is_cglobal = 1
1042             if entry.type.is_pyobject:
1043                 entry.init = 0
1044             self.var_entries.append(entry)
1045         return entry
1046
1047     def declare_global(self, name, pos):
1048         entry = self.lookup_here(name)
1049         if not entry:
1050             self.declare_var(name, py_object_type, pos)
1051
1052     def use_utility_code(self, new_code):
1053         if new_code is not None:
1054             self.utility_code_list.append(new_code)
1055
1056     def declare_c_class(self, name, pos, defining = 0, implementing = 0,
1057         module_name = None, base_type = None, objstruct_cname = None,
1058         typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
1059         buffer_defaults = None, shadow = 0):
1060         # If this is a non-extern typedef class, expose the typedef, but use
1061         # the non-typedef struct internally to avoid needing forward
1062         # declarations for anonymous structs.
1063         if typedef_flag and visibility != 'extern':
1064             if not (visibility == 'public' or api):
1065                 warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
1066             objtypedef_cname = objstruct_cname
1067             typedef_flag = 0
1068         else:
1069             objtypedef_cname = None
1070         #
1071         #  Look for previous declaration as a type
1072         #
1073         entry = self.lookup_here(name)
1074         if entry and not shadow:
1075             type = entry.type
1076             if not (entry.is_type and type.is_extension_type):
1077                 entry = None # Will cause redeclaration and produce an error
1078             else:
1079                 scope = type.scope
1080                 if typedef_flag and (not scope or scope.defined):
1081                     self.check_previous_typedef_flag(entry, typedef_flag, pos)
1082                 if (scope and scope.defined) or (base_type and type.base_type):
1083                     if base_type and base_type is not type.base_type:
1084                         error(pos, "Base type does not match previous declaration")
1085                 if base_type and not type.base_type:
1086                     type.base_type = base_type
1087         #
1088         #  Make a new entry if needed
1089         #
1090         if not entry or shadow:
1091             type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
1092             type.pos = pos
1093             type.buffer_defaults = buffer_defaults
1094             if objtypedef_cname is not None:
1095                 type.objtypedef_cname = objtypedef_cname
1096             if visibility == 'extern':
1097                 type.module_name = module_name
1098             else:
1099                 type.module_name = self.qualified_name
1100             type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1101             entry = self.declare_type(name, type, pos, visibility = visibility,
1102                 defining = 0, shadow = shadow)
1103             entry.is_cclass = True
1104             if objstruct_cname:
1105                 type.objstruct_cname = objstruct_cname
1106             elif not entry.in_cinclude:
1107                 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1108             else:
1109                 error(entry.pos,
1110                     "Object name required for 'public' or 'extern' C class")
1111             self.attach_var_entry_to_c_class(entry)
1112             self.c_class_entries.append(entry)
1113         #
1114         #  Check for re-definition and create scope if needed
1115         #
1116         if not type.scope:
1117             if defining or implementing:
1118                 scope = CClassScope(name = name, outer_scope = self,
1119                     visibility = visibility)
1120                 if base_type and base_type.scope:
1121                     scope.declare_inherited_c_attributes(base_type.scope)
1122                 type.set_scope(scope)
1123                 self.type_entries.append(entry)
1124             else:
1125                 self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
1126         else:
1127             if defining and type.scope.defined:
1128                 error(pos, "C class '%s' already defined" % name)
1129             elif implementing and type.scope.implemented:
1130                 error(pos, "C class '%s' already implemented" % name)
1131         #
1132         #  Fill in options, checking for compatibility with any previous declaration
1133         #
1134         if defining:
1135             entry.defined_in_pxd = 1
1136         if implementing:   # So that filenames in runtime exceptions refer to
1137             entry.pos = pos  # the .pyx file and not the .pxd file
1138         if visibility != 'private' and entry.visibility != visibility:
1139             error(pos, "Class '%s' previously declared as '%s'"
1140                 % (name, entry.visibility))
1141         if api:
1142             entry.api = 1
1143         if objstruct_cname:
1144             if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1145                 error(pos, "Object struct name differs from previous declaration")
1146             type.objstruct_cname = objstruct_cname
1147         if typeobj_cname:
1148             if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1149                     error(pos, "Type object name differs from previous declaration")
1150             type.typeobj_cname = typeobj_cname
1151         #
1152         # Return new or existing entry
1153         #
1154         return entry
1155
1156     def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
1157         if typedef_flag and not self.in_cinclude:
1158             error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
1159
1160     def allocate_vtable_names(self, entry):
1161         #  If extension type has a vtable, allocate vtable struct and
1162         #  slot names for it.
1163         type = entry.type
1164         if type.base_type and type.base_type.vtabslot_cname:
1165             #print "...allocating vtabslot_cname because base type has one" ###
1166             type.vtabslot_cname = "%s.%s" % (
1167                 Naming.obj_base_cname, type.base_type.vtabslot_cname)
1168         elif type.scope and type.scope.cfunc_entries:
1169             # one special case here: when inheriting from builtin
1170             # types, the methods may also be built-in, in which
1171             # case they won't need a vtable
1172             entry_count = len(type.scope.cfunc_entries)
1173             base_type = type.base_type
1174             while base_type:
1175                 # FIXME: this will break if we ever get non-inherited C methods
1176                 if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
1177                     break
1178                 if base_type.is_builtin_type:
1179                     # builtin base type defines all methods => no vtable needed
1180                     return
1181                 base_type = base_type.base_type
1182             #print "...allocating vtabslot_cname because there are C methods" ###
1183             type.vtabslot_cname = Naming.vtabslot_cname
1184         if type.vtabslot_cname:
1185             #print "...allocating other vtable related cnames" ###
1186             type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1187             type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1188
1189     def check_c_classes_pxd(self):
1190         # Performs post-analysis checking and finishing up of extension types
1191         # being implemented in this module. This is called only for the .pxd.
1192         #
1193         # Checks all extension types declared in this scope to
1194         # make sure that:
1195         #
1196         #    * The extension type is fully declared
1197         #
1198         # Also allocates a name for the vtable if needed.
1199         #
1200         for entry in self.c_class_entries:
1201             # Check defined
1202             if not entry.type.scope:
1203                 error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
1204
1205     def check_c_class(self, entry):
1206         type = entry.type
1207         name = entry.name
1208         visibility = entry.visibility
1209         # Check defined
1210         if not type.scope:
1211             error(entry.pos, "C class '%s' is declared but not defined" % name)
1212         # Generate typeobj_cname
1213         if visibility != 'extern' and not type.typeobj_cname:
1214             type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1215         ## Generate typeptr_cname
1216         #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1217         # Check C methods defined
1218         if type.scope:
1219             for method_entry in type.scope.cfunc_entries:
1220                 if not method_entry.is_inherited and not method_entry.func_cname:
1221                     error(method_entry.pos, "C method '%s' is declared but not defined" %
1222                         method_entry.name)
1223         # Allocate vtable name if necessary
1224         if type.vtabslot_cname:
1225             #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1226             type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1227
1228     def check_c_classes(self):
1229         # Performs post-analysis checking and finishing up of extension types
1230         # being implemented in this module. This is called only for the main
1231         # .pyx file scope, not for cimported .pxd scopes.
1232         #
1233         # Checks all extension types declared in this scope to
1234         # make sure that:
1235         #
1236         #    * The extension type is implemented
1237         #    * All required object and type names have been specified or generated
1238         #    * All non-inherited C methods are implemented
1239         #
1240         # Also allocates a name for the vtable if needed.
1241         #
1242         debug_check_c_classes = 0
1243         if debug_check_c_classes:
1244             print("Scope.check_c_classes: checking scope " + self.qualified_name)
1245         for entry in self.c_class_entries:
1246             if debug_check_c_classes:
1247                 print("...entry %s %s" % (entry.name, entry))
1248                 print("......type = ",  entry.type)
1249                 print("......visibility = ", entry.visibility)
1250             self.check_c_class(entry)
1251
1252     def check_c_functions(self):
1253         # Performs post-analysis checking making sure all
1254         # defined c functions are actually implemented.
1255         for name, entry in self.entries.items():
1256             if entry.is_cfunction:
1257                 if (entry.defined_in_pxd
1258                         and entry.scope is self
1259                         and entry.visibility != 'extern'
1260                         and not entry.in_cinclude
1261                         and not entry.is_implemented):
1262                     error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1263
1264     def attach_var_entry_to_c_class(self, entry):
1265         # The name of an extension class has to serve as both a type
1266         # name and a variable name holding the type object. It is
1267         # represented in the symbol table by a type entry with a
1268         # variable entry attached to it. For the variable entry,
1269         # we use a read-only C global variable whose name is an
1270         # expression that refers to the type object.
1271         import Builtin
1272         var_entry = Entry(name = entry.name,
1273             type = Builtin.type_type,
1274             pos = entry.pos,
1275             cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
1276         var_entry.is_variable = 1
1277         var_entry.is_cglobal = 1
1278         var_entry.is_readonly = 1
1279         entry.as_variable = var_entry
1280
1281     def is_cpp(self):
1282         return self.cpp
1283
1284     def infer_types(self):
1285         from TypeInference import PyObjectTypeInferer
1286         PyObjectTypeInferer().infer_types(self)
1287
1288 class LocalScope(Scope):
1289
1290     def __init__(self, name, outer_scope, parent_scope = None):
1291         if parent_scope is None:
1292             parent_scope = outer_scope
1293         Scope.__init__(self, name, outer_scope, parent_scope)
1294
1295     def mangle(self, prefix, name):
1296         return prefix + name
1297
1298     def declare_arg(self, name, type, pos):
1299         # Add an entry for an argument of a function.
1300         cname = self.mangle(Naming.var_prefix, name)
1301         entry = self.declare(name, cname, type, pos, 'private')
1302         entry.is_variable = 1
1303         if type.is_pyobject:
1304             entry.init = "0"
1305         entry.is_arg = 1
1306         #entry.borrowed = 1 # Not using borrowed arg refs for now
1307         self.arg_entries.append(entry)
1308         self.control_flow.set_state((), (name, 'source'), 'arg')
1309         return entry
1310
1311     def declare_var(self, name, type, pos,
1312                     cname = None, visibility = 'private', api = 0, is_cdef = 0):
1313         # Add an entry for a local variable.
1314         if visibility in ('public', 'readonly'):
1315             error(pos, "Local variable cannot be declared %s" % visibility)
1316         entry = Scope.declare_var(self, name, type, pos,
1317                                   cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1318         if type.is_pyobject and not Options.init_local_none:
1319             entry.init = "0"
1320         entry.init_to_none = (type.is_pyobject or type.is_unspecified) and Options.init_local_none
1321         entry.is_local = 1
1322         self.var_entries.append(entry)
1323         return entry
1324
1325     def declare_global(self, name, pos):
1326         # Pull entry from global scope into local scope.
1327         if self.lookup_here(name):
1328             warning(pos, "'%s' redeclared  ", 0)
1329         else:
1330             entry = self.global_scope().lookup_target(name)
1331             self.entries[name] = entry
1332
1333     def declare_nonlocal(self, name, pos):
1334         # Pull entry from outer scope into local scope
1335         orig_entry = self.lookup_here(name)
1336         if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1337             error(pos, "'%s' redeclared as nonlocal" % name)
1338         else:
1339             entry = self.lookup(name)
1340             if entry is None or not entry.from_closure:
1341                 error(pos, "no binding for nonlocal '%s' found" % name)
1342
1343     def lookup(self, name):
1344         # Look up name in this scope or an enclosing one.
1345         # Return None if not found.
1346         entry = Scope.lookup(self, name)
1347         if entry is not None:
1348             if entry.scope is not self and entry.scope.is_closure_scope:
1349                 if hasattr(entry.scope, "scope_class"):
1350                     raise InternalError, "lookup() after scope class created."
1351                 # The actual c fragment for the different scopes differs
1352                 # on the outside and inside, so we make a new entry
1353                 entry.in_closure = True
1354                 # Would it be better to declare_var here?
1355                 inner_entry = Entry(entry.name, entry.cname, entry.type, entry.pos)
1356                 inner_entry.scope = self
1357                 inner_entry.is_variable = True
1358                 inner_entry.outer_entry = entry
1359                 inner_entry.from_closure = True
1360                 inner_entry.is_declared_generic = entry.is_declared_generic
1361                 self.entries[name] = inner_entry
1362                 return inner_entry
1363         return entry
1364
1365     def mangle_closure_cnames(self, outer_scope_cname):
1366         for entry in self.entries.values():
1367             if entry.from_closure:
1368                 cname = entry.outer_entry.cname
1369                 if self.is_passthrough:
1370                     entry.cname = cname
1371                 else:
1372                     if cname.startswith(Naming.cur_scope_cname):
1373                         cname = cname[len(Naming.cur_scope_cname)+2:]
1374                     entry.cname = "%s->%s" % (outer_scope_cname, cname)
1375             elif entry.in_closure:
1376                 entry.original_cname = entry.cname
1377                 entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
1378
1379 class GeneratorExpressionScope(Scope):
1380     """Scope for generator expressions and comprehensions.  As opposed
1381     to generators, these can be easily inlined in some cases, so all
1382     we really need is a scope that holds the loop variable(s).
1383     """
1384     def __init__(self, outer_scope):
1385         name = outer_scope.global_scope().next_id(Naming.genexpr_id_ref)
1386         Scope.__init__(self, name, outer_scope, outer_scope)
1387         self.directives = outer_scope.directives
1388         self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
1389
1390     def mangle(self, prefix, name):
1391         return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
1392
1393     def declare_var(self, name, type, pos,
1394                     cname = None, visibility = 'private', api = 0, is_cdef = True):
1395         if type is unspecified_type:
1396             # if the outer scope defines a type for this variable, inherit it
1397             outer_entry = self.outer_scope.lookup(name)
1398             if outer_entry and outer_entry.is_variable:
1399                 type = outer_entry.type # may still be 'unspecified_type' !
1400         # the parent scope needs to generate code for the variable, but
1401         # this scope must hold its name exclusively
1402         cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name))
1403         entry = self.declare(name, cname, type, pos, visibility)
1404         entry.is_variable = 1
1405         self.var_entries.append(entry)
1406         self.entries[name] = entry
1407         return entry
1408
1409     def declare_lambda_function(self, func_cname, pos):
1410         return self.outer_scope.declare_lambda_function(func_cname, pos)
1411
1412     def add_lambda_def(self, def_node):
1413         return self.outer_scope.add_lambda_def(def_node)
1414
1415
1416 class ClosureScope(LocalScope):
1417
1418     is_closure_scope = True
1419
1420     def __init__(self, name, scope_name, outer_scope):
1421         LocalScope.__init__(self, name, outer_scope)
1422         self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name)
1423
1424 #    def mangle_closure_cnames(self, scope_var):
1425 #        for entry in self.entries.values() + self.temp_entries:
1426 #            entry.in_closure = 1
1427 #        LocalScope.mangle_closure_cnames(self, scope_var)
1428
1429 #    def mangle(self, prefix, name):
1430 #        return "%s->%s" % (self.cur_scope_cname, name)
1431 #        return "%s->%s" % (self.closure_cname, name)
1432
1433     def declare_pyfunction(self, name, pos, allow_redefine=False):
1434         return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private')
1435
1436 class StructOrUnionScope(Scope):
1437     #  Namespace of a C struct or union.
1438
1439     def __init__(self, name="?"):
1440         Scope.__init__(self, name, None, None)
1441
1442     def declare_var(self, name, type, pos,
1443                     cname = None, visibility = 'private', api = 0, is_cdef = 0, allow_pyobject = 0):
1444         # Add an entry for an attribute.
1445         if not cname:
1446             cname = name
1447             if visibility == 'private':
1448                 cname = c_safe_identifier(cname)
1449         if type.is_cfunction:
1450             type = PyrexTypes.CPtrType(type)
1451         entry = self.declare(name, cname, type, pos, visibility)
1452         entry.is_variable = 1
1453         self.var_entries.append(entry)
1454         if type.is_pyobject and not allow_pyobject:
1455             error(pos,
1456                   "C struct/union member cannot be a Python object")
1457         if visibility != 'private':
1458             error(pos,
1459                   "C struct/union member cannot be declared %s" % visibility)
1460         return entry
1461
1462     def declare_cfunction(self, name, type, pos,
1463                           cname = None, visibility = 'private', defining = 0,
1464                           api = 0, in_pxd = 0, modifiers = ()): # currently no utility code ...
1465         return self.declare_var(name, type, pos,
1466                                 cname=cname, visibility=visibility)
1467
1468 class ClassScope(Scope):
1469     #  Abstract base class for namespace of
1470     #  Python class or extension type.
1471     #
1472     #  class_name     string   Pyrex name of the class
1473     #  scope_prefix   string   Additional prefix for names
1474     #                          declared in the class
1475     #  doc    string or None   Doc string
1476
1477     def __init__(self, name, outer_scope):
1478         Scope.__init__(self, name, outer_scope, outer_scope)
1479         self.class_name = name
1480         self.doc = None
1481
1482     def lookup(self, name):
1483         entry = Scope.lookup(self, name)
1484         if entry:
1485             return entry
1486         if name == "classmethod":
1487             # We don't want to use the builtin classmethod here 'cause it won't do the
1488             # right thing in this scope (as the class memebers aren't still functions).
1489             # Don't want to add a cfunction to this scope 'cause that would mess with
1490             # the type definition, so we just return the right entry.
1491             self.use_utility_code(classmethod_utility_code)
1492             entry = Entry(
1493                 "classmethod",
1494                 "__Pyx_Method_ClassMethod",
1495                 PyrexTypes.CFuncType(
1496                     py_object_type,
1497                     [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1498             entry.is_cfunction = 1
1499         return entry
1500
1501
1502 class PyClassScope(ClassScope):
1503     #  Namespace of a Python class.
1504     #
1505     #  class_obj_cname     string   C variable holding class object
1506
1507     is_py_class_scope = 1
1508
1509     def declare_var(self, name, type, pos,
1510                     cname = None, visibility = 'private', api = 0, is_cdef = 0):
1511         if type is unspecified_type:
1512             type = py_object_type
1513         # Add an entry for a class attribute.
1514         entry = Scope.declare_var(self, name, type, pos,
1515                                   cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1516         entry.is_pyglobal = 1 # FIXME: WTF?
1517         entry.is_pyclass_attr = 1
1518         return entry
1519
1520     def declare_nonlocal(self, name, pos):
1521         # Pull entry from outer scope into local scope
1522         orig_entry = self.lookup_here(name)
1523         if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1524             error(pos, "'%s' redeclared as nonlocal" % name)
1525         else:
1526             entry = self.lookup(name)
1527             if entry is None:
1528                 error(pos, "no binding for nonlocal '%s' found" % name)
1529             else:
1530                 # FIXME: this works, but it's unclear if it's the
1531                 # right thing to do
1532                 self.entries[name] = entry
1533
1534     def add_default_value(self, type):
1535         return self.outer_scope.add_default_value(type)
1536
1537
1538 class CClassScope(ClassScope):
1539     #  Namespace of an extension type.
1540     #
1541     #  parent_type           CClassType
1542     #  #typeobj_cname        string or None
1543     #  #objstruct_cname      string
1544     #  method_table_cname    string
1545     #  getset_table_cname    string
1546     #  has_pyobject_attrs    boolean  Any PyObject attributes?
1547     #  property_entries      [Entry]
1548     #  defined               boolean  Defined in .pxd file
1549     #  implemented           boolean  Defined in .pyx file
1550     #  inherited_var_entries [Entry]  Adapted var entries from base class
1551
1552     is_c_class_scope = 1
1553
1554     def __init__(self, name, outer_scope, visibility):
1555         ClassScope.__init__(self, name, outer_scope)
1556         if visibility != 'extern':
1557             self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1558             self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1559         self.has_pyobject_attrs = 0
1560         self.property_entries = []
1561         self.inherited_var_entries = []
1562         self.defined = 0
1563         self.implemented = 0
1564
1565     def needs_gc(self):
1566         # If the type or any of its base types have Python-valued
1567         # C attributes, then it needs to participate in GC.
1568         return self.has_pyobject_attrs or \
1569             (self.parent_type.base_type and
1570                 self.parent_type.base_type.scope is not None and
1571                 self.parent_type.base_type.scope.needs_gc())
1572
1573     def declare_var(self, name, type, pos,
1574                     cname = None, visibility = 'private', api = 0, is_cdef = 0):
1575         if is_cdef:
1576             # Add an entry for an attribute.
1577             if self.defined:
1578                 error(pos,
1579                     "C attributes cannot be added in implementation part of"
1580                     " extension type defined in a pxd")
1581             if get_special_method_signature(name):
1582                 error(pos,
1583                     "The name '%s' is reserved for a special method."
1584                         % name)
1585             if not cname:
1586                 cname = name
1587                 if visibility == 'private':
1588                     cname = c_safe_identifier(cname)
1589             if type.is_cpp_class and visibility != 'extern':
1590                 error(pos, "C++ classes not allowed as members of an extension type, use a pointer or reference instead")
1591             entry = self.declare(name, cname, type, pos, visibility)
1592             entry.is_variable = 1
1593             self.var_entries.append(entry)
1594             if type.is_pyobject:
1595                 self.has_pyobject_attrs = 1
1596             if visibility not in ('private', 'public', 'readonly'):
1597                 error(pos,
1598                     "Attribute of extension type cannot be declared %s" % visibility)
1599             if visibility in ('public', 'readonly'):
1600                 if name == "__weakref__":
1601                     error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1602                 if not type.is_pyobject:
1603                     if (not type.create_to_py_utility_code(self) or
1604                         (visibility=='public' and not
1605                          type.create_from_py_utility_code(self))):
1606                         error(pos,
1607                               "C attribute of type '%s' cannot be accessed from Python" % type)
1608             return entry
1609         else:
1610             if type is unspecified_type:
1611                 type = py_object_type
1612             # Add an entry for a class attribute.
1613             entry = Scope.declare_var(self, name, type, pos,
1614                                       cname=cname, visibility=visibility, api=api, is_cdef=is_cdef)
1615             entry.is_member = 1
1616             entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1617                                   # I keep it in for now. is_member should be enough
1618                                   # later on
1619             self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1620             return entry
1621
1622
1623     def declare_pyfunction(self, name, pos, allow_redefine=False):
1624         # Add an entry for a method.
1625         if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1626             error(pos, "Special method %s must be implemented via __richcmp__" % name)
1627         if name == "__new__":
1628             error(pos, "__new__ method of extension type will change semantics "
1629                 "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1630         entry = self.declare_var(name, py_object_type, pos,
1631                                  visibility='extern')
1632         special_sig = get_special_method_signature(name)
1633         if special_sig:
1634             # Special methods get put in the method table with a particular
1635             # signature declared in advance.
1636             entry.signature = special_sig
1637             entry.is_special = 1
1638         else:
1639             entry.signature = pymethod_signature
1640             entry.is_special = 0
1641
1642         self.pyfunc_entries.append(entry)
1643         return entry
1644
1645     def lookup_here(self, name):
1646         if name == "__new__":
1647             name = EncodedString("__cinit__")
1648         return ClassScope.lookup_here(self, name)
1649
1650     def declare_cfunction(self, name, type, pos,
1651                           cname = None, visibility = 'private',
1652                           defining = 0, api = 0, in_pxd = 0, modifiers = (),
1653                           utility_code = None):
1654         if get_special_method_signature(name):
1655             error(pos, "Special methods must be declared with 'def', not 'cdef'")
1656         args = type.args
1657         if not args:
1658             error(pos, "C method has no self argument")
1659         elif not self.parent_type.assignable_from(args[0].type):
1660             error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
1661                   (args[0].type, name, self.parent_type))
1662         entry = self.lookup_here(name)
1663         if entry:
1664             if not entry.is_cfunction:
1665                 warning(pos, "'%s' redeclared  " % name, 0)
1666             else:
1667                 if defining and entry.func_cname:
1668                     error(pos, "'%s' already defined" % name)
1669                 #print "CClassScope.declare_cfunction: checking signature" ###
1670                 if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1671                     pass
1672                 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1673                     entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore', modifiers=modifiers)
1674                     defining = 1
1675                 else:
1676                     error(pos, "Signature not compatible with previous declaration")
1677                     error(entry.pos, "Previous declaration is here")
1678         else:
1679             if self.defined:
1680                 error(pos,
1681                     "C method '%s' not previously declared in definition part of"
1682                     " extension type" % name)
1683             entry = self.add_cfunction(name, type, pos, cname or name,
1684                                        visibility, modifiers)
1685         if defining:
1686             entry.func_cname = self.mangle(Naming.func_prefix, name)
1687         entry.utility_code = utility_code
1688         return entry
1689
1690     def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
1691         # Add a cfunction entry without giving it a func_cname.
1692         prev_entry = self.lookup_here(name)
1693         entry = ClassScope.add_cfunction(self, name, type, pos, cname,
1694                                          visibility, modifiers)
1695         entry.is_cmethod = 1
1696         entry.prev_entry = prev_entry
1697         return entry
1698
1699     def declare_builtin_cfunction(self, name, type, cname, utility_code = None):
1700         # overridden methods of builtin types still have their Python
1701         # equivalent that must be accessible to support bound methods
1702         name = EncodedString(name)
1703         entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
1704                                        utility_code = utility_code)
1705         var_entry = Entry(name, name, py_object_type)
1706         var_entry.is_variable = 1
1707         var_entry.is_builtin = 1
1708         var_entry.utility_code = utility_code
1709         entry.as_variable = var_entry
1710         return entry
1711
1712     def declare_property(self, name, doc, pos):
1713         entry = self.lookup_here(name)
1714         if entry is None:
1715             entry = self.declare(name, name, py_object_type, pos, 'private')
1716         entry.is_property = 1
1717         entry.doc = doc
1718         entry.scope = PropertyScope(name,
1719             outer_scope = self.global_scope(), parent_scope = self)
1720         entry.scope.parent_type = self.parent_type
1721         self.property_entries.append(entry)
1722         return entry
1723
1724     def declare_inherited_c_attributes(self, base_scope):
1725         # Declare entries for all the C attributes of an
1726         # inherited type, with cnames modified appropriately
1727         # to work with this type.
1728         def adapt(cname):
1729             return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
1730         for base_entry in \
1731             base_scope.inherited_var_entries + base_scope.var_entries:
1732                 entry = self.declare(base_entry.name, adapt(base_entry.cname),
1733                     base_entry.type, None, 'private')
1734                 entry.is_variable = 1
1735                 self.inherited_var_entries.append(entry)
1736         for base_entry in base_scope.cfunc_entries:
1737             entry = self.add_cfunction(base_entry.name, base_entry.type,
1738                                        base_entry.pos, adapt(base_entry.cname),
1739                                        base_entry.visibility, base_entry.func_modifiers)
1740             entry.is_inherited = 1
1741
1742
1743 class CppClassScope(Scope):
1744     #  Namespace of a C++ class.
1745
1746     is_cpp_class_scope = 1
1747
1748     default_constructor = None
1749
1750     def __init__(self, name, outer_scope):
1751         Scope.__init__(self, name, outer_scope, None)
1752         self.directives = outer_scope.directives
1753         self.inherited_var_entries = []
1754
1755     def declare_var(self, name, type, pos,
1756                     cname = None, visibility = 'extern', api = 0,
1757                     is_cdef = 0, allow_pyobject = 0):
1758         # Add an entry for an attribute.
1759         if not cname:
1760             cname = name
1761         if type.is_cfunction:
1762             type = PyrexTypes.CPtrType(type)
1763         entry = self.declare(name, cname, type, pos, visibility)
1764         entry.is_variable = 1
1765         self.var_entries.append(entry)
1766         if type.is_pyobject and not allow_pyobject:
1767             error(pos,
1768                 "C++ class member cannot be a Python object")
1769         return entry
1770
1771     def check_base_default_constructor(self, pos):
1772         # Look for default constructors in all base classes.
1773         if self.default_constructor is None:
1774             entry = self.lookup(self.name)
1775             if len(entry.type.base_classes) == 0:
1776                 self.default_constructor = True
1777                 return
1778             for base_class in entry.type.base_classes:
1779                 temp_entry = base_class.scope.lookup_here("<init>")
1780                 found = False
1781                 if temp_entry is None:
1782                     continue
1783                 for alternative in temp_entry.all_alternatives():
1784                     type = alternative.type
1785                     if type.is_ptr:
1786                         type = type.base_type
1787                     if len(type.args) == 0:
1788                         found = True
1789                         break
1790                 if not found:
1791                     self.default_constructor = temp_entry.scope.name
1792                     error(pos, "no matching function for call to " \
1793                             "%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name))
1794         elif not self.default_constructor:
1795             error(pos, "no matching function for call to %s::%s()" %
1796                   (self.default_constructor, self.default_constructor))
1797
1798     def declare_cfunction(self, name, type, pos, cname = None,
1799                           visibility = 'extern', api = 0, defining = 0,
1800                           in_pxd = 0, modifiers = (), utility_code = None):
1801         if name == self.name.split('::')[-1] and cname is None:
1802             self.check_base_default_constructor(pos)
1803             name = '<init>'
1804             type.return_type = self.lookup(self.name).type
1805         prev_entry = self.lookup_here(name)
1806         entry = self.declare_var(name, type, pos,
1807                                  cname=cname, visibility=visibility)
1808         if prev_entry:
1809             entry.overloaded_alternatives = prev_entry.all_alternatives()
1810         entry.utility_code = utility_code
1811         return entry
1812
1813     def declare_inherited_cpp_attributes(self, base_scope):
1814         # Declare entries for all the C++ attributes of an
1815         # inherited type, with cnames modified appropriately
1816         # to work with this type.
1817         for base_entry in \
1818             base_scope.inherited_var_entries + base_scope.var_entries:
1819                 #contructor is not inherited
1820                 if base_entry.name == "<init>":
1821                     continue
1822                 #print base_entry.name, self.entries
1823                 if base_entry.name in self.entries:
1824                     base_entry.name
1825                 entry = self.declare(base_entry.name, base_entry.cname,
1826                     base_entry.type, None, 'extern')
1827                 entry.is_variable = 1
1828                 self.inherited_var_entries.append(entry)
1829         for base_entry in base_scope.cfunc_entries:
1830             entry = self.declare_cfunction(base_entry.name, base_entry.type,
1831                                            base_entry.pos, base_entry.cname,
1832                                            base_entry.visibility, 0,
1833                                            modifiers = base_entry.func_modifiers,
1834                                            utility_code = base_entry.utility_code)
1835             entry.is_inherited = 1
1836
1837     def specialize(self, values):
1838         scope = CppClassScope(self.name, self.outer_scope)
1839         for entry in self.entries.values():
1840             if entry.is_type:
1841                 scope.declare_type(entry.name,
1842                                     entry.type.specialize(values),
1843                                     entry.pos,
1844                                     entry.cname)
1845             else:
1846 #                scope.declare_var(entry.name,
1847 #                                    entry.type.specialize(values),
1848 #                                    entry.pos,
1849 #                                    entry.cname,
1850 #                                    entry.visibility)
1851                 for e in entry.all_alternatives():
1852                     scope.declare_cfunction(e.name,
1853                                             e.type.specialize(values),
1854                                             e.pos,
1855                                             e.cname,
1856                                             utility_code = e.utility_code)
1857         return scope
1858
1859     def add_include_file(self, filename):
1860         self.outer_scope.add_include_file(filename)
1861
1862 class PropertyScope(Scope):
1863     #  Scope holding the __get__, __set__ and __del__ methods for
1864     #  a property of an extension type.
1865     #
1866     #  parent_type   PyExtensionType   The type to which the property belongs
1867
1868     is_property_scope = 1
1869
1870     def declare_pyfunction(self, name, pos, allow_redefine=False):
1871         # Add an entry for a method.
1872         signature = get_property_accessor_signature(name)
1873         if signature:
1874             entry = self.declare(name, name, py_object_type, pos, 'private')
1875             entry.is_special = 1
1876             entry.signature = signature
1877             return entry
1878         else:
1879             error(pos, "Only __get__, __set__ and __del__ methods allowed "
1880                 "in a property declaration")
1881             return None
1882
1883
1884 # Should this go elsewhere (and then get imported)?
1885 #------------------------------------------------------------------------------------
1886
1887 classmethod_utility_code = Code.UtilityCode(
1888 proto = """
1889 #include "descrobject.h"
1890 static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
1891 """,
1892 impl = """
1893 static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
1894     /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
1895     static PyTypeObject *methoddescr_type = NULL;
1896     if (methoddescr_type == NULL) {
1897        PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
1898        if (!meth) return NULL;
1899        methoddescr_type = Py_TYPE(meth);
1900        Py_DECREF(meth);
1901     }
1902     if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
1903         PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
1904         #if PY_VERSION_HEX < 0x03020000
1905         PyTypeObject *d_type = descr->d_type;
1906         #else
1907         PyTypeObject *d_type = descr->d_common.d_type;
1908         #endif
1909         return PyDescr_NewClassMethod(d_type, descr->d_method);
1910     }
1911     else if (PyMethod_Check(method)) { /* python classes */
1912         return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
1913     }
1914     else if (PyCFunction_Check(method)) {
1915         return PyClassMethod_New(method);
1916     }
1917 #ifdef __pyx_binding_PyCFunctionType_USED
1918     else if (PyObject_TypeCheck(method, __pyx_binding_PyCFunctionType)) { /* binded CFunction */
1919         return PyClassMethod_New(method);
1920     }
1921 #endif
1922     PyErr_Format(PyExc_TypeError,
1923                  "Class-level classmethod() can only be called on "
1924                  "a method_descriptor or instance method.");
1925     return NULL;
1926 }
1927 """)
1928
1929 #------------------------------------------------------------------------------------
1930
1931 ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'