OLD | NEW |
(Empty) | |
| 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_typ
e), 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_wh
itelist) |
| 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") |
OLD | NEW |