cython

Форк
0
/
CythonScope.py 
179 строк · 6.6 Кб
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
from . import MemoryView
7
from .StringEncoding import EncodedString
8

9

10
class CythonScope(ModuleScope):
11
    is_cython_builtin = 1
12
    _cythonscope_initialized = False
13

14
    def __init__(self, context):
15
        ModuleScope.__init__(self, 'cython', None, None)
16
        self.pxd_file_loaded = True
17
        self.populate_cython_scope()
18
        # The Main.Context object
19
        self.context = context
20

21
        for fused_type in (cy_integral_type, cy_floating_type, cy_numeric_type):
22
            entry = self.declare_typedef(fused_type.name,
23
                                         fused_type,
24
                                         None,
25
                                         cname='<error>')
26
            entry.in_cinclude = True
27

28
    def is_cpp(self):
29
        # Allow C++ utility code in C++ contexts.
30
        return self.context.cpp
31

32
    def lookup_type(self, name):
33
        # This function should go away when types are all first-level objects.
34
        type = parse_basic_type(name)
35
        if type:
36
            return type
37

38
        return super().lookup_type(name)
39

40
    def lookup(self, name):
41
        entry = super().lookup(name)
42

43
        if entry is None and not self._cythonscope_initialized:
44
            self.load_cythonscope()
45
            entry = super().lookup(name)
46

47
        return entry
48

49
    def find_module(self, module_name, pos):
50
        error("cython.%s is not available" % module_name, pos)
51

52
    def find_submodule(self, module_name, as_package=False):
53
        entry = self.entries.get(module_name, None)
54
        if not entry:
55
            self.load_cythonscope()
56
            entry = self.entries.get(module_name, None)
57

58
        if entry and entry.as_module:
59
            return entry.as_module
60
        else:
61
            # TODO: fix find_submodule control flow so that we're not
62
            # expected to create a submodule here (to protect CythonScope's
63
            # possible immutability). Hack ourselves out of the situation
64
            # for now.
65
            raise error((StringSourceDescriptor("cython", ""), 0, 0),
66
                  "cython.%s is not available" % module_name)
67

68
    def lookup_qualified_name(self, qname):
69
        # ExprNode.as_cython_attribute generates qnames and we untangle it here...
70
        name_path = qname.split('.')
71
        scope = self
72
        while len(name_path) > 1:
73
            scope = scope.lookup_here(name_path[0])
74
            if scope:
75
                scope = scope.as_module
76
            del name_path[0]
77
            if scope is None:
78
                return None
79
        else:
80
            return scope.lookup_here(name_path[0])
81

82
    def populate_cython_scope(self):
83
        # These are used to optimize isinstance in FinalOptimizePhase
84
        type_object = self.declare_typedef(
85
            'PyTypeObject',
86
            base_type = c_void_type,
87
            pos = None,
88
            cname = 'PyTypeObject')
89
        type_object.is_void = True
90
        type_object_type = type_object.type
91

92
        self.declare_cfunction(
93
            'PyObject_TypeCheck',
94
            CFuncType(c_bint_type, [CFuncTypeArg("o", py_object_type, None),
95
                                    CFuncTypeArg("t", c_ptr_type(type_object_type), None)]),
96
            pos = None,
97
            defining = 1,
98
            cname = 'PyObject_TypeCheck')
99

100
    def load_cythonscope(self):
101
        """
102
        Creates some entries for testing purposes and entries for
103
        cython.array() and for cython.view.*.
104
        """
105
        if self._cythonscope_initialized:
106
            return
107

108
        self._cythonscope_initialized = True
109
        cython_testscope_utility_code.declare_in_scope(
110
                                self, cython_scope=self)
111
        cython_test_extclass_utility_code.declare_in_scope(
112
                                    self, cython_scope=self)
113

114
        #
115
        # The view sub-scope
116
        #
117
        self.viewscope = viewscope = ModuleScope('view', self, None)
118
        self.declare_module('view', viewscope, None).as_module = viewscope
119
        viewscope.is_cython_builtin = True
120
        viewscope.pxd_file_loaded = True
121

122
        cythonview_testscope_utility_code.declare_in_scope(
123
                                            viewscope, cython_scope=self)
124

125
        view_utility_scope = MemoryView.view_utility_code.declare_in_scope(
126
                                            self.viewscope, cython_scope=self,
127
                                            allowlist=MemoryView.view_utility_allowlist)
128

129
        # Marks the types as being cython_builtin_type so that they can be
130
        # extended from without Cython attempting to import cython.view
131
        ext_types = [ entry.type
132
                         for entry in view_utility_scope.entries.values()
133
                         if entry.type.is_extension_type ]
134
        for ext_type in ext_types:
135
            ext_type.is_cython_builtin_type = 1
136

137
        # self.entries["array"] = view_utility_scope.entries.pop("array")
138

139
        # dataclasses scope
140
        dc_str = EncodedString('dataclasses')
141
        dataclassesscope = ModuleScope(dc_str, self, context=None)
142
        self.declare_module(dc_str, dataclassesscope, pos=None).as_module = dataclassesscope
143
        dataclassesscope.is_cython_builtin = True
144
        dataclassesscope.pxd_file_loaded = True
145
        # doesn't actually have any contents
146

147

148
def create_cython_scope(context):
149
    # One could in fact probably make it a singleton,
150
    # but not sure yet whether any code mutates it (which would kill reusing
151
    # it across different contexts)
152
    return CythonScope(context)
153

154
# Load test utilities for the cython scope
155

156
def load_testscope_utility(cy_util_name, **kwargs):
157
    return CythonUtilityCode.load(cy_util_name, "TestCythonScope.pyx", **kwargs)
158

159

160
undecorated_methods_protos = UtilityCode(proto="""
161
    /* These methods are undecorated and have therefore no prototype */
162
    static PyObject *__pyx_TestClass_cdef_method(
163
            struct __pyx_TestClass_obj *self, int value);
164
    static PyObject *__pyx_TestClass_cpdef_method(
165
            struct __pyx_TestClass_obj *self, int value, int skip_dispatch);
166
    static PyObject *__pyx_TestClass_def_method(
167
            PyObject *self, PyObject *value);
168
""")
169

170
cython_testscope_utility_code = load_testscope_utility("TestScope")
171

172
test_cython_utility_dep = load_testscope_utility("TestDep")
173

174
cython_test_extclass_utility_code = \
175
    load_testscope_utility("TestClass", name="TestClass",
176
                           requires=[undecorated_methods_protos,
177
                                     test_cython_utility_dep])
178

179
cythonview_testscope_utility_code = load_testscope_utility("View.TestScope")
180

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.