cython

Форк
0
/
check_size.srctree 
234 строки · 5.0 Кб
1
PYTHON setup.py build_ext --inplace
2
PYTHON -c "import runner"
3

4
######## setup.py ########
5

6
from Cython.Build.Dependencies import cythonize
7
from Cython.Compiler.Errors import CompileError
8
from distutils.core import setup
9

10
# force the build order
11
setup(ext_modules= cythonize("check_size.pyx"))
12

13
setup(ext_modules = cythonize("_check_size*.pyx"))
14

15
try:
16
    setup(ext_modules= cythonize("check_size_invalid.pyx"))
17
    assert False
18
except CompileError as e:
19
    pass
20

21
######## check_size_nominal.h ########
22

23
#include <Python.h>
24

25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28

29
typedef struct {
30
    PyObject_HEAD
31
    int f0;
32
    int f1;
33
    int f2;
34
} FooStructNominal;
35

36
#ifdef __cplusplus
37
}
38
#endif
39

40
######## check_size_bigger.h ########
41

42
#include <Python.h>
43

44
#ifdef __cplusplus
45
extern "C" {
46
#endif
47

48
typedef struct {
49
    PyObject_HEAD
50
    int f0;
51
    int f1;
52
    int f2;
53
    int f3;
54
    int f4;
55
} FooStructBig;
56

57
#ifdef __cplusplus
58
}
59
#endif
60

61
######## check_size_smaller.h ########
62

63
#include <Python.h>
64

65
#ifdef __cplusplus
66
extern "C" {
67
#endif
68

69
typedef struct {
70
    PyObject_HEAD
71
    int f9;
72
} FooStructSmall;
73

74
#ifdef __cplusplus
75
}
76
#endif
77

78

79
######## check_size.pyx ########
80

81
cdef class Foo:
82
    cdef public int field0, field1, field2;
83

84
    def __init__(self, f0, f1, f2):
85
        self.field0 = f0
86
        self.field1 = f1
87
        self.field2 = f2
88

89
######## _check_size_exact.pyx ########
90

91
cdef extern from "check_size_nominal.h":
92

93
    ctypedef class check_size.Foo [object FooStructNominal]:
94
        cdef:
95
            int f0
96
            int f1
97

98

99
cpdef public int testme(Foo f) except -1:
100
    return f.f0 + f.f1
101

102
######## _check_size_too_small.pyx ########
103

104
cdef extern from "check_size_bigger.h":
105

106
    ctypedef class check_size.Foo [object FooStructBig]:
107
        cdef:
108
            int f0
109
            int f1
110
            int f2
111

112

113
cpdef public int testme(Foo f, int f2) except -1:
114
    f.f2 = f2
115
    return f.f0 + f.f1 + f.f2
116

117
######## _check_size_default.pyx ########
118

119
cdef extern from "check_size_smaller.h":
120

121
    ctypedef class check_size.Foo [object FooStructSmall]:
122
        cdef:
123
            int f9
124

125

126
cpdef public int testme(Foo f) except -1:
127
    return f.f9
128

129
######## _check_size_warn.pyx ########
130

131
cdef extern from "check_size_smaller.h":
132

133
    # make sure missing check_size is equivalent to warn
134
    ctypedef class check_size.Foo [object FooStructSmall, check_size warn]:
135
        cdef:
136
            int f9
137

138

139
cpdef public int testme(Foo f) except -1:
140
    return f.f9
141

142
######## _check_size_ignore.pyx ########
143

144
cdef extern from "check_size_smaller.h":
145

146
    # Allow size to be larger
147
    ctypedef class check_size.Foo [object FooStructSmall, check_size ignore]:
148
        cdef:
149
            int f9
150

151

152
cpdef public int testme(Foo f) except -1:
153
    return f.f9
154

155
######## _check_size_error.pyx ########
156

157
cdef extern from "check_size_smaller.h":
158

159
    # Strict checking, will raise an error
160
    ctypedef class check_size.Foo [object FooStructSmall, check_size error]:
161
        cdef:
162
            int f9
163

164

165
cpdef public int testme(Foo f) except -1:
166
    return f.f9
167

168
######## check_size_invalid.pyx ########
169

170
cdef extern from "check_size_smaller.h":
171

172
    # Raise CompileError when using bad value
173
    ctypedef class check_size.Foo [object FooStructSmall, check_size hihi]:
174
        cdef:
175
            int f9
176

177

178
cpdef public int testme(Foo f) except -1:
179
    return f.f9
180

181
######## runner.py ########
182

183
import check_size, _check_size_exact, warnings
184

185
foo = check_size.Foo(23, 123, 1023)
186

187
assert foo.field0 == 23
188
assert foo.field1 == 123
189

190
ret =  _check_size_exact.testme(foo)
191
assert ret == 23 + 123
192

193
# ValueError since check_size.Foo's tp_basicsize is smaller than what is needed
194
# for FooStructBig. Messing with f2 will access memory outside the struct!
195
try:
196
    import _check_size_too_small
197
    assert False
198
except ValueError as e:
199
    assert str(e).startswith('check_size.Foo size changed')
200

201
# Warning since check_size.Foo's tp_basicsize is larger than what is needed
202
# for FooStructSmall. There is "spare", accessing FooStructSmall's fields will
203
# never access invalid memory. This can happen, for instance, when using old
204
# headers with a newer runtime, or when using an old _check_size{2,3} with a newer
205
# check_size, where the developers of check_size are careful to be backward
206
# compatible.
207

208
with warnings.catch_warnings(record=True) as w:
209
    warnings.simplefilter("always")
210
    import _check_size_default
211
    import _check_size_warn
212
    assert len(w) == 2, 'expected two warnings, got %d' % len(w)
213
    assert str(w[0].message).startswith('check_size.Foo size changed')
214
    assert str(w[1].message).startswith('check_size.Foo size changed')
215

216
ret = _check_size_default.testme(foo)
217
assert ret == 23
218
ret = _check_size_warn.testme(foo)
219
assert ret == 23
220

221
with warnings.catch_warnings(record=True) as w:
222
    # No warning, runtime vendor must provide backward compatibility
223
    import _check_size_ignore
224
    assert len(w) == 0
225

226
ret = _check_size_ignore.testme(foo)
227
assert ret == 23
228

229
try:
230
    # Enforce strict checking
231
    import _check_size_error
232
    assert False
233
except ValueError as e:
234
    assert str(e).startswith('check_size.Foo size changed')
235

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

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

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

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