Cython has moved to github.

cython-devel

view Cython/Compiler/Symtab.py @ 4256:b816b03ff502

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