1 from Symtab import ModuleScope 2 from PyrexTypes import * 3 from UtilityCode import CythonUtilityCode 4 from Errors import error 5 from Scanning import StringSourceDescriptor 6 import MemoryView 7 8 class CythonScope(ModuleScope): 9 is_cython_builtin = 1 10 _cythonscope_initialized = False 11 12 def __init__(self, context): 13 ModuleScope.__init__(self, u'cython', None, None) 14 self.pxd_file_loaded = True 15 self.populate_cython_scope() 16 # The Main.Context object 17 self.context = context 18 19 for fused_type in (cy_integral_type, cy_floating_type, cy_numeric_type): 20 entry = self.declare_typedef(fused_type.name, 21 fused_type, 22 None, 23 cname='<error>') 24 entry.in_cinclude = True 25 26 def lookup_type(self, name): 27 # This function should go away when types are all first-level objects. 28 type = parse_basic_type(name) 29 if type: 30 return type 31 32 return super(CythonScope, self).lookup_type(name) 33 34 def lookup(self, name): 35 entry = super(CythonScope, self).lookup(name) 36 37 if entry is None and not self._cythonscope_initialized: 38 self.load_cythonscope() 39 entry = super(CythonScope, self).lookup(name) 40 41 return entry 42 43 def find_module(self, module_name, pos): 44 error("cython.%s is not available" % module_name, pos) 45 46 def find_submodule(self, module_name): 47 entry = self.entries.get(module_name, None) 48 if not entry: 49 self.load_cythonscope() 50 entry = self.entries.get(module_name, None) 51 52 if entry and entry.as_module: 53 return entry.as_module 54 else: 55 # TODO: fix find_submodule control flow so that we're not 56 # expected to create a submodule here (to protect CythonScope's 57 # possible immutability). Hack ourselves out of the situation 58 # for now. 59 raise error((StringSourceDescriptor(u"cython", u""), 0, 0), 60 "cython.%s is not available" % module_name) 61 62 def lookup_qualified_name(self, qname): 63 # ExprNode.as_cython_attribute generates qnames and we untangle it here... 64 name_path = qname.split(u'.') 65 scope = self 66 while len(name_path) > 1: 67 scope = scope.lookup_here(name_path[0]).as_module 68 del name_path[0] 69 if scope is None: 70 return None 71 else: 72 return scope.lookup_here(name_path[0]) 73 74 def populate_cython_scope(self): 75 # These are used to optimize isinstance in FinalOptimizePhase 76 type_object = self.declare_typedef( 77 'PyTypeObject', 78 base_type = c_void_type, 79 pos = None, 80 cname = 'PyTypeObject') 81 type_object.is_void = True 82 type_object_type = type_object.type 83 84 self.declare_cfunction( 85 'PyObject_TypeCheck', 86 CFuncType(c_bint_type, [CFuncTypeArg("o", py_object_type, None), 87 CFuncTypeArg("t", c_ptr_type(type_object_type), None)]), 88 pos = None, 89 defining = 1, 90 cname = 'PyObject_TypeCheck') 91 92 def load_cythonscope(self): 93 """ 94 Creates some entries for testing purposes and entries for 95 cython.array() and for cython.view.*. 96 """ 97 if self._cythonscope_initialized: 98 return 99 100 self._cythonscope_initialized = True 101 cython_testscope_utility_code.declare_in_scope( 102 self, cython_scope=self) 103 cython_test_extclass_utility_code.declare_in_scope( 104 self, cython_scope=self) 105 106 # 107 # The view sub-scope 108 # 109 self.viewscope = viewscope = ModuleScope(u'view', self, None) 110 self.declare_module('view', viewscope, None).as_module = viewscope 111 viewscope.is_cython_builtin = True 112 viewscope.pxd_file_loaded = True 113 114 cythonview_testscope_utility_code.declare_in_scope( 115 viewscope, cython_scope=self) 116 117 view_utility_scope = MemoryView.view_utility_code.declare_in_scope( 118 self.viewscope, cython_scope=self, 119 whitelist=MemoryView.view_utility_whitelist) 120 121 # self.entries["array"] = view_utility_scope.entries.pop("array") 122 123 124 def create_cython_scope(context): 125 # One could in fact probably make it a singleton, 126 # but not sure yet whether any code mutates it (which would kill reusing 127 # it across different contexts) 128 return CythonScope(context) 129 130 # Load test utilities for the cython scope 131 132 def load_testscope_utility(cy_util_name, **kwargs): 133 return CythonUtilityCode.load(cy_util_name, "TestCythonScope.pyx", **kwargs) 134 135 136 undecorated_methods_protos = UtilityCode(proto=u""" 137 /* These methods are undecorated and have therefore no prototype */ 138 static PyObject *__pyx_TestClass_cdef_method( 139 struct __pyx_TestClass_obj *self, int value); 140 static PyObject *__pyx_TestClass_cpdef_method( 141 struct __pyx_TestClass_obj *self, int value, int skip_dispatch); 142 static PyObject *__pyx_TestClass_def_method( 143 PyObject *self, PyObject *value); 144 """) 145 146 cython_testscope_utility_code = load_testscope_utility("TestScope") 147 148 test_cython_utility_dep = load_testscope_utility("TestDep") 149 150 cython_test_extclass_utility_code = \ 151 load_testscope_utility("TestClass", name="TestClass", 152 requires=[undecorated_methods_protos, 153 test_cython_utility_dep]) 154 155 cythonview_testscope_utility_code = load_testscope_utility("View.TestScope") 156