Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / cython / src / Cython / Compiler / Symtab.py
blob8db1e6db7533798930bfc73e3d4a078db374300b
2 # Symbol Table
5 import copy
6 import re
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 from TypeSlots import \
13 pyfunction_signature, pymethod_signature, \
14 get_special_method_signature, get_property_accessor_signature
15 import Code
16 import __builtin__ as builtins
18 iso_c99_keywords = set(
19 ['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
20 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
21 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof',
22 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
23 'volatile', 'while',
24 '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict'])
26 def c_safe_identifier(cname):
27 # There are some C limitations on struct entry names.
28 if ((cname[:2] == '__'
29 and not (cname.startswith(Naming.pyrex_prefix)
30 or cname == '__weakref__'))
31 or cname in iso_c99_keywords):
32 cname = Naming.pyrex_prefix + cname
33 return cname
35 class BufferAux(object):
36 writable_needed = False
38 def __init__(self, buflocal_nd_var, rcbuf_var):
39 self.buflocal_nd_var = buflocal_nd_var
40 self.rcbuf_var = rcbuf_var
42 def __repr__(self):
43 return "<BufferAux %r>" % self.__dict__
46 class Entry(object):
47 # A symbol table entry in a Scope or ModuleNamespace.
49 # name string Python name of entity
50 # cname string C name of entity
51 # type PyrexType Type of entity
52 # doc string Doc string
53 # init string Initial value
54 # visibility 'private' or 'public' or 'extern'
55 # is_builtin boolean Is an entry in the Python builtins dict
56 # is_cglobal boolean Is a C global variable
57 # is_pyglobal boolean Is a Python module-level variable
58 # or class attribute during
59 # class construction
60 # is_member boolean Is an assigned class member
61 # is_pyclass_attr boolean Is a name in a Python class namespace
62 # is_variable boolean Is a variable
63 # is_cfunction boolean Is a C function
64 # is_cmethod boolean Is a C method of an extension type
65 # is_builtin_cmethod boolean Is a C method of a builtin type (implies is_cmethod)
66 # is_unbound_cmethod boolean Is an unbound C method of an extension type
67 # is_final_cmethod boolean Is non-overridable C method
68 # is_inline_cmethod boolean Is inlined C method
69 # is_anonymous boolean Is a anonymous pyfunction entry
70 # is_type boolean Is a type definition
71 # is_cclass boolean Is an extension class
72 # is_cpp_class boolean Is a C++ class
73 # is_const boolean Is a constant
74 # is_property boolean Is a property of an extension type:
75 # doc_cname string or None C const holding the docstring
76 # getter_cname string C func for getting property
77 # setter_cname string C func for setting or deleting property
78 # is_self_arg boolean Is the "self" arg of an exttype method
79 # is_arg boolean Is the arg of a method
80 # is_local boolean Is a local variable
81 # in_closure boolean Is referenced in an inner scope
82 # is_readonly boolean Can't be assigned to
83 # func_cname string C func implementing Python func
84 # func_modifiers [string] C function modifiers ('inline')
85 # pos position Source position where declared
86 # namespace_cname string If is_pyglobal, the C variable
87 # holding its home namespace
88 # pymethdef_cname string PyMethodDef structure
89 # signature Signature Arg & return types for Python func
90 # as_variable Entry Alternative interpretation of extension
91 # type name or builtin C function as a variable
92 # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
93 # in_cinclude boolean Suppress C declaration code
94 # enum_values [Entry] For enum types, list of values
95 # qualified_name string "modname.funcname" or "modname.classname"
96 # or "modname.classname.funcname"
97 # is_declared_generic boolean Is declared as PyObject * even though its
98 # type is an extension type
99 # as_module None Module scope, if a cimported module
100 # is_inherited boolean Is an inherited attribute of an extension type
101 # pystring_cname string C name of Python version of string literal
102 # is_interned boolean For string const entries, value is interned
103 # is_identifier boolean For string const entries, value is an identifier
104 # used boolean
105 # is_special boolean Is a special method or property accessor
106 # of an extension type
107 # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
108 # api boolean Generate C API for C class or function
109 # utility_code string Utility code needed when this entry is used
111 # buffer_aux BufferAux or None Extra information needed for buffer variables
112 # inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
113 # Ideally this should not be necesarry.
114 # might_overflow boolean In an arithmetic expression that could cause
115 # overflow (used for type inference).
116 # utility_code_definition For some Cython builtins, the utility code
117 # which contains the definition of the entry.
118 # Currently only supported for CythonScope entries.
119 # error_on_uninitialized Have Control Flow issue an error when this entry is
120 # used uninitialized
121 # cf_used boolean Entry is used
122 # is_fused_specialized boolean Whether this entry of a cdef or def function
123 # is a specialization
125 # TODO: utility_code and utility_code_definition serves the same purpose...
127 inline_func_in_pxd = False
128 borrowed = 0
129 init = ""
130 visibility = 'private'
131 is_builtin = 0
132 is_cglobal = 0
133 is_pyglobal = 0
134 is_member = 0
135 is_pyclass_attr = 0
136 is_variable = 0
137 is_cfunction = 0
138 is_cmethod = 0
139 is_builtin_cmethod = False
140 is_unbound_cmethod = 0
141 is_final_cmethod = 0
142 is_inline_cmethod = 0
143 is_anonymous = 0
144 is_type = 0
145 is_cclass = 0
146 is_cpp_class = 0
147 is_const = 0
148 is_property = 0
149 doc_cname = None
150 getter_cname = None
151 setter_cname = None
152 is_self_arg = 0
153 is_arg = 0
154 is_local = 0
155 in_closure = 0
156 from_closure = 0
157 is_declared_generic = 0
158 is_readonly = 0
159 pyfunc_cname = None
160 func_cname = None
161 func_modifiers = []
162 final_func_cname = None
163 doc = None
164 as_variable = None
165 xdecref_cleanup = 0
166 in_cinclude = 0
167 as_module = None
168 is_inherited = 0
169 pystring_cname = None
170 is_identifier = 0
171 is_interned = 0
172 used = 0
173 is_special = 0
174 defined_in_pxd = 0
175 is_implemented = 0
176 api = 0
177 utility_code = None
178 is_overridable = 0
179 buffer_aux = None
180 prev_entry = None
181 might_overflow = 0
182 fused_cfunction = None
183 is_fused_specialized = False
184 utility_code_definition = None
185 needs_property = False
186 in_with_gil_block = 0
187 from_cython_utility_code = None
188 error_on_uninitialized = False
189 cf_used = True
190 outer_entry = None
192 def __init__(self, name, cname, type, pos = None, init = None):
193 self.name = name
194 self.cname = cname
195 self.type = type
196 self.pos = pos
197 self.init = init
198 self.overloaded_alternatives = []
199 self.cf_assignments = []
200 self.cf_references = []
201 self.inner_entries = []
202 self.defining_entry = self
204 def __repr__(self):
205 return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type)
207 def redeclared(self, pos):
208 error(pos, "'%s' does not match previous declaration" % self.name)
209 error(self.pos, "Previous declaration is here")
211 def all_alternatives(self):
212 return [self] + self.overloaded_alternatives
214 def all_entries(self):
215 return [self] + self.inner_entries
218 class InnerEntry(Entry):
220 An entry in a closure scope that represents the real outer Entry.
222 from_closure = True
224 def __init__(self, outer_entry, scope):
225 Entry.__init__(self, outer_entry.name,
226 outer_entry.cname,
227 outer_entry.type,
228 outer_entry.pos)
229 self.outer_entry = outer_entry
230 self.scope = scope
232 # share state with (outermost) defining entry
233 outermost_entry = outer_entry
234 while outermost_entry.outer_entry:
235 outermost_entry = outermost_entry.outer_entry
236 self.defining_entry = outermost_entry
237 self.inner_entries = outermost_entry.inner_entries
238 self.cf_assignments = outermost_entry.cf_assignments
239 self.cf_references = outermost_entry.cf_references
240 self.overloaded_alternatives = outermost_entry.overloaded_alternatives
241 self.inner_entries.append(self)
243 def __getattr__(self, name):
244 if name.startswith('__'):
245 # we wouldn't have been called if it was there
246 raise AttributeError(name)
247 return getattr(self.defining_entry, name)
249 def all_entries(self):
250 return self.defining_entry.all_entries()
253 class Scope(object):
254 # name string Unqualified name
255 # outer_scope Scope or None Enclosing scope
256 # entries {string : Entry} Python name to entry, non-types
257 # const_entries [Entry] Constant entries
258 # type_entries [Entry] Struct/union/enum/typedef/exttype entries
259 # sue_entries [Entry] Struct/union/enum entries
260 # arg_entries [Entry] Function argument entries
261 # var_entries [Entry] User-defined variable entries
262 # pyfunc_entries [Entry] Python function entries
263 # cfunc_entries [Entry] C function entries
264 # c_class_entries [Entry] All extension type entries
265 # cname_to_entry {string : Entry} Temp cname to entry mapping
266 # return_type PyrexType or None Return type of function owning scope
267 # is_builtin_scope boolean Is the builtin scope of Python/Cython
268 # is_py_class_scope boolean Is a Python class scope
269 # is_c_class_scope boolean Is an extension type scope
270 # is_closure_scope boolean Is a closure scope
271 # is_passthrough boolean Outer scope is passed directly
272 # is_cpp_class_scope boolean Is a C++ class scope
273 # is_property_scope boolean Is a extension type property scope
274 # scope_prefix string Disambiguator for C names
275 # in_cinclude boolean Suppress C declaration code
276 # qualified_name string "modname" or "modname.classname"
277 # Python strings in this scope
278 # nogil boolean In a nogil section
279 # directives dict Helper variable for the recursive
280 # analysis, contains directive values.
281 # is_internal boolean Is only used internally (simpler setup)
283 is_builtin_scope = 0
284 is_py_class_scope = 0
285 is_c_class_scope = 0
286 is_closure_scope = 0
287 is_passthrough = 0
288 is_cpp_class_scope = 0
289 is_property_scope = 0
290 is_module_scope = 0
291 is_internal = 0
292 scope_prefix = ""
293 in_cinclude = 0
294 nogil = 0
295 fused_to_specific = None
297 def __init__(self, name, outer_scope, parent_scope):
298 # The outer_scope is the next scope in the lookup chain.
299 # The parent_scope is used to derive the qualified name of this scope.
300 self.name = name
301 self.outer_scope = outer_scope
302 self.parent_scope = parent_scope
303 mangled_name = "%d%s_" % (len(name), name)
304 qual_scope = self.qualifying_scope()
305 if qual_scope:
306 self.qualified_name = qual_scope.qualify_name(name)
307 self.scope_prefix = qual_scope.scope_prefix + mangled_name
308 else:
309 self.qualified_name = EncodedString(name)
310 self.scope_prefix = mangled_name
311 self.entries = {}
312 self.const_entries = []
313 self.type_entries = []
314 self.sue_entries = []
315 self.arg_entries = []
316 self.var_entries = []
317 self.pyfunc_entries = []
318 self.cfunc_entries = []
319 self.c_class_entries = []
320 self.defined_c_classes = []
321 self.imported_c_classes = {}
322 self.cname_to_entry = {}
323 self.string_to_entry = {}
324 self.identifier_to_entry = {}
325 self.num_to_entry = {}
326 self.obj_to_entry = {}
327 self.buffer_entries = []
328 self.lambda_defs = []
329 self.return_type = None
330 self.id_counters = {}
332 def __deepcopy__(self, memo):
333 return self
335 def merge_in(self, other, merge_unused=True, whitelist=None):
336 # Use with care...
337 entries = []
338 for name, entry in other.entries.iteritems():
339 if not whitelist or name in whitelist:
340 if entry.used or merge_unused:
341 entries.append((name, entry))
343 self.entries.update(entries)
345 for attr in ('const_entries',
346 'type_entries',
347 'sue_entries',
348 'arg_entries',
349 'var_entries',
350 'pyfunc_entries',
351 'cfunc_entries',
352 'c_class_entries'):
353 self_entries = getattr(self, attr)
354 names = set([e.name for e in self_entries])
355 for entry in getattr(other, attr):
356 if (entry.used or merge_unused) and entry.name not in names:
357 self_entries.append(entry)
359 def __str__(self):
360 return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
362 def qualifying_scope(self):
363 return self.parent_scope
365 def mangle(self, prefix, name = None):
366 if name:
367 return "%s%s%s" % (prefix, self.scope_prefix, name)
368 else:
369 return self.parent_scope.mangle(prefix, self.name)
371 def mangle_internal(self, name):
372 # Mangle an internal name so as not to clash with any
373 # user-defined name in this scope.
374 prefix = "%s%s_" % (Naming.pyrex_prefix, name)
375 return self.mangle(prefix)
376 #return self.parent_scope.mangle(prefix, self.name)
378 def mangle_class_private_name(self, name):
379 if self.parent_scope:
380 return self.parent_scope.mangle_class_private_name(name)
381 return name
383 def next_id(self, name=None):
384 # Return a cname fragment that is unique for this module
385 counters = self.global_scope().id_counters
386 try:
387 count = counters[name] + 1
388 except KeyError:
389 count = 0
390 counters[name] = count
391 if name:
392 if not count:
393 # unique names don't need a suffix, reoccurrences will get one
394 return name
395 return '%s%d' % (name, count)
396 else:
397 return '%d' % count
399 def global_scope(self):
400 """ Return the module-level scope containing this scope. """
401 return self.outer_scope.global_scope()
403 def builtin_scope(self):
404 """ Return the module-level scope containing this scope. """
405 return self.outer_scope.builtin_scope()
407 def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0):
408 # Create new entry, and add to dictionary if
409 # name is not None. Reports a warning if already
410 # declared.
411 if type.is_buffer and not isinstance(self, LocalScope): # and not is_type:
412 error(pos, 'Buffer types only allowed as function local variables')
413 if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
414 # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
415 warning(pos, "'%s' is a reserved name in C." % cname, -1)
416 entries = self.entries
417 if name and name in entries and not shadow:
418 if visibility == 'extern':
419 warning(pos, "'%s' redeclared " % name, 0)
420 elif visibility != 'ignore':
421 error(pos, "'%s' redeclared " % name)
422 entry = Entry(name, cname, type, pos = pos)
423 entry.in_cinclude = self.in_cinclude
424 if name:
425 entry.qualified_name = self.qualify_name(name)
426 # if name in entries and self.is_cpp():
427 # entries[name].overloaded_alternatives.append(entry)
428 # else:
429 # entries[name] = entry
430 if not shadow:
431 entries[name] = entry
433 if type.is_memoryviewslice:
434 import MemoryView
435 entry.init = MemoryView.memslice_entry_init
437 entry.scope = self
438 entry.visibility = visibility
439 return entry
441 def qualify_name(self, name):
442 return EncodedString("%s.%s" % (self.qualified_name, name))
444 def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0):
445 # Add an entry for a named constant.
446 if not cname:
447 if self.in_cinclude or (visibility == 'public' or api):
448 cname = name
449 else:
450 cname = self.mangle(Naming.enum_prefix, name)
451 entry = self.declare(name, cname, type, pos, visibility)
452 entry.is_const = 1
453 entry.value_node = value
454 return entry
456 def declare_type(self, name, type, pos,
457 cname = None, visibility = 'private', api = 0, defining = 1,
458 shadow = 0, template = 0):
459 # Add an entry for a type definition.
460 if not cname:
461 cname = name
462 entry = self.declare(name, cname, type, pos, visibility, shadow,
463 is_type=True)
464 entry.is_type = 1
465 entry.api = api
466 if defining:
467 self.type_entries.append(entry)
469 if not template:
470 type.entry = entry
472 # here we would set as_variable to an object representing this type
473 return entry
475 def declare_typedef(self, name, base_type, pos, cname = None,
476 visibility = 'private', api = 0):
477 if not cname:
478 if self.in_cinclude or (visibility == 'public' or api):
479 cname = name
480 else:
481 cname = self.mangle(Naming.type_prefix, name)
482 try:
483 type = PyrexTypes.create_typedef_type(name, base_type, cname,
484 (visibility == 'extern'))
485 except ValueError, e:
486 error(pos, e.args[0])
487 type = PyrexTypes.error_type
488 entry = self.declare_type(name, type, pos, cname,
489 visibility = visibility, api = api)
490 type.qualified_name = entry.qualified_name
491 return entry
493 def declare_struct_or_union(self, name, kind, scope,
494 typedef_flag, pos, cname = None,
495 visibility = 'private', api = 0,
496 packed = False):
497 # Add an entry for a struct or union definition.
498 if not cname:
499 if self.in_cinclude or (visibility == 'public' or api):
500 cname = name
501 else:
502 cname = self.mangle(Naming.type_prefix, name)
503 entry = self.lookup_here(name)
504 if not entry:
505 type = PyrexTypes.CStructOrUnionType(
506 name, kind, scope, typedef_flag, cname, packed)
507 entry = self.declare_type(name, type, pos, cname,
508 visibility = visibility, api = api,
509 defining = scope is not None)
510 self.sue_entries.append(entry)
511 type.entry = entry
512 else:
513 if not (entry.is_type and entry.type.is_struct_or_union
514 and entry.type.kind == kind):
515 warning(pos, "'%s' redeclared " % name, 0)
516 elif scope and entry.type.scope:
517 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
518 else:
519 self.check_previous_typedef_flag(entry, typedef_flag, pos)
520 self.check_previous_visibility(entry, visibility, pos)
521 if scope:
522 entry.type.scope = scope
523 self.type_entries.append(entry)
524 return entry
526 def declare_cpp_class(self, name, scope,
527 pos, cname = None, base_classes = (),
528 visibility = 'extern', templates = None):
529 if cname is None:
530 if self.in_cinclude or (visibility != 'private'):
531 cname = name
532 else:
533 cname = self.mangle(Naming.type_prefix, name)
534 base_classes = list(base_classes)
535 entry = self.lookup_here(name)
536 if not entry:
537 type = PyrexTypes.CppClassType(
538 name, scope, cname, base_classes, templates = templates)
539 entry = self.declare_type(name, type, pos, cname,
540 visibility = visibility, defining = scope is not None)
541 self.sue_entries.append(entry)
542 else:
543 if not (entry.is_type and entry.type.is_cpp_class):
544 error(pos, "'%s' redeclared " % name)
545 return None
546 elif scope and entry.type.scope:
547 warning(pos, "'%s' already defined (ignoring second definition)" % name, 0)
548 else:
549 if scope:
550 entry.type.scope = scope
551 self.type_entries.append(entry)
552 if base_classes:
553 if entry.type.base_classes and entry.type.base_classes != base_classes:
554 error(pos, "Base type does not match previous declaration")
555 else:
556 entry.type.base_classes = base_classes
557 if templates or entry.type.templates:
558 if templates != entry.type.templates:
559 error(pos, "Template parameters do not match previous declaration")
561 def declare_inherited_attributes(entry, base_classes):
562 for base_class in base_classes:
563 if base_class is PyrexTypes.error_type:
564 continue
565 if base_class.scope is None:
566 error(pos, "Cannot inherit from incomplete type")
567 else:
568 declare_inherited_attributes(entry, base_class.base_classes)
569 entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
570 if entry.type.scope:
571 declare_inherited_attributes(entry, base_classes)
572 entry.type.scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos)
573 if self.is_cpp_class_scope:
574 entry.type.namespace = self.outer_scope.lookup(self.name).type
575 return entry
577 def check_previous_typedef_flag(self, entry, typedef_flag, pos):
578 if typedef_flag != entry.type.typedef_flag:
579 error(pos, "'%s' previously declared using '%s'" % (
580 entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
582 def check_previous_visibility(self, entry, visibility, pos):
583 if entry.visibility != visibility:
584 error(pos, "'%s' previously declared as '%s'" % (
585 entry.name, entry.visibility))
587 def declare_enum(self, name, pos, cname, typedef_flag,
588 visibility = 'private', api = 0):
589 if name:
590 if not cname:
591 if self.in_cinclude or (visibility == 'public' or api):
592 cname = name
593 else:
594 cname = self.mangle(Naming.type_prefix, name)
595 type = PyrexTypes.CEnumType(name, cname, typedef_flag)
596 else:
597 type = PyrexTypes.c_anon_enum_type
598 entry = self.declare_type(name, type, pos, cname = cname,
599 visibility = visibility, api = api)
600 entry.enum_values = []
601 self.sue_entries.append(entry)
602 return entry
604 def declare_var(self, name, type, pos,
605 cname = None, visibility = 'private',
606 api = 0, in_pxd = 0, is_cdef = 0):
607 # Add an entry for a variable.
608 if not cname:
609 if visibility != 'private' or api:
610 cname = name
611 else:
612 cname = self.mangle(Naming.var_prefix, name)
613 if type.is_cpp_class and visibility != 'extern':
614 type.check_nullary_constructor(pos)
615 entry = self.declare(name, cname, type, pos, visibility)
616 entry.is_variable = 1
617 if in_pxd and visibility != 'extern':
618 entry.defined_in_pxd = 1
619 entry.used = 1
620 if api:
621 entry.api = 1
622 entry.used = 1
623 return entry
625 def declare_builtin(self, name, pos):
626 return self.outer_scope.declare_builtin(name, pos)
628 def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
629 if entry and not entry.type.is_cfunction:
630 error(pos, "'%s' already declared" % name)
631 error(entry.pos, "Previous declaration is here")
632 entry = self.declare_var(name, py_object_type, pos, visibility=visibility)
633 entry.signature = pyfunction_signature
634 self.pyfunc_entries.append(entry)
635 return entry
637 def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
638 # Add an entry for a Python function.
639 entry = self.lookup_here(name)
640 if not allow_redefine:
641 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
642 if entry:
643 if entry.type.is_unspecified:
644 entry.type = py_object_type
645 elif entry.type is not py_object_type:
646 return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
647 else: # declare entry stub
648 self.declare_var(name, py_object_type, pos, visibility=visibility)
649 entry = self.declare_var(None, py_object_type, pos,
650 cname=name, visibility='private')
651 entry.name = EncodedString(name)
652 entry.qualified_name = self.qualify_name(name)
653 entry.signature = pyfunction_signature
654 entry.is_anonymous = True
655 return entry
657 def declare_lambda_function(self, lambda_name, pos):
658 # Add an entry for an anonymous Python function.
659 func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
660 pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
661 qualified_name = self.qualify_name(lambda_name)
663 entry = self.declare(None, func_cname, py_object_type, pos, 'private')
664 entry.name = lambda_name
665 entry.qualified_name = qualified_name
666 entry.pymethdef_cname = pymethdef_cname
667 entry.func_cname = func_cname
668 entry.signature = pyfunction_signature
669 entry.is_anonymous = True
670 return entry
672 def add_lambda_def(self, def_node):
673 self.lambda_defs.append(def_node)
675 def register_pyfunction(self, entry):
676 self.pyfunc_entries.append(entry)
678 def declare_cfunction(self, name, type, pos,
679 cname = None, visibility = 'private', api = 0, in_pxd = 0,
680 defining = 0, modifiers = (), utility_code = None):
681 # Add an entry for a C function.
682 if not cname:
683 if visibility != 'private' or api:
684 cname = name
685 else:
686 cname = self.mangle(Naming.func_prefix, name)
687 entry = self.lookup_here(name)
688 if entry:
689 if visibility != 'private' and visibility != entry.visibility:
690 warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
691 if not entry.type.same_as(type):
692 if visibility == 'extern' and entry.visibility == 'extern':
693 can_override = False
694 if self.is_cpp():
695 can_override = True
696 elif cname:
697 # if all alternatives have different cnames,
698 # it's safe to allow signature overrides
699 for alt_entry in entry.all_alternatives():
700 if not alt_entry.cname or cname == alt_entry.cname:
701 break # cname not unique!
702 else:
703 can_override = True
704 if can_override:
705 temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
706 temp.overloaded_alternatives = entry.all_alternatives()
707 entry = temp
708 else:
709 warning(pos, "Function signature does not match previous declaration", 1)
710 entry.type = type
711 else:
712 error(pos, "Function signature does not match previous declaration")
713 else:
714 entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
715 entry.func_cname = cname
716 if in_pxd and visibility != 'extern':
717 entry.defined_in_pxd = 1
718 if api:
719 entry.api = 1
720 if not defining and not in_pxd and visibility != 'extern':
721 error(pos, "Non-extern C function '%s' declared but not defined" % name)
722 if defining:
723 entry.is_implemented = True
724 if modifiers:
725 entry.func_modifiers = modifiers
726 if utility_code:
727 assert not entry.utility_code, "duplicate utility code definition in entry %s (%s)" % (name, cname)
728 entry.utility_code = utility_code
729 type.entry = entry
730 return entry
732 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
733 # Add a C function entry without giving it a func_cname.
734 entry = self.declare(name, cname, type, pos, visibility)
735 entry.is_cfunction = 1
736 if modifiers:
737 entry.func_modifiers = modifiers
738 self.cfunc_entries.append(entry)
739 return entry
741 def find(self, name, pos):
742 # Look up name, report error if not found.
743 entry = self.lookup(name)
744 if entry:
745 return entry
746 else:
747 error(pos, "'%s' is not declared" % name)
749 def find_imported_module(self, path, pos):
750 # Look up qualified name, must be a module, report error if not found.
751 # Path is a list of names.
752 scope = self
753 for name in path:
754 entry = scope.find(name, pos)
755 if not entry:
756 return None
757 if entry.as_module:
758 scope = entry.as_module
759 else:
760 error(pos, "'%s' is not a cimported module" % '.'.join(path))
761 return None
762 return scope
764 def lookup(self, name):
765 # Look up name in this scope or an enclosing one.
766 # Return None if not found.
767 return (self.lookup_here(name)
768 or (self.outer_scope and self.outer_scope.lookup(name))
769 or None)
771 def lookup_here(self, name):
772 # Look up in this scope only, return None if not found.
773 return self.entries.get(name, None)
775 def lookup_target(self, name):
776 # Look up name in this scope only. Declare as Python
777 # variable if not found.
778 entry = self.lookup_here(name)
779 if not entry:
780 entry = self.declare_var(name, py_object_type, None)
781 return entry
783 def lookup_type(self, name):
784 entry = self.lookup(name)
785 if entry and entry.is_type:
786 if entry.type.is_fused and self.fused_to_specific:
787 return entry.type.specialize(self.fused_to_specific)
788 return entry.type
790 def lookup_operator(self, operator, operands):
791 if operands[0].type.is_cpp_class:
792 obj_type = operands[0].type
793 method = obj_type.scope.lookup("operator%s" % operator)
794 if method is not None:
795 res = PyrexTypes.best_match(operands[1:], method.all_alternatives())
796 if res is not None:
797 return res
798 function = self.lookup("operator%s" % operator)
799 if function is None:
800 return None
801 return PyrexTypes.best_match(operands, function.all_alternatives())
803 def lookup_operator_for_types(self, pos, operator, types):
804 from Nodes import Node
805 class FakeOperand(Node):
806 pass
807 operands = [FakeOperand(pos, type=type) for type in types]
808 return self.lookup_operator(operator, operands)
810 def use_utility_code(self, new_code):
811 self.global_scope().use_utility_code(new_code)
813 def generate_library_function_declarations(self, code):
814 # Generate extern decls for C library funcs used.
815 pass
817 def defines_any(self, names):
818 # Test whether any of the given names are
819 # defined in this scope.
820 for name in names:
821 if name in self.entries:
822 return 1
823 return 0
825 def infer_types(self):
826 from TypeInference import get_type_inferer
827 get_type_inferer().infer_types(self)
829 def is_cpp(self):
830 outer = self.outer_scope
831 if outer is None:
832 return False
833 else:
834 return outer.is_cpp()
836 def add_include_file(self, filename):
837 self.outer_scope.add_include_file(filename)
840 class PreImportScope(Scope):
842 namespace_cname = Naming.preimport_cname
844 def __init__(self):
845 Scope.__init__(self, Options.pre_import, None, None)
847 def declare_builtin(self, name, pos):
848 entry = self.declare(name, name, py_object_type, pos, 'private')
849 entry.is_variable = True
850 entry.is_pyglobal = True
851 return entry
854 class BuiltinScope(Scope):
855 # The builtin namespace.
857 is_builtin_scope = True
859 def __init__(self):
860 if Options.pre_import is None:
861 Scope.__init__(self, "__builtin__", None, None)
862 else:
863 Scope.__init__(self, "__builtin__", PreImportScope(), None)
864 self.type_names = {}
866 for name, definition in self.builtin_entries.iteritems():
867 cname, type = definition
868 self.declare_var(name, type, None, cname)
870 def lookup(self, name, language_level=None):
871 # 'language_level' is passed by ModuleScope
872 if language_level == 3:
873 if name == 'str':
874 name = 'unicode'
875 return Scope.lookup(self, name)
877 def declare_builtin(self, name, pos):
878 if not hasattr(builtins, name):
879 if self.outer_scope is not None:
880 return self.outer_scope.declare_builtin(name, pos)
881 else:
882 if Options.error_on_unknown_names:
883 error(pos, "undeclared name not builtin: %s" % name)
884 else:
885 warning(pos, "undeclared name not builtin: %s" % name, 2)
887 def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
888 utility_code = None):
889 # If python_equiv == "*", the Python equivalent has the same name
890 # as the entry, otherwise it has the name specified by python_equiv.
891 name = EncodedString(name)
892 entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
893 utility_code = utility_code)
894 if python_equiv:
895 if python_equiv == "*":
896 python_equiv = name
897 else:
898 python_equiv = EncodedString(python_equiv)
899 var_entry = Entry(python_equiv, python_equiv, py_object_type)
900 var_entry.is_variable = 1
901 var_entry.is_builtin = 1
902 var_entry.utility_code = utility_code
903 entry.as_variable = var_entry
904 return entry
906 def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None):
907 name = EncodedString(name)
908 type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname)
909 scope = CClassScope(name, outer_scope=None, visibility='extern')
910 scope.directives = {}
911 if name == 'bool':
912 type.is_final_type = True
913 type.set_scope(scope)
914 self.type_names[name] = 1
915 entry = self.declare_type(name, type, None, visibility='extern')
916 entry.utility_code = utility_code
918 var_entry = Entry(name = entry.name,
919 type = self.lookup('type').type, # make sure "type" is the first type declared...
920 pos = entry.pos,
921 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
922 var_entry.is_variable = 1
923 var_entry.is_cglobal = 1
924 var_entry.is_readonly = 1
925 var_entry.is_builtin = 1
926 var_entry.utility_code = utility_code
927 if Options.cache_builtins:
928 var_entry.is_const = True
929 entry.as_variable = var_entry
931 return type
933 def builtin_scope(self):
934 return self
936 builtin_entries = {
938 "type": ["((PyObject*)&PyType_Type)", py_object_type],
940 "bool": ["((PyObject*)&PyBool_Type)", py_object_type],
941 "int": ["((PyObject*)&PyInt_Type)", py_object_type],
942 "long": ["((PyObject*)&PyLong_Type)", py_object_type],
943 "float": ["((PyObject*)&PyFloat_Type)", py_object_type],
944 "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
946 "bytes": ["((PyObject*)&PyBytes_Type)", py_object_type],
947 "bytearray": ["((PyObject*)&PyByteArray_Type)", py_object_type],
948 "str": ["((PyObject*)&PyString_Type)", py_object_type],
949 "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
951 "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type],
952 "list": ["((PyObject*)&PyList_Type)", py_object_type],
953 "dict": ["((PyObject*)&PyDict_Type)", py_object_type],
954 "set": ["((PyObject*)&PySet_Type)", py_object_type],
955 "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
957 "slice": ["((PyObject*)&PySlice_Type)", py_object_type],
958 # "file": ["((PyObject*)&PyFile_Type)", py_object_type], # not in Py3
960 "None": ["Py_None", py_object_type],
961 "False": ["Py_False", py_object_type],
962 "True": ["Py_True", py_object_type],
965 const_counter = 1 # As a temporary solution for compiling code in pxds
967 class ModuleScope(Scope):
968 # module_name string Python name of the module
969 # module_cname string C name of Python module object
970 # #module_dict_cname string C name of module dict object
971 # method_table_cname string C name of method table
972 # doc string Module doc string
973 # doc_cname string C name of module doc string
974 # utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py
975 # python_include_files [string] Standard Python headers to be included
976 # include_files [string] Other C headers to be included
977 # string_to_entry {string : Entry} Map string const to entry
978 # identifier_to_entry {string : Entry} Map identifier string const to entry
979 # context Context
980 # parent_module Scope Parent in the import namespace
981 # module_entries {string : Entry} For cimport statements
982 # type_names {string : 1} Set of type names (used during parsing)
983 # included_files [string] Cython sources included with 'include'
984 # pxd_file_loaded boolean Corresponding .pxd file has been processed
985 # cimported_modules [ModuleScope] Modules imported with cimport
986 # types_imported {PyrexType} Set of types for which import code generated
987 # has_import_star boolean Module contains import *
988 # cpp boolean Compiling a C++ file
989 # is_cython_builtin boolean Is this the Cython builtin scope (or a child scope)
990 # is_package boolean Is this a package module? (__init__)
992 is_module_scope = 1
993 has_import_star = 0
994 is_cython_builtin = 0
996 def __init__(self, name, parent_module, context):
997 import Builtin
998 self.parent_module = parent_module
999 outer_scope = Builtin.builtin_scope
1000 Scope.__init__(self, name, outer_scope, parent_module)
1001 if name == "__init__":
1002 # Treat Spam/__init__.pyx specially, so that when Python loads
1003 # Spam/__init__.so, initSpam() is defined.
1004 self.module_name = parent_module.module_name
1005 self.is_package = True
1006 else:
1007 self.module_name = name
1008 self.is_package = False
1009 self.module_name = EncodedString(self.module_name)
1010 self.context = context
1011 self.module_cname = Naming.module_cname
1012 self.module_dict_cname = Naming.moddict_cname
1013 self.method_table_cname = Naming.methtable_cname
1014 self.doc = ""
1015 self.doc_cname = Naming.moddoc_cname
1016 self.utility_code_list = []
1017 self.module_entries = {}
1018 self.python_include_files = ["Python.h"]
1019 self.include_files = []
1020 self.type_names = dict(outer_scope.type_names)
1021 self.pxd_file_loaded = 0
1022 self.cimported_modules = []
1023 self.types_imported = set()
1024 self.included_files = []
1025 self.has_extern_class = 0
1026 self.cached_builtins = []
1027 self.undeclared_cached_builtins = []
1028 self.namespace_cname = self.module_cname
1029 for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__']:
1030 self.declare_var(EncodedString(var_name), py_object_type, None)
1032 def qualifying_scope(self):
1033 return self.parent_module
1035 def global_scope(self):
1036 return self
1038 def lookup(self, name):
1039 entry = self.lookup_here(name)
1040 if entry is not None:
1041 return entry
1043 if self.context is not None:
1044 language_level = self.context.language_level
1045 else:
1046 language_level = 3
1048 return self.outer_scope.lookup(name, language_level=language_level)
1050 def declare_builtin(self, name, pos):
1051 if not hasattr(builtins, name) \
1052 and name not in Code.non_portable_builtins_map \
1053 and name not in Code.uncachable_builtins:
1054 if self.has_import_star:
1055 entry = self.declare_var(name, py_object_type, pos)
1056 return entry
1057 else:
1058 if Options.error_on_unknown_names:
1059 error(pos, "undeclared name not builtin: %s" % name)
1060 else:
1061 warning(pos, "undeclared name not builtin: %s" % name, 2)
1062 # unknown - assume it's builtin and look it up at runtime
1063 entry = self.declare(name, None, py_object_type, pos, 'private')
1064 entry.is_builtin = 1
1065 return entry
1066 if Options.cache_builtins:
1067 for entry in self.cached_builtins:
1068 if entry.name == name:
1069 return entry
1070 entry = self.declare(None, None, py_object_type, pos, 'private')
1071 if Options.cache_builtins and name not in Code.uncachable_builtins:
1072 entry.is_builtin = 1
1073 entry.is_const = 1 # cached
1074 entry.name = name
1075 entry.cname = Naming.builtin_prefix + name
1076 self.cached_builtins.append(entry)
1077 self.undeclared_cached_builtins.append(entry)
1078 else:
1079 entry.is_builtin = 1
1080 entry.name = name
1081 return entry
1083 def find_module(self, module_name, pos):
1084 # Find a module in the import namespace, interpreting
1085 # relative imports relative to this module's parent.
1086 # Finds and parses the module's .pxd file if the module
1087 # has not been referenced before.
1088 return self.global_scope().context.find_module(
1089 module_name, relative_to = self.parent_module, pos = pos)
1091 def find_submodule(self, name):
1092 # Find and return scope for a submodule of this module,
1093 # creating a new empty one if necessary. Doesn't parse .pxd.
1094 scope = self.lookup_submodule(name)
1095 if not scope:
1096 scope = ModuleScope(name,
1097 parent_module = self, context = self.context)
1098 self.module_entries[name] = scope
1099 return scope
1101 def lookup_submodule(self, name):
1102 # Return scope for submodule of this module, or None.
1103 return self.module_entries.get(name, None)
1105 def add_include_file(self, filename):
1106 if filename not in self.python_include_files \
1107 and filename not in self.include_files:
1108 self.include_files.append(filename)
1110 def add_imported_module(self, scope):
1111 if scope not in self.cimported_modules:
1112 for filename in scope.include_files:
1113 self.add_include_file(filename)
1114 self.cimported_modules.append(scope)
1115 for m in scope.cimported_modules:
1116 self.add_imported_module(m)
1118 def add_imported_entry(self, name, entry, pos):
1119 if entry not in self.entries:
1120 self.entries[name] = entry
1121 else:
1122 warning(pos, "'%s' redeclared " % name, 0)
1124 def declare_module(self, name, scope, pos):
1125 # Declare a cimported module. This is represented as a
1126 # Python module-level variable entry with a module
1127 # scope attached to it. Reports an error and returns
1128 # None if previously declared as something else.
1129 entry = self.lookup_here(name)
1130 if entry:
1131 if entry.is_pyglobal and entry.as_module is scope:
1132 return entry # Already declared as the same module
1133 if not (entry.is_pyglobal and not entry.as_module):
1134 # SAGE -- I put this here so Pyrex
1135 # cimport's work across directories.
1136 # Currently it tries to multiply define
1137 # every module appearing in an import list.
1138 # It shouldn't be an error for a module
1139 # name to appear again, and indeed the generated
1140 # code compiles fine.
1141 return entry
1142 else:
1143 entry = self.declare_var(name, py_object_type, pos)
1144 entry.as_module = scope
1145 self.add_imported_module(scope)
1146 return entry
1148 def declare_var(self, name, type, pos,
1149 cname = None, visibility = 'private',
1150 api = 0, in_pxd = 0, is_cdef = 0):
1151 # Add an entry for a global variable. If it is a Python
1152 # object type, and not declared with cdef, it will live
1153 # in the module dictionary, otherwise it will be a C
1154 # global variable.
1155 if not visibility in ('private', 'public', 'extern'):
1156 error(pos, "Module-level variable cannot be declared %s" % visibility)
1157 if not is_cdef:
1158 if type is unspecified_type:
1159 type = py_object_type
1160 if not (type.is_pyobject and not type.is_extension_type):
1161 raise InternalError(
1162 "Non-cdef global variable is not a generic Python object")
1164 if not cname:
1165 defining = not in_pxd
1166 if visibility == 'extern' or (visibility == 'public' and defining):
1167 cname = name
1168 else:
1169 cname = self.mangle(Naming.var_prefix, name)
1171 entry = self.lookup_here(name)
1172 if entry and entry.defined_in_pxd:
1173 #if visibility != 'private' and visibility != entry.visibility:
1174 # warning(pos, "Variable '%s' previously declared as '%s'" % (name, entry.visibility), 1)
1175 if not entry.type.same_as(type):
1176 if visibility == 'extern' and entry.visibility == 'extern':
1177 warning(pos, "Variable '%s' type does not match previous declaration" % name, 1)
1178 entry.type = type
1179 #else:
1180 # error(pos, "Variable '%s' type does not match previous declaration" % name)
1181 if entry.visibility != "private":
1182 mangled_cname = self.mangle(Naming.var_prefix, name)
1183 if entry.cname == mangled_cname:
1184 cname = name
1185 entry.cname = name
1186 if not entry.is_implemented:
1187 entry.is_implemented = True
1188 return entry
1190 entry = Scope.declare_var(self, name, type, pos,
1191 cname=cname, visibility=visibility,
1192 api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1193 if is_cdef:
1194 entry.is_cglobal = 1
1195 if entry.type.is_pyobject:
1196 entry.init = 0
1197 self.var_entries.append(entry)
1198 else:
1199 entry.is_pyglobal = 1
1200 if Options.cimport_from_pyx:
1201 entry.used = 1
1202 return entry
1204 def declare_cfunction(self, name, type, pos,
1205 cname = None, visibility = 'private', api = 0, in_pxd = 0,
1206 defining = 0, modifiers = (), utility_code = None):
1207 # Add an entry for a C function.
1208 if not cname:
1209 if visibility == 'extern' or (visibility == 'public' and defining):
1210 cname = name
1211 else:
1212 cname = self.mangle(Naming.func_prefix, name)
1213 entry = self.lookup_here(name)
1214 if entry and entry.defined_in_pxd:
1215 if entry.visibility != "private":
1216 mangled_cname = self.mangle(Naming.var_prefix, name)
1217 if entry.cname == mangled_cname:
1218 cname = name
1219 entry.cname = cname
1220 entry.func_cname = cname
1221 entry = Scope.declare_cfunction(
1222 self, name, type, pos,
1223 cname = cname, visibility = visibility, api = api, in_pxd = in_pxd,
1224 defining = defining, modifiers = modifiers, utility_code = utility_code)
1225 return entry
1227 def declare_global(self, name, pos):
1228 entry = self.lookup_here(name)
1229 if not entry:
1230 self.declare_var(name, py_object_type, pos)
1232 def use_utility_code(self, new_code):
1233 if new_code is not None:
1234 self.utility_code_list.append(new_code)
1236 def declare_c_class(self, name, pos, defining = 0, implementing = 0,
1237 module_name = None, base_type = None, objstruct_cname = None,
1238 typeobj_cname = None, typeptr_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
1239 buffer_defaults = None, shadow = 0):
1240 # If this is a non-extern typedef class, expose the typedef, but use
1241 # the non-typedef struct internally to avoid needing forward
1242 # declarations for anonymous structs.
1243 if typedef_flag and visibility != 'extern':
1244 if not (visibility == 'public' or api):
1245 warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
1246 objtypedef_cname = objstruct_cname
1247 typedef_flag = 0
1248 else:
1249 objtypedef_cname = None
1251 # Look for previous declaration as a type
1253 entry = self.lookup_here(name)
1254 if entry and not shadow:
1255 type = entry.type
1256 if not (entry.is_type and type.is_extension_type):
1257 entry = None # Will cause redeclaration and produce an error
1258 else:
1259 scope = type.scope
1260 if typedef_flag and (not scope or scope.defined):
1261 self.check_previous_typedef_flag(entry, typedef_flag, pos)
1262 if (scope and scope.defined) or (base_type and type.base_type):
1263 if base_type and base_type is not type.base_type:
1264 error(pos, "Base type does not match previous declaration")
1265 if base_type and not type.base_type:
1266 type.base_type = base_type
1268 # Make a new entry if needed
1270 if not entry or shadow:
1271 type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
1272 type.pos = pos
1273 type.buffer_defaults = buffer_defaults
1274 if objtypedef_cname is not None:
1275 type.objtypedef_cname = objtypedef_cname
1276 if visibility == 'extern':
1277 type.module_name = module_name
1278 else:
1279 type.module_name = self.qualified_name
1280 if typeptr_cname:
1281 type.typeptr_cname = typeptr_cname
1282 else:
1283 type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1284 entry = self.declare_type(name, type, pos, visibility = visibility,
1285 defining = 0, shadow = shadow)
1286 entry.is_cclass = True
1287 if objstruct_cname:
1288 type.objstruct_cname = objstruct_cname
1289 elif not entry.in_cinclude:
1290 type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1291 else:
1292 error(entry.pos,
1293 "Object name required for 'public' or 'extern' C class")
1294 self.attach_var_entry_to_c_class(entry)
1295 self.c_class_entries.append(entry)
1297 # Check for re-definition and create scope if needed
1299 if not type.scope:
1300 if defining or implementing:
1301 scope = CClassScope(name = name, outer_scope = self,
1302 visibility = visibility)
1303 scope.directives = self.directives.copy()
1304 if base_type and base_type.scope:
1305 scope.declare_inherited_c_attributes(base_type.scope)
1306 type.set_scope(scope)
1307 self.type_entries.append(entry)
1308 else:
1309 if defining and type.scope.defined:
1310 error(pos, "C class '%s' already defined" % name)
1311 elif implementing and type.scope.implemented:
1312 error(pos, "C class '%s' already implemented" % name)
1314 # Fill in options, checking for compatibility with any previous declaration
1316 if defining:
1317 entry.defined_in_pxd = 1
1318 if implementing: # So that filenames in runtime exceptions refer to
1319 entry.pos = pos # the .pyx file and not the .pxd file
1320 if visibility != 'private' and entry.visibility != visibility:
1321 error(pos, "Class '%s' previously declared as '%s'"
1322 % (name, entry.visibility))
1323 if api:
1324 entry.api = 1
1325 if objstruct_cname:
1326 if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1327 error(pos, "Object struct name differs from previous declaration")
1328 type.objstruct_cname = objstruct_cname
1329 if typeobj_cname:
1330 if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1331 error(pos, "Type object name differs from previous declaration")
1332 type.typeobj_cname = typeobj_cname
1334 if self.directives.get('final'):
1335 entry.type.is_final_type = True
1337 # cdef classes are always exported, but we need to set it to
1338 # distinguish between unused Cython utility code extension classes
1339 entry.used = True
1342 # Return new or existing entry
1344 return entry
1346 def allocate_vtable_names(self, entry):
1347 # If extension type has a vtable, allocate vtable struct and
1348 # slot names for it.
1349 type = entry.type
1350 if type.base_type and type.base_type.vtabslot_cname:
1351 #print "...allocating vtabslot_cname because base type has one" ###
1352 type.vtabslot_cname = "%s.%s" % (
1353 Naming.obj_base_cname, type.base_type.vtabslot_cname)
1354 elif type.scope and type.scope.cfunc_entries:
1355 # one special case here: when inheriting from builtin
1356 # types, the methods may also be built-in, in which
1357 # case they won't need a vtable
1358 entry_count = len(type.scope.cfunc_entries)
1359 base_type = type.base_type
1360 while base_type:
1361 # FIXME: this will break if we ever get non-inherited C methods
1362 if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
1363 break
1364 if base_type.is_builtin_type:
1365 # builtin base type defines all methods => no vtable needed
1366 return
1367 base_type = base_type.base_type
1368 #print "...allocating vtabslot_cname because there are C methods" ###
1369 type.vtabslot_cname = Naming.vtabslot_cname
1370 if type.vtabslot_cname:
1371 #print "...allocating other vtable related cnames" ###
1372 type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1373 type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1375 def check_c_classes_pxd(self):
1376 # Performs post-analysis checking and finishing up of extension types
1377 # being implemented in this module. This is called only for the .pxd.
1379 # Checks all extension types declared in this scope to
1380 # make sure that:
1382 # * The extension type is fully declared
1384 # Also allocates a name for the vtable if needed.
1386 for entry in self.c_class_entries:
1387 # Check defined
1388 if not entry.type.scope:
1389 error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
1391 def check_c_class(self, entry):
1392 type = entry.type
1393 name = entry.name
1394 visibility = entry.visibility
1395 # Check defined
1396 if not type.scope:
1397 error(entry.pos, "C class '%s' is declared but not defined" % name)
1398 # Generate typeobj_cname
1399 if visibility != 'extern' and not type.typeobj_cname:
1400 type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1401 ## Generate typeptr_cname
1402 #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1403 # Check C methods defined
1404 if type.scope:
1405 for method_entry in type.scope.cfunc_entries:
1406 if not method_entry.is_inherited and not method_entry.func_cname:
1407 error(method_entry.pos, "C method '%s' is declared but not defined" %
1408 method_entry.name)
1409 # Allocate vtable name if necessary
1410 if type.vtabslot_cname:
1411 #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1412 type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1414 def check_c_classes(self):
1415 # Performs post-analysis checking and finishing up of extension types
1416 # being implemented in this module. This is called only for the main
1417 # .pyx file scope, not for cimported .pxd scopes.
1419 # Checks all extension types declared in this scope to
1420 # make sure that:
1422 # * The extension type is implemented
1423 # * All required object and type names have been specified or generated
1424 # * All non-inherited C methods are implemented
1426 # Also allocates a name for the vtable if needed.
1428 debug_check_c_classes = 0
1429 if debug_check_c_classes:
1430 print("Scope.check_c_classes: checking scope " + self.qualified_name)
1431 for entry in self.c_class_entries:
1432 if debug_check_c_classes:
1433 print("...entry %s %s" % (entry.name, entry))
1434 print("......type = ", entry.type)
1435 print("......visibility = ", entry.visibility)
1436 self.check_c_class(entry)
1438 def check_c_functions(self):
1439 # Performs post-analysis checking making sure all
1440 # defined c functions are actually implemented.
1441 for name, entry in self.entries.items():
1442 if entry.is_cfunction:
1443 if (entry.defined_in_pxd
1444 and entry.scope is self
1445 and entry.visibility != 'extern'
1446 and not entry.in_cinclude
1447 and not entry.is_implemented):
1448 error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1450 def attach_var_entry_to_c_class(self, entry):
1451 # The name of an extension class has to serve as both a type
1452 # name and a variable name holding the type object. It is
1453 # represented in the symbol table by a type entry with a
1454 # variable entry attached to it. For the variable entry,
1455 # we use a read-only C global variable whose name is an
1456 # expression that refers to the type object.
1457 import Builtin
1458 var_entry = Entry(name = entry.name,
1459 type = Builtin.type_type,
1460 pos = entry.pos,
1461 cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
1462 var_entry.is_variable = 1
1463 var_entry.is_cglobal = 1
1464 var_entry.is_readonly = 1
1465 entry.as_variable = var_entry
1467 def is_cpp(self):
1468 return self.cpp
1470 def infer_types(self):
1471 from TypeInference import PyObjectTypeInferer
1472 PyObjectTypeInferer().infer_types(self)
1475 class LocalScope(Scope):
1477 # Does the function have a 'with gil:' block?
1478 has_with_gil_block = False
1480 # Transient attribute, used for symbol table variable declarations
1481 _in_with_gil_block = False
1483 def __init__(self, name, outer_scope, parent_scope = None):
1484 if parent_scope is None:
1485 parent_scope = outer_scope
1486 Scope.__init__(self, name, outer_scope, parent_scope)
1488 def mangle(self, prefix, name):
1489 return prefix + name
1491 def declare_arg(self, name, type, pos):
1492 # Add an entry for an argument of a function.
1493 cname = self.mangle(Naming.var_prefix, name)
1494 entry = self.declare(name, cname, type, pos, 'private')
1495 entry.is_variable = 1
1496 if type.is_pyobject:
1497 entry.init = "0"
1498 entry.is_arg = 1
1499 #entry.borrowed = 1 # Not using borrowed arg refs for now
1500 self.arg_entries.append(entry)
1501 return entry
1503 def declare_var(self, name, type, pos,
1504 cname = None, visibility = 'private',
1505 api = 0, in_pxd = 0, is_cdef = 0):
1506 # Add an entry for a local variable.
1507 if visibility in ('public', 'readonly'):
1508 error(pos, "Local variable cannot be declared %s" % visibility)
1509 entry = Scope.declare_var(self, name, type, pos,
1510 cname=cname, visibility=visibility,
1511 api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1512 if type.is_pyobject:
1513 entry.init = "0"
1514 entry.is_local = 1
1516 entry.in_with_gil_block = self._in_with_gil_block
1517 self.var_entries.append(entry)
1518 return entry
1520 def declare_global(self, name, pos):
1521 # Pull entry from global scope into local scope.
1522 if self.lookup_here(name):
1523 warning(pos, "'%s' redeclared ", 0)
1524 else:
1525 entry = self.global_scope().lookup_target(name)
1526 self.entries[name] = entry
1528 def declare_nonlocal(self, name, pos):
1529 # Pull entry from outer scope into local scope
1530 orig_entry = self.lookup_here(name)
1531 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1532 error(pos, "'%s' redeclared as nonlocal" % name)
1533 else:
1534 entry = self.lookup(name)
1535 if entry is None or not entry.from_closure:
1536 error(pos, "no binding for nonlocal '%s' found" % name)
1538 def lookup(self, name):
1539 # Look up name in this scope or an enclosing one.
1540 # Return None if not found.
1541 entry = Scope.lookup(self, name)
1542 if entry is not None:
1543 if entry.scope is not self and entry.scope.is_closure_scope:
1544 if hasattr(entry.scope, "scope_class"):
1545 raise InternalError("lookup() after scope class created.")
1546 # The actual c fragment for the different scopes differs
1547 # on the outside and inside, so we make a new entry
1548 entry.in_closure = True
1549 inner_entry = InnerEntry(entry, self)
1550 inner_entry.is_variable = True
1551 self.entries[name] = inner_entry
1552 return inner_entry
1553 return entry
1555 def mangle_closure_cnames(self, outer_scope_cname):
1556 for entry in self.entries.values():
1557 if entry.from_closure:
1558 cname = entry.outer_entry.cname
1559 if self.is_passthrough:
1560 entry.cname = cname
1561 else:
1562 if cname.startswith(Naming.cur_scope_cname):
1563 cname = cname[len(Naming.cur_scope_cname)+2:]
1564 entry.cname = "%s->%s" % (outer_scope_cname, cname)
1565 elif entry.in_closure:
1566 entry.original_cname = entry.cname
1567 entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
1570 class GeneratorExpressionScope(Scope):
1571 """Scope for generator expressions and comprehensions. As opposed
1572 to generators, these can be easily inlined in some cases, so all
1573 we really need is a scope that holds the loop variable(s).
1575 def __init__(self, outer_scope):
1576 name = outer_scope.global_scope().next_id(Naming.genexpr_id_ref)
1577 Scope.__init__(self, name, outer_scope, outer_scope)
1578 self.directives = outer_scope.directives
1579 self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
1581 def mangle(self, prefix, name):
1582 return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
1584 def declare_var(self, name, type, pos,
1585 cname = None, visibility = 'private',
1586 api = 0, in_pxd = 0, is_cdef = True):
1587 if type is unspecified_type:
1588 # if the outer scope defines a type for this variable, inherit it
1589 outer_entry = self.outer_scope.lookup(name)
1590 if outer_entry and outer_entry.is_variable:
1591 type = outer_entry.type # may still be 'unspecified_type' !
1592 # the parent scope needs to generate code for the variable, but
1593 # this scope must hold its name exclusively
1594 cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id()))
1595 entry = self.declare(name, cname, type, pos, visibility)
1596 entry.is_variable = 1
1597 entry.is_local = 1
1598 self.var_entries.append(entry)
1599 self.entries[name] = entry
1600 return entry
1602 def declare_pyfunction(self, name, pos, allow_redefine=False):
1603 return self.outer_scope.declare_pyfunction(
1604 name, pos, allow_redefine)
1606 def declare_lambda_function(self, func_cname, pos):
1607 return self.outer_scope.declare_lambda_function(func_cname, pos)
1609 def add_lambda_def(self, def_node):
1610 return self.outer_scope.add_lambda_def(def_node)
1613 class ClosureScope(LocalScope):
1615 is_closure_scope = True
1617 def __init__(self, name, scope_name, outer_scope, parent_scope=None):
1618 LocalScope.__init__(self, name, outer_scope, parent_scope)
1619 self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name)
1621 # def mangle_closure_cnames(self, scope_var):
1622 # for entry in self.entries.values() + self.temp_entries:
1623 # entry.in_closure = 1
1624 # LocalScope.mangle_closure_cnames(self, scope_var)
1626 # def mangle(self, prefix, name):
1627 # return "%s->%s" % (self.cur_scope_cname, name)
1628 # return "%s->%s" % (self.closure_cname, name)
1630 def declare_pyfunction(self, name, pos, allow_redefine=False):
1631 return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private')
1634 class StructOrUnionScope(Scope):
1635 # Namespace of a C struct or union.
1637 def __init__(self, name="?"):
1638 Scope.__init__(self, name, None, None)
1640 def declare_var(self, name, type, pos,
1641 cname = None, visibility = 'private',
1642 api = 0, in_pxd = 0, is_cdef = 0,
1643 allow_pyobject = 0):
1644 # Add an entry for an attribute.
1645 if not cname:
1646 cname = name
1647 if visibility == 'private':
1648 cname = c_safe_identifier(cname)
1649 if type.is_cfunction:
1650 type = PyrexTypes.CPtrType(type)
1651 entry = self.declare(name, cname, type, pos, visibility)
1652 entry.is_variable = 1
1653 self.var_entries.append(entry)
1654 if type.is_pyobject and not allow_pyobject:
1655 error(pos,
1656 "C struct/union member cannot be a Python object")
1657 if visibility != 'private':
1658 error(pos,
1659 "C struct/union member cannot be declared %s" % visibility)
1660 return entry
1662 def declare_cfunction(self, name, type, pos,
1663 cname = None, visibility = 'private', api = 0, in_pxd = 0,
1664 defining = 0, modifiers = ()): # currently no utility code ...
1665 return self.declare_var(name, type, pos,
1666 cname=cname, visibility=visibility)
1669 class ClassScope(Scope):
1670 # Abstract base class for namespace of
1671 # Python class or extension type.
1673 # class_name string Python name of the class
1674 # scope_prefix string Additional prefix for names
1675 # declared in the class
1676 # doc string or None Doc string
1678 def __init__(self, name, outer_scope):
1679 Scope.__init__(self, name, outer_scope, outer_scope)
1680 self.class_name = name
1681 self.doc = None
1683 def lookup(self, name):
1684 entry = Scope.lookup(self, name)
1685 if entry:
1686 return entry
1687 if name == "classmethod":
1688 # We don't want to use the builtin classmethod here 'cause it won't do the
1689 # right thing in this scope (as the class members aren't still functions).
1690 # Don't want to add a cfunction to this scope 'cause that would mess with
1691 # the type definition, so we just return the right entry.
1692 entry = Entry(
1693 "classmethod",
1694 "__Pyx_Method_ClassMethod",
1695 PyrexTypes.CFuncType(
1696 py_object_type,
1697 [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1698 entry.utility_code_definition = Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c")
1699 entry.is_cfunction = 1
1700 return entry
1703 class PyClassScope(ClassScope):
1704 # Namespace of a Python class.
1706 # class_obj_cname string C variable holding class object
1708 is_py_class_scope = 1
1710 def mangle_class_private_name(self, name):
1711 return self.mangle_special_name(name)
1713 def mangle_special_name(self, name):
1714 if name and name.startswith('__') and not name.endswith('__'):
1715 name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name))
1716 return name
1718 def lookup_here(self, name):
1719 name = self.mangle_special_name(name)
1720 return ClassScope.lookup_here(self, name)
1722 def declare_var(self, name, type, pos,
1723 cname = None, visibility = 'private',
1724 api = 0, in_pxd = 0, is_cdef = 0):
1725 name = self.mangle_special_name(name)
1726 if type is unspecified_type:
1727 type = py_object_type
1728 # Add an entry for a class attribute.
1729 entry = Scope.declare_var(self, name, type, pos,
1730 cname=cname, visibility=visibility,
1731 api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1732 entry.is_pyglobal = 1
1733 entry.is_pyclass_attr = 1
1734 return entry
1736 def declare_nonlocal(self, name, pos):
1737 # Pull entry from outer scope into local scope
1738 orig_entry = self.lookup_here(name)
1739 if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1740 error(pos, "'%s' redeclared as nonlocal" % name)
1741 else:
1742 entry = self.lookup(name)
1743 if entry is None:
1744 error(pos, "no binding for nonlocal '%s' found" % name)
1745 else:
1746 # FIXME: this works, but it's unclear if it's the
1747 # right thing to do
1748 self.entries[name] = entry
1750 def declare_global(self, name, pos):
1751 # Pull entry from global scope into local scope.
1752 if self.lookup_here(name):
1753 warning(pos, "'%s' redeclared ", 0)
1754 else:
1755 entry = self.global_scope().lookup_target(name)
1756 self.entries[name] = entry
1758 def add_default_value(self, type):
1759 return self.outer_scope.add_default_value(type)
1762 class CClassScope(ClassScope):
1763 # Namespace of an extension type.
1765 # parent_type CClassType
1766 # #typeobj_cname string or None
1767 # #objstruct_cname string
1768 # method_table_cname string
1769 # getset_table_cname string
1770 # has_pyobject_attrs boolean Any PyObject attributes?
1771 # has_memoryview_attrs boolean Any memory view attributes?
1772 # has_cyclic_pyobject_attrs boolean Any PyObject attributes that may need GC?
1773 # property_entries [Entry]
1774 # defined boolean Defined in .pxd file
1775 # implemented boolean Defined in .pyx file
1776 # inherited_var_entries [Entry] Adapted var entries from base class
1778 is_c_class_scope = 1
1780 has_pyobject_attrs = False
1781 has_memoryview_attrs = False
1782 has_cyclic_pyobject_attrs = False
1783 defined = False
1784 implemented = False
1786 def __init__(self, name, outer_scope, visibility):
1787 ClassScope.__init__(self, name, outer_scope)
1788 if visibility != 'extern':
1789 self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1790 self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1791 self.property_entries = []
1792 self.inherited_var_entries = []
1794 def needs_gc(self):
1795 # If the type or any of its base types have Python-valued
1796 # C attributes, then it needs to participate in GC.
1797 if self.has_cyclic_pyobject_attrs:
1798 return True
1799 base_type = self.parent_type.base_type
1800 if base_type and base_type.scope is not None:
1801 return base_type.scope.needs_gc()
1802 elif self.parent_type.is_builtin_type:
1803 return not self.parent_type.is_gc_simple
1804 return False
1806 def needs_tp_clear(self):
1808 Do we need to generate an implementation for the tp_clear slot? Can
1809 be disabled to keep references for the __dealloc__ cleanup function.
1811 return self.needs_gc() and not self.directives.get('no_gc_clear', False)
1813 def get_refcounted_entries(self, include_weakref=False,
1814 include_gc_simple=True):
1815 py_attrs = []
1816 py_buffers = []
1817 memoryview_slices = []
1819 for entry in self.var_entries:
1820 if entry.type.is_pyobject:
1821 if include_weakref or entry.name != "__weakref__":
1822 if include_gc_simple or not entry.type.is_gc_simple:
1823 py_attrs.append(entry)
1824 elif entry.type == PyrexTypes.c_py_buffer_type:
1825 py_buffers.append(entry)
1826 elif entry.type.is_memoryviewslice:
1827 memoryview_slices.append(entry)
1829 have_entries = py_attrs or py_buffers or memoryview_slices
1830 return have_entries, (py_attrs, py_buffers, memoryview_slices)
1832 def declare_var(self, name, type, pos,
1833 cname = None, visibility = 'private',
1834 api = 0, in_pxd = 0, is_cdef = 0):
1835 if is_cdef:
1836 # Add an entry for an attribute.
1837 if self.defined:
1838 error(pos,
1839 "C attributes cannot be added in implementation part of"
1840 " extension type defined in a pxd")
1841 if get_special_method_signature(name):
1842 error(pos,
1843 "The name '%s' is reserved for a special method."
1844 % name)
1845 if not cname:
1846 cname = name
1847 if visibility == 'private':
1848 cname = c_safe_identifier(cname)
1849 if type.is_cpp_class and visibility != 'extern':
1850 type.check_nullary_constructor(pos)
1851 self.use_utility_code(Code.UtilityCode("#include <new>"))
1852 entry = self.declare(name, cname, type, pos, visibility)
1853 entry.is_variable = 1
1854 self.var_entries.append(entry)
1855 if type.is_memoryviewslice:
1856 self.has_memoryview_attrs = True
1857 elif type.is_pyobject and name != '__weakref__':
1858 self.has_pyobject_attrs = True
1859 if (not type.is_builtin_type
1860 or not type.scope or type.scope.needs_gc()):
1861 self.has_cyclic_pyobject_attrs = True
1862 if visibility not in ('private', 'public', 'readonly'):
1863 error(pos,
1864 "Attribute of extension type cannot be declared %s" % visibility)
1865 if visibility in ('public', 'readonly'):
1866 # If the field is an external typedef, we cannot be sure about the type,
1867 # so do conversion ourself rather than rely on the CPython mechanism (through
1868 # a property; made in AnalyseDeclarationsTransform).
1869 entry.needs_property = True
1870 if name == "__weakref__":
1871 error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1872 if not type.is_pyobject:
1873 if (not type.create_to_py_utility_code(self) or
1874 (visibility=='public' and not
1875 type.create_from_py_utility_code(self))):
1876 error(pos,
1877 "C attribute of type '%s' cannot be accessed from Python" % type)
1878 else:
1879 entry.needs_property = False
1880 return entry
1881 else:
1882 if type is unspecified_type:
1883 type = py_object_type
1884 # Add an entry for a class attribute.
1885 entry = Scope.declare_var(self, name, type, pos,
1886 cname=cname, visibility=visibility,
1887 api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1888 entry.is_member = 1
1889 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1890 # I keep it in for now. is_member should be enough
1891 # later on
1892 self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1893 return entry
1895 def declare_pyfunction(self, name, pos, allow_redefine=False):
1896 # Add an entry for a method.
1897 if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1898 error(pos, "Special method %s must be implemented via __richcmp__" % name)
1899 if name == "__new__":
1900 error(pos, "__new__ method of extension type will change semantics "
1901 "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1902 entry = self.declare_var(name, py_object_type, pos,
1903 visibility='extern')
1904 special_sig = get_special_method_signature(name)
1905 if special_sig:
1906 # Special methods get put in the method table with a particular
1907 # signature declared in advance.
1908 entry.signature = special_sig
1909 entry.is_special = 1
1910 else:
1911 entry.signature = pymethod_signature
1912 entry.is_special = 0
1914 self.pyfunc_entries.append(entry)
1915 return entry
1917 def lookup_here(self, name):
1918 if name == "__new__":
1919 name = EncodedString("__cinit__")
1920 entry = ClassScope.lookup_here(self, name)
1921 if entry and entry.is_builtin_cmethod:
1922 if not self.parent_type.is_builtin_type:
1923 # For subtypes of builtin types, we can only return
1924 # optimised C methods if the type if final.
1925 # Otherwise, subtypes may choose to override the
1926 # method, but the optimisation would prevent the
1927 # subtype method from being called.
1928 if not self.parent_type.is_final_type:
1929 return None
1930 return entry
1932 def declare_cfunction(self, name, type, pos,
1933 cname = None, visibility = 'private', api = 0, in_pxd = 0,
1934 defining = 0, modifiers = (), utility_code = None):
1935 if get_special_method_signature(name) and not self.parent_type.is_builtin_type:
1936 error(pos, "Special methods must be declared with 'def', not 'cdef'")
1937 args = type.args
1938 if not args:
1939 error(pos, "C method has no self argument")
1940 elif not self.parent_type.assignable_from(args[0].type):
1941 error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
1942 (args[0].type, name, self.parent_type))
1943 entry = self.lookup_here(name)
1944 if cname is None:
1945 cname = c_safe_identifier(name)
1946 if entry:
1947 if not entry.is_cfunction:
1948 warning(pos, "'%s' redeclared " % name, 0)
1949 else:
1950 if defining and entry.func_cname:
1951 error(pos, "'%s' already defined" % name)
1952 #print "CClassScope.declare_cfunction: checking signature" ###
1953 if entry.is_final_cmethod and entry.is_inherited:
1954 error(pos, "Overriding final methods is not allowed")
1955 elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1956 pass
1957 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1958 entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers)
1959 defining = 1
1960 else:
1961 error(pos, "Signature not compatible with previous declaration")
1962 error(entry.pos, "Previous declaration is here")
1963 else:
1964 if self.defined:
1965 error(pos,
1966 "C method '%s' not previously declared in definition part of"
1967 " extension type" % name)
1968 entry = self.add_cfunction(name, type, pos, cname,
1969 visibility, modifiers)
1970 if defining:
1971 entry.func_cname = self.mangle(Naming.func_prefix, name)
1972 entry.utility_code = utility_code
1973 type.entry = entry
1975 if u'inline' in modifiers:
1976 entry.is_inline_cmethod = True
1978 if (self.parent_type.is_final_type or entry.is_inline_cmethod or
1979 self.directives.get('final')):
1980 entry.is_final_cmethod = True
1981 entry.final_func_cname = entry.func_cname
1983 return entry
1985 def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
1986 # Add a cfunction entry without giving it a func_cname.
1987 prev_entry = self.lookup_here(name)
1988 entry = ClassScope.add_cfunction(self, name, type, pos, cname,
1989 visibility, modifiers)
1990 entry.is_cmethod = 1
1991 entry.prev_entry = prev_entry
1992 return entry
1994 def declare_builtin_cfunction(self, name, type, cname, utility_code = None):
1995 # overridden methods of builtin types still have their Python
1996 # equivalent that must be accessible to support bound methods
1997 name = EncodedString(name)
1998 entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
1999 utility_code = utility_code)
2000 var_entry = Entry(name, name, py_object_type)
2001 var_entry.is_variable = 1
2002 var_entry.is_builtin = 1
2003 var_entry.utility_code = utility_code
2004 entry.as_variable = var_entry
2005 return entry
2007 def declare_property(self, name, doc, pos):
2008 entry = self.lookup_here(name)
2009 if entry is None:
2010 entry = self.declare(name, name, py_object_type, pos, 'private')
2011 entry.is_property = 1
2012 entry.doc = doc
2013 entry.scope = PropertyScope(name,
2014 outer_scope = self.global_scope(), parent_scope = self)
2015 entry.scope.parent_type = self.parent_type
2016 self.property_entries.append(entry)
2017 return entry
2019 def declare_inherited_c_attributes(self, base_scope):
2020 # Declare entries for all the C attributes of an
2021 # inherited type, with cnames modified appropriately
2022 # to work with this type.
2023 def adapt(cname):
2024 return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
2026 entries = base_scope.inherited_var_entries + base_scope.var_entries
2027 for base_entry in entries:
2028 entry = self.declare(
2029 base_entry.name, adapt(base_entry.cname),
2030 base_entry.type, None, 'private')
2031 entry.is_variable = 1
2032 self.inherited_var_entries.append(entry)
2034 # If the class defined in a pxd, specific entries have not been added.
2035 # Ensure now that the parent (base) scope has specific entries
2036 # Iterate over a copy as get_all_specialized_function_types() will mutate
2037 for base_entry in base_scope.cfunc_entries[:]:
2038 if base_entry.type.is_fused:
2039 base_entry.type.get_all_specialized_function_types()
2041 for base_entry in base_scope.cfunc_entries:
2042 cname = base_entry.cname
2043 var_entry = base_entry.as_variable
2044 is_builtin = var_entry and var_entry.is_builtin
2045 if not is_builtin:
2046 cname = adapt(cname)
2047 entry = self.add_cfunction(base_entry.name, base_entry.type,
2048 base_entry.pos, cname,
2049 base_entry.visibility, base_entry.func_modifiers)
2050 entry.is_inherited = 1
2051 if base_entry.is_final_cmethod:
2052 entry.is_final_cmethod = True
2053 entry.is_inline_cmethod = base_entry.is_inline_cmethod
2054 if (self.parent_scope == base_scope.parent_scope or
2055 entry.is_inline_cmethod):
2056 entry.final_func_cname = base_entry.final_func_cname
2057 if is_builtin:
2058 entry.is_builtin_cmethod = True
2059 entry.as_variable = var_entry
2060 if base_entry.utility_code:
2061 entry.utility_code = base_entry.utility_code
2064 class CppClassScope(Scope):
2065 # Namespace of a C++ class.
2067 is_cpp_class_scope = 1
2069 default_constructor = None
2070 type = None
2072 def __init__(self, name, outer_scope, templates=None):
2073 Scope.__init__(self, name, outer_scope, None)
2074 self.directives = outer_scope.directives
2075 self.inherited_var_entries = []
2076 if templates is not None:
2077 for T in templates:
2078 template_entry = self.declare(
2079 T, T, PyrexTypes.TemplatePlaceholderType(T), None, 'extern')
2080 template_entry.is_type = 1
2082 def declare_var(self, name, type, pos,
2083 cname = None, visibility = 'extern',
2084 api = 0, in_pxd = 0, is_cdef = 0,
2085 allow_pyobject = 0, defining = 0):
2086 # Add an entry for an attribute.
2087 if not cname:
2088 cname = name
2089 entry = self.lookup_here(name)
2090 if defining and entry is not None:
2091 if not entry.type.same_as(type):
2092 error(pos, "Function signature does not match previous declaration")
2093 else:
2094 entry = self.declare(name, cname, type, pos, visibility)
2095 entry.is_variable = 1
2096 if type.is_cfunction and self.type:
2097 entry.func_cname = "%s::%s" % (self.type.declaration_code(""), cname)
2098 if name != "this" and (defining or name != "<init>"):
2099 self.var_entries.append(entry)
2100 if type.is_pyobject and not allow_pyobject:
2101 error(pos,
2102 "C++ class member cannot be a Python object")
2103 return entry
2105 def check_base_default_constructor(self, pos):
2106 # Look for default constructors in all base classes.
2107 if self.default_constructor is None:
2108 entry = self.lookup(self.name)
2109 if not entry.type.base_classes:
2110 self.default_constructor = True
2111 return
2112 for base_class in entry.type.base_classes:
2113 if base_class is PyrexTypes.error_type:
2114 continue
2115 temp_entry = base_class.scope.lookup_here("<init>")
2116 found = False
2117 if temp_entry is None:
2118 continue
2119 for alternative in temp_entry.all_alternatives():
2120 type = alternative.type
2121 if type.is_ptr:
2122 type = type.base_type
2123 if not type.args:
2124 found = True
2125 break
2126 if not found:
2127 self.default_constructor = temp_entry.scope.name
2128 error(pos, "no matching function for call to " \
2129 "%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name))
2130 elif not self.default_constructor:
2131 error(pos, "no matching function for call to %s::%s()" %
2132 (self.default_constructor, self.default_constructor))
2134 def declare_cfunction(self, name, type, pos,
2135 cname = None, visibility = 'extern', api = 0, in_pxd = 0,
2136 defining = 0, modifiers = (), utility_code = None):
2137 if name in (self.name.split('::')[-1], '__init__') and cname is None:
2138 self.check_base_default_constructor(pos)
2139 cname = self.type.cname
2140 name = '<init>'
2141 type.return_type = PyrexTypes.InvisibleVoidType()
2142 elif name == '__dealloc__' and cname is None:
2143 cname = "~%s" % self.type.cname
2144 name = '<del>'
2145 type.return_type = PyrexTypes.InvisibleVoidType()
2146 prev_entry = self.lookup_here(name)
2147 entry = self.declare_var(name, type, pos,
2148 defining=defining,
2149 cname=cname, visibility=visibility)
2150 if prev_entry and not defining:
2151 entry.overloaded_alternatives = prev_entry.all_alternatives()
2152 entry.utility_code = utility_code
2153 type.entry = entry
2154 return entry
2156 def declare_inherited_cpp_attributes(self, base_scope):
2157 # Declare entries for all the C++ attributes of an
2158 # inherited type, with cnames modified appropriately
2159 # to work with this type.
2160 for base_entry in \
2161 base_scope.inherited_var_entries + base_scope.var_entries:
2162 #contructor is not inherited
2163 if base_entry.name == "<init>":
2164 continue
2165 #print base_entry.name, self.entries
2166 if base_entry.name in self.entries:
2167 base_entry.name # FIXME: is there anything to do in this case?
2168 entry = self.declare(base_entry.name, base_entry.cname,
2169 base_entry.type, None, 'extern')
2170 entry.is_variable = 1
2171 self.inherited_var_entries.append(entry)
2172 for base_entry in base_scope.cfunc_entries:
2173 entry = self.declare_cfunction(base_entry.name, base_entry.type,
2174 base_entry.pos, base_entry.cname,
2175 base_entry.visibility, 0,
2176 modifiers = base_entry.func_modifiers,
2177 utility_code = base_entry.utility_code)
2178 entry.is_inherited = 1
2180 def specialize(self, values):
2181 scope = CppClassScope(self.name, self.outer_scope)
2182 for entry in self.entries.values():
2183 if entry.is_type:
2184 scope.declare_type(entry.name,
2185 entry.type.specialize(values),
2186 entry.pos,
2187 entry.cname,
2188 template=1)
2189 elif entry.type.is_cfunction:
2190 for e in entry.all_alternatives():
2191 scope.declare_cfunction(e.name,
2192 e.type.specialize(values),
2193 e.pos,
2194 e.cname,
2195 utility_code = e.utility_code)
2196 else:
2197 scope.declare_var(entry.name,
2198 entry.type.specialize(values),
2199 entry.pos,
2200 entry.cname,
2201 entry.visibility)
2203 return scope
2206 class PropertyScope(Scope):
2207 # Scope holding the __get__, __set__ and __del__ methods for
2208 # a property of an extension type.
2210 # parent_type PyExtensionType The type to which the property belongs
2212 is_property_scope = 1
2214 def declare_pyfunction(self, name, pos, allow_redefine=False):
2215 # Add an entry for a method.
2216 signature = get_property_accessor_signature(name)
2217 if signature:
2218 entry = self.declare(name, name, py_object_type, pos, 'private')
2219 entry.is_special = 1
2220 entry.signature = signature
2221 return entry
2222 else:
2223 error(pos, "Only __get__, __set__ and __del__ methods allowed "
2224 "in a property declaration")
2225 return None
2228 class CConstScope(Scope):
2230 def __init__(self, const_base_type_scope):
2231 Scope.__init__(
2232 self,
2233 'const_' + const_base_type_scope.name,
2234 const_base_type_scope.outer_scope,
2235 const_base_type_scope.parent_scope)
2236 self.const_base_type_scope = const_base_type_scope
2238 def lookup_here(self, name):
2239 entry = self.const_base_type_scope.lookup_here(name)
2240 if entry is not None:
2241 entry = copy.copy(entry)
2242 entry.type = PyrexTypes.c_const_type(entry.type)
2243 return entry
2245 class TemplateScope(Scope):
2246 def __init__(self, name, outer_scope):
2247 Scope.__init__(self, name, outer_scope, None)
2248 self.directives = outer_scope.directives