7 from Errors
import warning
, error
, InternalError
8 from StringEncoding
import EncodedString
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
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',
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
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
43 return "<BufferAux %r>" % self
.__dict
__
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
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
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
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
130 visibility
= 'private'
139 is_builtin_cmethod
= False
140 is_unbound_cmethod
= 0
142 is_inline_cmethod
= 0
157 is_declared_generic
= 0
162 final_func_cname
= None
169 pystring_cname
= None
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
192 def __init__(self
, name
, cname
, type, pos
= None, init
= None):
198 self
.overloaded_alternatives
= []
199 self
.cf_assignments
= []
200 self
.cf_references
= []
201 self
.inner_entries
= []
202 self
.defining_entry
= 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.
224 def __init__(self
, outer_entry
, scope
):
225 Entry
.__init
__(self
, outer_entry
.name
,
229 self
.outer_entry
= outer_entry
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()
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)
284 is_py_class_scope
= 0
288 is_cpp_class_scope
= 0
289 is_property_scope
= 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.
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()
306 self
.qualified_name
= qual_scope
.qualify_name(name
)
307 self
.scope_prefix
= qual_scope
.scope_prefix
+ mangled_name
309 self
.qualified_name
= EncodedString(name
)
310 self
.scope_prefix
= mangled_name
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
):
335 def merge_in(self
, other
, merge_unused
=True, whitelist
=None):
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',
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
)
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):
367 return "%s%s%s" % (prefix
, self
.scope_prefix
, name
)
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
)
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
387 count
= counters
[name
] + 1
390 counters
[name
] = count
393 # unique names don't need a suffix, reoccurrences will get one
395 return '%s%d' % (name
, 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
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
425 entry
.qualified_name
= self
.qualify_name(name
)
426 # if name in entries and self.is_cpp():
427 # entries[name].overloaded_alternatives.append(entry)
429 # entries[name] = entry
431 entries
[name
] = entry
433 if type.is_memoryviewslice
:
435 entry
.init
= MemoryView
.memslice_entry_init
438 entry
.visibility
= visibility
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.
447 if self
.in_cinclude
or (visibility
== 'public' or api
):
450 cname
= self
.mangle(Naming
.enum_prefix
, name
)
451 entry
= self
.declare(name
, cname
, type, pos
, visibility
)
453 entry
.value_node
= value
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.
462 entry
= self
.declare(name
, cname
, type, pos
, visibility
, shadow
,
467 self
.type_entries
.append(entry
)
472 # here we would set as_variable to an object representing this type
475 def declare_typedef(self
, name
, base_type
, pos
, cname
= None,
476 visibility
= 'private', api
= 0):
478 if self
.in_cinclude
or (visibility
== 'public' or api
):
481 cname
= self
.mangle(Naming
.type_prefix
, name
)
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
493 def declare_struct_or_union(self
, name
, kind
, scope
,
494 typedef_flag
, pos
, cname
= None,
495 visibility
= 'private', api
= 0,
497 # Add an entry for a struct or union definition.
499 if self
.in_cinclude
or (visibility
== 'public' or api
):
502 cname
= self
.mangle(Naming
.type_prefix
, name
)
503 entry
= self
.lookup_here(name
)
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
)
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)
519 self
.check_previous_typedef_flag(entry
, typedef_flag
, pos
)
520 self
.check_previous_visibility(entry
, visibility
, pos
)
522 entry
.type.scope
= scope
523 self
.type_entries
.append(entry
)
526 def declare_cpp_class(self
, name
, scope
,
527 pos
, cname
= None, base_classes
= (),
528 visibility
= 'extern', templates
= None):
530 if self
.in_cinclude
or (visibility
!= 'private'):
533 cname
= self
.mangle(Naming
.type_prefix
, name
)
534 base_classes
= list(base_classes
)
535 entry
= self
.lookup_here(name
)
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
)
543 if not (entry
.is_type
and entry
.type.is_cpp_class
):
544 error(pos
, "'%s' redeclared " % name
)
546 elif scope
and entry
.type.scope
:
547 warning(pos
, "'%s' already defined (ignoring second definition)" % name
, 0)
550 entry
.type.scope
= scope
551 self
.type_entries
.append(entry
)
553 if entry
.type.base_classes
and entry
.type.base_classes
!= base_classes
:
554 error(pos
, "Base type does not match previous declaration")
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
:
565 if base_class
.scope
is None:
566 error(pos
, "Cannot inherit from incomplete type")
568 declare_inherited_attributes(entry
, base_class
.base_classes
)
569 entry
.type.scope
.declare_inherited_cpp_attributes(base_class
.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
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):
591 if self
.in_cinclude
or (visibility
== 'public' or api
):
594 cname
= self
.mangle(Naming
.type_prefix
, name
)
595 type = PyrexTypes
.CEnumType(name
, cname
, typedef_flag
)
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
)
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.
609 if visibility
!= 'private' or api
:
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
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
)
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
)
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
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
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.
683 if visibility
!= 'private' or api
:
686 cname
= self
.mangle(Naming
.func_prefix
, name
)
687 entry
= self
.lookup_here(name
)
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':
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!
705 temp
= self
.add_cfunction(name
, type, pos
, cname
, visibility
, modifiers
)
706 temp
.overloaded_alternatives
= entry
.all_alternatives()
709 warning(pos
, "Function signature does not match previous declaration", 1)
712 error(pos
, "Function signature does not match previous declaration")
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
720 if not defining
and not in_pxd
and visibility
!= 'extern':
721 error(pos
, "Non-extern C function '%s' declared but not defined" % name
)
723 entry
.is_implemented
= True
725 entry
.func_modifiers
= modifiers
727 assert not entry
.utility_code
, "duplicate utility code definition in entry %s (%s)" % (name
, cname
)
728 entry
.utility_code
= utility_code
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
737 entry
.func_modifiers
= modifiers
738 self
.cfunc_entries
.append(entry
)
741 def find(self
, name
, pos
):
742 # Look up name, report error if not found.
743 entry
= self
.lookup(name
)
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.
754 entry
= scope
.find(name
, pos
)
758 scope
= entry
.as_module
760 error(pos
, "'%s' is not a cimported module" % '.'.join(path
))
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
))
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
)
780 entry
= self
.declare_var(name
, py_object_type
, None)
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
)
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())
798 function
= self
.lookup("operator%s" % operator
)
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
):
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.
817 def defines_any(self
, names
):
818 # Test whether any of the given names are
819 # defined in this scope.
821 if name
in self
.entries
:
825 def infer_types(self
):
826 from TypeInference
import get_type_inferer
827 get_type_inferer().infer_types(self
)
830 outer
= self
.outer_scope
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
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
854 class BuiltinScope(Scope
):
855 # The builtin namespace.
857 is_builtin_scope
= True
860 if Options
.pre_import
is None:
861 Scope
.__init
__(self
, "__builtin__", None, None)
863 Scope
.__init
__(self
, "__builtin__", PreImportScope(), None)
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:
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
)
882 if Options
.error_on_unknown_names
:
883 error(pos
, "undeclared name not builtin: %s" % name
)
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
)
895 if python_equiv
== "*":
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
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
= {}
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...
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
933 def builtin_scope(self
):
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
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__)
994 is_cython_builtin
= 0
996 def __init__(self
, name
, parent_module
, context
):
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
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
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
):
1038 def lookup(self
, name
):
1039 entry
= self
.lookup_here(name
)
1040 if entry
is not None:
1043 if self
.context
is not None:
1044 language_level
= self
.context
.language_level
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
)
1058 if Options
.error_on_unknown_names
:
1059 error(pos
, "undeclared name not builtin: %s" % name
)
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
1066 if Options
.cache_builtins
:
1067 for entry
in self
.cached_builtins
:
1068 if entry
.name
== name
:
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
1075 entry
.cname
= Naming
.builtin_prefix
+ name
1076 self
.cached_builtins
.append(entry
)
1077 self
.undeclared_cached_builtins
.append(entry
)
1079 entry
.is_builtin
= 1
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
)
1096 scope
= ModuleScope(name
,
1097 parent_module
= self
, context
= self
.context
)
1098 self
.module_entries
[name
] = 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
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
)
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.
1143 entry
= self
.declare_var(name
, py_object_type
, pos
)
1144 entry
.as_module
= scope
1145 self
.add_imported_module(scope
)
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
1155 if not visibility
in ('private', 'public', 'extern'):
1156 error(pos
, "Module-level variable cannot be declared %s" % visibility
)
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")
1165 defining
= not in_pxd
1166 if visibility
== 'extern' or (visibility
== 'public' and defining
):
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)
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
:
1186 if not entry
.is_implemented
:
1187 entry
.is_implemented
= True
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
)
1194 entry
.is_cglobal
= 1
1195 if entry
.type.is_pyobject
:
1197 self
.var_entries
.append(entry
)
1199 entry
.is_pyglobal
= 1
1200 if Options
.cimport_from_pyx
:
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.
1209 if visibility
== 'extern' or (visibility
== 'public' and defining
):
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
:
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
)
1227 def declare_global(self
, name
, pos
):
1228 entry
= self
.lookup_here(name
)
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
1249 objtypedef_cname
= None
1251 # Look for previous declaration as a type
1253 entry
= self
.lookup_here(name
)
1254 if entry
and not shadow
:
1256 if not (entry
.is_type
and type.is_extension_type
):
1257 entry
= None # Will cause redeclaration and produce an error
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')
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
1279 type.module_name
= self
.qualified_name
1281 type.typeptr_cname
= typeptr_cname
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
1288 type.objstruct_cname
= objstruct_cname
1289 elif not entry
.in_cinclude
:
1290 type.objstruct_cname
= self
.mangle(Naming
.objstruct_prefix
, name
)
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
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
)
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
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
))
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
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
1342 # Return new or existing entry
1346 def allocate_vtable_names(self
, entry
):
1347 # If extension type has a vtable, allocate vtable struct and
1348 # slot names for it.
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
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
):
1364 if base_type
.is_builtin_type
:
1365 # builtin base type defines all methods => no vtable needed
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
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
:
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
):
1394 visibility
= entry
.visibility
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
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" %
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
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.
1458 var_entry
= Entry(name
= entry
.name
,
1459 type = Builtin
.type_type
,
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
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
:
1499 #entry.borrowed = 1 # Not using borrowed arg refs for now
1500 self
.arg_entries
.append(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
:
1516 entry
.in_with_gil_block
= self
._in
_with
_gil
_block
1517 self
.var_entries
.append(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)
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
)
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
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
:
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
1598 self
.var_entries
.append(entry
)
1599 self
.entries
[name
] = 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.
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
:
1656 "C struct/union member cannot be a Python object")
1657 if visibility
!= 'private':
1659 "C struct/union member cannot be declared %s" % visibility
)
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
1683 def lookup(self
, name
):
1684 entry
= Scope
.lookup(self
, name
)
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.
1694 "__Pyx_Method_ClassMethod",
1695 PyrexTypes
.CFuncType(
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
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
))
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
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
)
1742 entry
= self
.lookup(name
)
1744 error(pos
, "no binding for nonlocal '%s' found" % name
)
1746 # FIXME: this works, but it's unclear if it's the
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)
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
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
= []
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
:
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
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):
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):
1836 # Add an entry for an attribute.
1839 "C attributes cannot be added in implementation part of"
1840 " extension type defined in a pxd")
1841 if get_special_method_signature(name
):
1843 "The name '%s' is reserved for a special method."
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'):
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
))):
1877 "C attribute of type '%s' cannot be accessed from Python" % type)
1879 entry
.needs_property
= False
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
)
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
1892 self
.namespace_cname
= "(PyObject *)%s" % self
.parent_type
.typeptr_cname
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
)
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
1911 entry
.signature
= pymethod_signature
1912 entry
.is_special
= 0
1914 self
.pyfunc_entries
.append(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
:
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'")
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
)
1945 cname
= c_safe_identifier(name
)
1947 if not entry
.is_cfunction
:
1948 warning(pos
, "'%s' redeclared " % name
, 0)
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
:
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
)
1961 error(pos
, "Signature not compatible with previous declaration")
1962 error(entry
.pos
, "Previous declaration is here")
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
)
1971 entry
.func_cname
= self
.mangle(Naming
.func_prefix
, name
)
1972 entry
.utility_code
= utility_code
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
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
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
2007 def declare_property(self
, name
, doc
, pos
):
2008 entry
= self
.lookup_here(name
)
2010 entry
= self
.declare(name
, name
, py_object_type
, pos
, 'private')
2011 entry
.is_property
= 1
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
)
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.
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
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
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
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:
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.
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")
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
:
2102 "C++ class member cannot be a Python object")
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
2112 for base_class
in entry
.type.base_classes
:
2113 if base_class
is PyrexTypes
.error_type
:
2115 temp_entry
= base_class
.scope
.lookup_here("<init>")
2117 if temp_entry
is None:
2119 for alternative
in temp_entry
.all_alternatives():
2120 type = alternative
.type
2122 type = type.base_type
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
2141 type.return_type
= PyrexTypes
.InvisibleVoidType()
2142 elif name
== '__dealloc__' and cname
is None:
2143 cname
= "~%s" % self
.type.cname
2145 type.return_type
= PyrexTypes
.InvisibleVoidType()
2146 prev_entry
= self
.lookup_here(name
)
2147 entry
= self
.declare_var(name
, type, pos
,
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
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.
2161 base_scope
.inherited_var_entries
+ base_scope
.var_entries
:
2162 #contructor is not inherited
2163 if base_entry
.name
== "<init>":
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():
2184 scope
.declare_type(entry
.name
,
2185 entry
.type.specialize(values
),
2189 elif entry
.type.is_cfunction
:
2190 for e
in entry
.all_alternatives():
2191 scope
.declare_cfunction(e
.name
,
2192 e
.type.specialize(values
),
2195 utility_code
= e
.utility_code
)
2197 scope
.declare_var(entry
.name
,
2198 entry
.type.specialize(values
),
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
)
2218 entry
= self
.declare(name
, name
, py_object_type
, pos
, 'private')
2219 entry
.is_special
= 1
2220 entry
.signature
= signature
2223 error(pos
, "Only __get__, __set__ and __del__ methods allowed "
2224 "in a property declaration")
2228 class CConstScope(Scope
):
2230 def __init__(self
, const_base_type_scope
):
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)
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