• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from Symtab import ModuleScope
2from PyrexTypes import *
3from UtilityCode import CythonUtilityCode
4from Errors import error
5from Scanning import StringSourceDescriptor
6import MemoryView
7
8class 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
124def 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
132def load_testscope_utility(cy_util_name, **kwargs):
133    return CythonUtilityCode.load(cy_util_name, "TestCythonScope.pyx", **kwargs)
134
135
136undecorated_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
146cython_testscope_utility_code = load_testscope_utility("TestScope")
147
148test_cython_utility_dep = load_testscope_utility("TestDep")
149
150cython_test_extclass_utility_code = \
151    load_testscope_utility("TestClass", name="TestClass",
152                           requires=[undecorated_methods_protos,
153                                     test_cython_utility_dep])
154
155cythonview_testscope_utility_code = load_testscope_utility("View.TestScope")
156