NonameSsSs commited on
Commit
e359f37
·
verified ·
1 Parent(s): bbb1840

Delete cffi/api.py

Browse files
Files changed (1) hide show
  1. cffi/api.py +0 -953
cffi/api.py DELETED
@@ -1,953 +0,0 @@
1
- import sys, types
2
- from .lock import allocate_lock
3
- from .error import CDefError
4
- from . import model
5
-
6
- try:
7
- callable
8
- except NameError:
9
- # Python 3.1
10
- from collections import Callable
11
- callable = lambda x: isinstance(x, Callable)
12
-
13
- try:
14
- basestring
15
- except NameError:
16
- # Python 3.x
17
- basestring = str
18
-
19
- _unspecified = object()
20
-
21
-
22
-
23
- class FFI(object):
24
- r'''
25
- The main top-level class that you instantiate once, or once per module.
26
-
27
- Example usage:
28
-
29
- ffi = FFI()
30
- ffi.cdef("""
31
- int printf(const char *, ...);
32
- """)
33
-
34
- C = ffi.dlopen(None) # standard library
35
- -or-
36
- C = ffi.verify() # use a C compiler: verify the decl above is right
37
-
38
- C.printf("hello, %s!\n", ffi.new("char[]", "world"))
39
- '''
40
-
41
- def __init__(self, backend=None):
42
- """Create an FFI instance. The 'backend' argument is used to
43
- select a non-default backend, mostly for tests.
44
- """
45
- if backend is None:
46
- # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with
47
- # _cffi_backend.so compiled.
48
- import _cffi_backend as backend
49
-
50
-
51
- from . import cparser
52
- self._backend = backend
53
- self._lock = allocate_lock()
54
- self._parser = cparser.Parser()
55
- self._cached_btypes = {}
56
- self._parsed_types = types.ModuleType('parsed_types').__dict__
57
- self._new_types = types.ModuleType('new_types').__dict__
58
- self._function_caches = []
59
- self._libraries = []
60
- self._cdefsources = []
61
- self._included_ffis = []
62
- self._windows_unicode = None
63
- self._init_once_cache = {}
64
- self._cdef_version = None
65
- self._embedding = None
66
- self._typecache = model.get_typecache(backend)
67
- if hasattr(backend, 'set_ffi'):
68
- backend.set_ffi(self)
69
- for name in list(backend.__dict__):
70
- if name.startswith('RTLD_'):
71
- setattr(self, name, getattr(backend, name))
72
- #
73
- with self._lock:
74
- self.BVoidP = self._get_cached_btype(model.voidp_type)
75
- self.BCharA = self._get_cached_btype(model.char_array_type)
76
- if isinstance(backend, types.ModuleType):
77
- # _cffi_backend: attach these constants to the class
78
- if not hasattr(FFI, 'NULL'):
79
- FFI.NULL = self.cast(self.BVoidP, 0)
80
- FFI.CData, FFI.CType = backend._get_types()
81
- else:
82
- # ctypes backend: attach these constants to the instance
83
- self.NULL = self.cast(self.BVoidP, 0)
84
- self.CData, self.CType = backend._get_types()
85
- self.buffer = backend.buffer
86
-
87
- def cdef(self, csource, override=False, packed=False, pack=None):
88
- """Parse the given C source. This registers all declared functions,
89
- types, and global variables. The functions and global variables can
90
- then be accessed via either 'ffi.dlopen()' or 'ffi.verify()'.
91
- The types can be used in 'ffi.new()' and other functions.
92
- If 'packed' is specified as True, all structs declared inside this
93
- cdef are packed, i.e. laid out without any field alignment at all.
94
- Alternatively, 'pack' can be a small integer, and requests for
95
- alignment greater than that are ignored (pack=1 is equivalent to
96
- packed=True).
97
- """
98
- self._cdef(csource, override=override, packed=packed, pack=pack)
99
-
100
- def embedding_api(self, csource, packed=False, pack=None):
101
- self._cdef(csource, packed=packed, pack=pack, dllexport=True)
102
- if self._embedding is None:
103
- self._embedding = ''
104
-
105
- def _cdef(self, csource, override=False, **options):
106
- if not isinstance(csource, str): # unicode, on Python 2
107
- if not isinstance(csource, basestring):
108
- raise TypeError("cdef() argument must be a string")
109
- csource = csource.encode('ascii')
110
- with self._lock:
111
- self._cdef_version = object()
112
- self._parser.parse(csource, override=override, **options)
113
- self._cdefsources.append(csource)
114
- if override:
115
- for cache in self._function_caches:
116
- cache.clear()
117
- finishlist = self._parser._recomplete
118
- if finishlist:
119
- self._parser._recomplete = []
120
- for tp in finishlist:
121
- tp.finish_backend_type(self, finishlist)
122
-
123
- def dlopen(self, name, flags=0):
124
- """Load and return a dynamic library identified by 'name'.
125
- The standard C library can be loaded by passing None.
126
- Note that functions and types declared by 'ffi.cdef()' are not
127
- linked to a particular library, just like C headers; in the
128
- library we only look for the actual (untyped) symbols.
129
- """
130
- if not (isinstance(name, basestring) or
131
- name is None or
132
- isinstance(name, self.CData)):
133
- raise TypeError("dlopen(name): name must be a file name, None, "
134
- "or an already-opened 'void *' handle")
135
- with self._lock:
136
- lib, function_cache = _make_ffi_library(self, name, flags)
137
- self._function_caches.append(function_cache)
138
- self._libraries.append(lib)
139
- return lib
140
-
141
- def dlclose(self, lib):
142
- """Close a library obtained with ffi.dlopen(). After this call,
143
- access to functions or variables from the library will fail
144
- (possibly with a segmentation fault).
145
- """
146
- type(lib).__cffi_close__(lib)
147
-
148
- def _typeof_locked(self, cdecl):
149
- # call me with the lock!
150
- key = cdecl
151
- if key in self._parsed_types:
152
- return self._parsed_types[key]
153
- #
154
- if not isinstance(cdecl, str): # unicode, on Python 2
155
- cdecl = cdecl.encode('ascii')
156
- #
157
- type = self._parser.parse_type(cdecl)
158
- really_a_function_type = type.is_raw_function
159
- if really_a_function_type:
160
- type = type.as_function_pointer()
161
- btype = self._get_cached_btype(type)
162
- result = btype, really_a_function_type
163
- self._parsed_types[key] = result
164
- return result
165
-
166
- def _typeof(self, cdecl, consider_function_as_funcptr=False):
167
- # string -> ctype object
168
- try:
169
- result = self._parsed_types[cdecl]
170
- except KeyError:
171
- with self._lock:
172
- result = self._typeof_locked(cdecl)
173
- #
174
- btype, really_a_function_type = result
175
- if really_a_function_type and not consider_function_as_funcptr:
176
- raise CDefError("the type %r is a function type, not a "
177
- "pointer-to-function type" % (cdecl,))
178
- return btype
179
-
180
- def typeof(self, cdecl):
181
- """Parse the C type given as a string and return the
182
- corresponding <ctype> object.
183
- It can also be used on 'cdata' instance to get its C type.
184
- """
185
- if isinstance(cdecl, basestring):
186
- return self._typeof(cdecl)
187
- if isinstance(cdecl, self.CData):
188
- return self._backend.typeof(cdecl)
189
- if isinstance(cdecl, types.BuiltinFunctionType):
190
- res = _builtin_function_type(cdecl)
191
- if res is not None:
192
- return res
193
- if (isinstance(cdecl, types.FunctionType)
194
- and hasattr(cdecl, '_cffi_base_type')):
195
- with self._lock:
196
- return self._get_cached_btype(cdecl._cffi_base_type)
197
- raise TypeError(type(cdecl))
198
-
199
- def sizeof(self, cdecl):
200
- """Return the size in bytes of the argument. It can be a
201
- string naming a C type, or a 'cdata' instance.
202
- """
203
- if isinstance(cdecl, basestring):
204
- BType = self._typeof(cdecl)
205
- return self._backend.sizeof(BType)
206
- else:
207
- return self._backend.sizeof(cdecl)
208
-
209
- def alignof(self, cdecl):
210
- """Return the natural alignment size in bytes of the C type
211
- given as a string.
212
- """
213
- if isinstance(cdecl, basestring):
214
- cdecl = self._typeof(cdecl)
215
- return self._backend.alignof(cdecl)
216
-
217
- def offsetof(self, cdecl, *fields_or_indexes):
218
- """Return the offset of the named field inside the given
219
- structure or array, which must be given as a C type name.
220
- You can give several field names in case of nested structures.
221
- You can also give numeric values which correspond to array
222
- items, in case of an array type.
223
- """
224
- if isinstance(cdecl, basestring):
225
- cdecl = self._typeof(cdecl)
226
- return self._typeoffsetof(cdecl, *fields_or_indexes)[1]
227
-
228
- def new(self, cdecl, init=None):
229
- """Allocate an instance according to the specified C type and
230
- return a pointer to it. The specified C type must be either a
231
- pointer or an array: ``new('X *')`` allocates an X and returns
232
- a pointer to it, whereas ``new('X[n]')`` allocates an array of
233
- n X'es and returns an array referencing it (which works
234
- mostly like a pointer, like in C). You can also use
235
- ``new('X[]', n)`` to allocate an array of a non-constant
236
- length n.
237
-
238
- The memory is initialized following the rules of declaring a
239
- global variable in C: by default it is zero-initialized, but
240
- an explicit initializer can be given which can be used to
241
- fill all or part of the memory.
242
-
243
- When the returned <cdata> object goes out of scope, the memory
244
- is freed. In other words the returned <cdata> object has
245
- ownership of the value of type 'cdecl' that it points to. This
246
- means that the raw data can be used as long as this object is
247
- kept alive, but must not be used for a longer time. Be careful
248
- about that when copying the pointer to the memory somewhere
249
- else, e.g. into another structure.
250
- """
251
- if isinstance(cdecl, basestring):
252
- cdecl = self._typeof(cdecl)
253
- return self._backend.newp(cdecl, init)
254
-
255
- def new_allocator(self, alloc=None, free=None,
256
- should_clear_after_alloc=True):
257
- """Return a new allocator, i.e. a function that behaves like ffi.new()
258
- but uses the provided low-level 'alloc' and 'free' functions.
259
-
260
- 'alloc' is called with the size as argument. If it returns NULL, a
261
- MemoryError is raised. 'free' is called with the result of 'alloc'
262
- as argument. Both can be either Python function or directly C
263
- functions. If 'free' is None, then no free function is called.
264
- If both 'alloc' and 'free' are None, the default is used.
265
-
266
- If 'should_clear_after_alloc' is set to False, then the memory
267
- returned by 'alloc' is assumed to be already cleared (or you are
268
- fine with garbage); otherwise CFFI will clear it.
269
- """
270
- compiled_ffi = self._backend.FFI()
271
- allocator = compiled_ffi.new_allocator(alloc, free,
272
- should_clear_after_alloc)
273
- def allocate(cdecl, init=None):
274
- if isinstance(cdecl, basestring):
275
- cdecl = self._typeof(cdecl)
276
- return allocator(cdecl, init)
277
- return allocate
278
-
279
- def cast(self, cdecl, source):
280
- """Similar to a C cast: returns an instance of the named C
281
- type initialized with the given 'source'. The source is
282
- casted between integers or pointers of any type.
283
- """
284
- if isinstance(cdecl, basestring):
285
- cdecl = self._typeof(cdecl)
286
- return self._backend.cast(cdecl, source)
287
-
288
- def string(self, cdata, maxlen=-1):
289
- """Return a Python string (or unicode string) from the 'cdata'.
290
- If 'cdata' is a pointer or array of characters or bytes, returns
291
- the null-terminated string. The returned string extends until
292
- the first null character, or at most 'maxlen' characters. If
293
- 'cdata' is an array then 'maxlen' defaults to its length.
294
-
295
- If 'cdata' is a pointer or array of wchar_t, returns a unicode
296
- string following the same rules.
297
-
298
- If 'cdata' is a single character or byte or a wchar_t, returns
299
- it as a string or unicode string.
300
-
301
- If 'cdata' is an enum, returns the value of the enumerator as a
302
- string, or 'NUMBER' if the value is out of range.
303
- """
304
- return self._backend.string(cdata, maxlen)
305
-
306
- def unpack(self, cdata, length):
307
- """Unpack an array of C data of the given length,
308
- returning a Python string/unicode/list.
309
-
310
- If 'cdata' is a pointer to 'char', returns a byte string.
311
- It does not stop at the first null. This is equivalent to:
312
- ffi.buffer(cdata, length)[:]
313
-
314
- If 'cdata' is a pointer to 'wchar_t', returns a unicode string.
315
- 'length' is measured in wchar_t's; it is not the size in bytes.
316
-
317
- If 'cdata' is a pointer to anything else, returns a list of
318
- 'length' items. This is a faster equivalent to:
319
- [cdata[i] for i in range(length)]
320
- """
321
- return self._backend.unpack(cdata, length)
322
-
323
- #def buffer(self, cdata, size=-1):
324
- # """Return a read-write buffer object that references the raw C data
325
- # pointed to by the given 'cdata'. The 'cdata' must be a pointer or
326
- # an array. Can be passed to functions expecting a buffer, or directly
327
- # manipulated with:
328
- #
329
- # buf[:] get a copy of it in a regular string, or
330
- # buf[idx] as a single character
331
- # buf[:] = ...
332
- # buf[idx] = ... change the content
333
- # """
334
- # note that 'buffer' is a type, set on this instance by __init__
335
-
336
- def from_buffer(self, cdecl, python_buffer=_unspecified,
337
- require_writable=False):
338
- """Return a cdata of the given type pointing to the data of the
339
- given Python object, which must support the buffer interface.
340
- Note that this is not meant to be used on the built-in types
341
- str or unicode (you can build 'char[]' arrays explicitly)
342
- but only on objects containing large quantities of raw data
343
- in some other format, like 'array.array' or numpy arrays.
344
-
345
- The first argument is optional and default to 'char[]'.
346
- """
347
- if python_buffer is _unspecified:
348
- cdecl, python_buffer = self.BCharA, cdecl
349
- elif isinstance(cdecl, basestring):
350
- cdecl = self._typeof(cdecl)
351
- return self._backend.from_buffer(cdecl, python_buffer,
352
- require_writable)
353
-
354
- def memmove(self, dest, src, n):
355
- """ffi.memmove(dest, src, n) copies n bytes of memory from src to dest.
356
-
357
- Like the C function memmove(), the memory areas may overlap;
358
- apart from that it behaves like the C function memcpy().
359
-
360
- 'src' can be any cdata ptr or array, or any Python buffer object.
361
- 'dest' can be any cdata ptr or array, or a writable Python buffer
362
- object. The size to copy, 'n', is always measured in bytes.
363
-
364
- Unlike other methods, this one supports all Python buffer including
365
- byte strings and bytearrays---but it still does not support
366
- non-contiguous buffers.
367
- """
368
- return self._backend.memmove(dest, src, n)
369
-
370
- def callback(self, cdecl, python_callable=None, error=None, onerror=None):
371
- """Return a callback object or a decorator making such a
372
- callback object. 'cdecl' must name a C function pointer type.
373
- The callback invokes the specified 'python_callable' (which may
374
- be provided either directly or via a decorator). Important: the
375
- callback object must be manually kept alive for as long as the
376
- callback may be invoked from the C level.
377
- """
378
- def callback_decorator_wrap(python_callable):
379
- if not callable(python_callable):
380
- raise TypeError("the 'python_callable' argument "
381
- "is not callable")
382
- return self._backend.callback(cdecl, python_callable,
383
- error, onerror)
384
- if isinstance(cdecl, basestring):
385
- cdecl = self._typeof(cdecl, consider_function_as_funcptr=True)
386
- if python_callable is None:
387
- return callback_decorator_wrap # decorator mode
388
- else:
389
- return callback_decorator_wrap(python_callable) # direct mode
390
-
391
- def getctype(self, cdecl, replace_with=''):
392
- """Return a string giving the C type 'cdecl', which may be itself
393
- a string or a <ctype> object. If 'replace_with' is given, it gives
394
- extra text to append (or insert for more complicated C types), like
395
- a variable name, or '*' to get actually the C type 'pointer-to-cdecl'.
396
- """
397
- if isinstance(cdecl, basestring):
398
- cdecl = self._typeof(cdecl)
399
- replace_with = replace_with.strip()
400
- if (replace_with.startswith('*')
401
- and '&[' in self._backend.getcname(cdecl, '&')):
402
- replace_with = '(%s)' % replace_with
403
- elif replace_with and not replace_with[0] in '[(':
404
- replace_with = ' ' + replace_with
405
- return self._backend.getcname(cdecl, replace_with)
406
-
407
- def gc(self, cdata, destructor, size=0):
408
- """Return a new cdata object that points to the same
409
- data. Later, when this new cdata object is garbage-collected,
410
- 'destructor(old_cdata_object)' will be called.
411
-
412
- The optional 'size' gives an estimate of the size, used to
413
- trigger the garbage collection more eagerly. So far only used
414
- on PyPy. It tells the GC that the returned object keeps alive
415
- roughly 'size' bytes of external memory.
416
- """
417
- return self._backend.gcp(cdata, destructor, size)
418
-
419
- def _get_cached_btype(self, type):
420
- assert self._lock.acquire(False) is False
421
- # call me with the lock!
422
- try:
423
- BType = self._cached_btypes[type]
424
- except KeyError:
425
- finishlist = []
426
- BType = type.get_cached_btype(self, finishlist)
427
- for type in finishlist:
428
- type.finish_backend_type(self, finishlist)
429
- return BType
430
-
431
- def verify(self, source='', tmpdir=None, **kwargs):
432
- """Verify that the current ffi signatures compile on this
433
- machine, and return a dynamic library object. The dynamic
434
- library can be used to call functions and access global
435
- variables declared in this 'ffi'. The library is compiled
436
- by the C compiler: it gives you C-level API compatibility
437
- (including calling macros). This is unlike 'ffi.dlopen()',
438
- which requires binary compatibility in the signatures.
439
- """
440
- from .verifier import Verifier, _caller_dir_pycache
441
- #
442
- # If set_unicode(True) was called, insert the UNICODE and
443
- # _UNICODE macro declarations
444
- if self._windows_unicode:
445
- self._apply_windows_unicode(kwargs)
446
- #
447
- # Set the tmpdir here, and not in Verifier.__init__: it picks
448
- # up the caller's directory, which we want to be the caller of
449
- # ffi.verify(), as opposed to the caller of Veritier().
450
- tmpdir = tmpdir or _caller_dir_pycache()
451
- #
452
- # Make a Verifier() and use it to load the library.
453
- self.verifier = Verifier(self, source, tmpdir, **kwargs)
454
- lib = self.verifier.load_library()
455
- #
456
- # Save the loaded library for keep-alive purposes, even
457
- # if the caller doesn't keep it alive itself (it should).
458
- self._libraries.append(lib)
459
- return lib
460
-
461
- def _get_errno(self):
462
- return self._backend.get_errno()
463
- def _set_errno(self, errno):
464
- self._backend.set_errno(errno)
465
- errno = property(_get_errno, _set_errno, None,
466
- "the value of 'errno' from/to the C calls")
467
-
468
- def getwinerror(self, code=-1):
469
- return self._backend.getwinerror(code)
470
-
471
- def _pointer_to(self, ctype):
472
- with self._lock:
473
- return model.pointer_cache(self, ctype)
474
-
475
- def addressof(self, cdata, *fields_or_indexes):
476
- """Return the address of a <cdata 'struct-or-union'>.
477
- If 'fields_or_indexes' are given, returns the address of that
478
- field or array item in the structure or array, recursively in
479
- case of nested structures.
480
- """
481
- try:
482
- ctype = self._backend.typeof(cdata)
483
- except TypeError:
484
- if '__addressof__' in type(cdata).__dict__:
485
- return type(cdata).__addressof__(cdata, *fields_or_indexes)
486
- raise
487
- if fields_or_indexes:
488
- ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes)
489
- else:
490
- if ctype.kind == "pointer":
491
- raise TypeError("addressof(pointer)")
492
- offset = 0
493
- ctypeptr = self._pointer_to(ctype)
494
- return self._backend.rawaddressof(ctypeptr, cdata, offset)
495
-
496
- def _typeoffsetof(self, ctype, field_or_index, *fields_or_indexes):
497
- ctype, offset = self._backend.typeoffsetof(ctype, field_or_index)
498
- for field1 in fields_or_indexes:
499
- ctype, offset1 = self._backend.typeoffsetof(ctype, field1, 1)
500
- offset += offset1
501
- return ctype, offset
502
-
503
- def include(self, ffi_to_include):
504
- """Includes the typedefs, structs, unions and enums defined
505
- in another FFI instance. Usage is similar to a #include in C,
506
- where a part of the program might include types defined in
507
- another part for its own usage. Note that the include()
508
- method has no effect on functions, constants and global
509
- variables, which must anyway be accessed directly from the
510
- lib object returned by the original FFI instance.
511
- """
512
- if not isinstance(ffi_to_include, FFI):
513
- raise TypeError("ffi.include() expects an argument that is also of"
514
- " type cffi.FFI, not %r" % (
515
- type(ffi_to_include).__name__,))
516
- if ffi_to_include is self:
517
- raise ValueError("self.include(self)")
518
- with ffi_to_include._lock:
519
- with self._lock:
520
- self._parser.include(ffi_to_include._parser)
521
- self._cdefsources.append('[')
522
- self._cdefsources.extend(ffi_to_include._cdefsources)
523
- self._cdefsources.append(']')
524
- self._included_ffis.append(ffi_to_include)
525
-
526
- def new_handle(self, x):
527
- return self._backend.newp_handle(self.BVoidP, x)
528
-
529
- def from_handle(self, x):
530
- return self._backend.from_handle(x)
531
-
532
- def release(self, x):
533
- self._backend.release(x)
534
-
535
- def set_unicode(self, enabled_flag):
536
- """Windows: if 'enabled_flag' is True, enable the UNICODE and
537
- _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR
538
- to be (pointers to) wchar_t. If 'enabled_flag' is False,
539
- declare these types to be (pointers to) plain 8-bit characters.
540
- This is mostly for backward compatibility; you usually want True.
541
- """
542
- if self._windows_unicode is not None:
543
- raise ValueError("set_unicode() can only be called once")
544
- enabled_flag = bool(enabled_flag)
545
- if enabled_flag:
546
- self.cdef("typedef wchar_t TBYTE;"
547
- "typedef wchar_t TCHAR;"
548
- "typedef const wchar_t *LPCTSTR;"
549
- "typedef const wchar_t *PCTSTR;"
550
- "typedef wchar_t *LPTSTR;"
551
- "typedef wchar_t *PTSTR;"
552
- "typedef TBYTE *PTBYTE;"
553
- "typedef TCHAR *PTCHAR;")
554
- else:
555
- self.cdef("typedef char TBYTE;"
556
- "typedef char TCHAR;"
557
- "typedef const char *LPCTSTR;"
558
- "typedef const char *PCTSTR;"
559
- "typedef char *LPTSTR;"
560
- "typedef char *PTSTR;"
561
- "typedef TBYTE *PTBYTE;"
562
- "typedef TCHAR *PTCHAR;")
563
- self._windows_unicode = enabled_flag
564
-
565
- def _apply_windows_unicode(self, kwds):
566
- defmacros = kwds.get('define_macros', ())
567
- if not isinstance(defmacros, (list, tuple)):
568
- raise TypeError("'define_macros' must be a list or tuple")
569
- defmacros = list(defmacros) + [('UNICODE', '1'),
570
- ('_UNICODE', '1')]
571
- kwds['define_macros'] = defmacros
572
-
573
- def _apply_embedding_fix(self, kwds):
574
- # must include an argument like "-lpython2.7" for the compiler
575
- def ensure(key, value):
576
- lst = kwds.setdefault(key, [])
577
- if value not in lst:
578
- lst.append(value)
579
- #
580
- if '__pypy__' in sys.builtin_module_names:
581
- import os
582
- if sys.platform == "win32":
583
- # we need 'libpypy-c.lib'. Current distributions of
584
- # pypy (>= 4.1) contain it as 'libs/python27.lib'.
585
- pythonlib = "python{0[0]}{0[1]}".format(sys.version_info)
586
- if hasattr(sys, 'prefix'):
587
- ensure('library_dirs', os.path.join(sys.prefix, 'libs'))
588
- else:
589
- # we need 'libpypy-c.{so,dylib}', which should be by
590
- # default located in 'sys.prefix/bin' for installed
591
- # systems.
592
- if sys.version_info < (3,):
593
- pythonlib = "pypy-c"
594
- else:
595
- pythonlib = "pypy3-c"
596
- if hasattr(sys, 'prefix'):
597
- ensure('library_dirs', os.path.join(sys.prefix, 'bin'))
598
- # On uninstalled pypy's, the libpypy-c is typically found in
599
- # .../pypy/goal/.
600
- if hasattr(sys, 'prefix'):
601
- ensure('library_dirs', os.path.join(sys.prefix, 'pypy', 'goal'))
602
- else:
603
- if sys.platform == "win32":
604
- template = "python%d%d"
605
- if hasattr(sys, 'gettotalrefcount'):
606
- template += '_d'
607
- else:
608
- try:
609
- import sysconfig
610
- except ImportError: # 2.6
611
- from cffi._shimmed_dist_utils import sysconfig
612
- template = "python%d.%d"
613
- if sysconfig.get_config_var('DEBUG_EXT'):
614
- template += sysconfig.get_config_var('DEBUG_EXT')
615
- pythonlib = (template %
616
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
617
- if hasattr(sys, 'abiflags'):
618
- pythonlib += sys.abiflags
619
- ensure('libraries', pythonlib)
620
- if sys.platform == "win32":
621
- ensure('extra_link_args', '/MANIFEST')
622
-
623
- def set_source(self, module_name, source, source_extension='.c', **kwds):
624
- import os
625
- if hasattr(self, '_assigned_source'):
626
- raise ValueError("set_source() cannot be called several times "
627
- "per ffi object")
628
- if not isinstance(module_name, basestring):
629
- raise TypeError("'module_name' must be a string")
630
- if os.sep in module_name or (os.altsep and os.altsep in module_name):
631
- raise ValueError("'module_name' must not contain '/': use a dotted "
632
- "name to make a 'package.module' location")
633
- self._assigned_source = (str(module_name), source,
634
- source_extension, kwds)
635
-
636
- def set_source_pkgconfig(self, module_name, pkgconfig_libs, source,
637
- source_extension='.c', **kwds):
638
- from . import pkgconfig
639
- if not isinstance(pkgconfig_libs, list):
640
- raise TypeError("the pkgconfig_libs argument must be a list "
641
- "of package names")
642
- kwds2 = pkgconfig.flags_from_pkgconfig(pkgconfig_libs)
643
- pkgconfig.merge_flags(kwds, kwds2)
644
- self.set_source(module_name, source, source_extension, **kwds)
645
-
646
- def distutils_extension(self, tmpdir='build', verbose=True):
647
- from cffi._shimmed_dist_utils import mkpath
648
- from .recompiler import recompile
649
- #
650
- if not hasattr(self, '_assigned_source'):
651
- if hasattr(self, 'verifier'): # fallback, 'tmpdir' ignored
652
- return self.verifier.get_extension()
653
- raise ValueError("set_source() must be called before"
654
- " distutils_extension()")
655
- module_name, source, source_extension, kwds = self._assigned_source
656
- if source is None:
657
- raise TypeError("distutils_extension() is only for C extension "
658
- "modules, not for dlopen()-style pure Python "
659
- "modules")
660
- mkpath(tmpdir)
661
- ext, updated = recompile(self, module_name,
662
- source, tmpdir=tmpdir, extradir=tmpdir,
663
- source_extension=source_extension,
664
- call_c_compiler=False, **kwds)
665
- if verbose:
666
- if updated:
667
- sys.stderr.write("regenerated: %r\n" % (ext.sources[0],))
668
- else:
669
- sys.stderr.write("not modified: %r\n" % (ext.sources[0],))
670
- return ext
671
-
672
- def emit_c_code(self, filename):
673
- from .recompiler import recompile
674
- #
675
- if not hasattr(self, '_assigned_source'):
676
- raise ValueError("set_source() must be called before emit_c_code()")
677
- module_name, source, source_extension, kwds = self._assigned_source
678
- if source is None:
679
- raise TypeError("emit_c_code() is only for C extension modules, "
680
- "not for dlopen()-style pure Python modules")
681
- recompile(self, module_name, source,
682
- c_file=filename, call_c_compiler=False,
683
- uses_ffiplatform=False, **kwds)
684
-
685
- def emit_python_code(self, filename):
686
- from .recompiler import recompile
687
- #
688
- if not hasattr(self, '_assigned_source'):
689
- raise ValueError("set_source() must be called before emit_c_code()")
690
- module_name, source, source_extension, kwds = self._assigned_source
691
- if source is not None:
692
- raise TypeError("emit_python_code() is only for dlopen()-style "
693
- "pure Python modules, not for C extension modules")
694
- recompile(self, module_name, source,
695
- c_file=filename, call_c_compiler=False,
696
- uses_ffiplatform=False, **kwds)
697
-
698
- def compile(self, tmpdir='.', verbose=0, target=None, debug=None):
699
- """The 'target' argument gives the final file name of the
700
- compiled DLL. Use '*' to force distutils' choice, suitable for
701
- regular CPython C API modules. Use a file name ending in '.*'
702
- to ask for the system's default extension for dynamic libraries
703
- (.so/.dll/.dylib).
704
-
705
- The default is '*' when building a non-embedded C API extension,
706
- and (module_name + '.*') when building an embedded library.
707
- """
708
- from .recompiler import recompile
709
- #
710
- if not hasattr(self, '_assigned_source'):
711
- raise ValueError("set_source() must be called before compile()")
712
- module_name, source, source_extension, kwds = self._assigned_source
713
- return recompile(self, module_name, source, tmpdir=tmpdir,
714
- target=target, source_extension=source_extension,
715
- compiler_verbose=verbose, debug=debug, **kwds)
716
-
717
- def init_once(self, func, tag):
718
- # Read _init_once_cache[tag], which is either (False, lock) if
719
- # we're calling the function now in some thread, or (True, result).
720
- # Don't call setdefault() in most cases, to avoid allocating and
721
- # immediately freeing a lock; but still use setdefaut() to avoid
722
- # races.
723
- try:
724
- x = self._init_once_cache[tag]
725
- except KeyError:
726
- x = self._init_once_cache.setdefault(tag, (False, allocate_lock()))
727
- # Common case: we got (True, result), so we return the result.
728
- if x[0]:
729
- return x[1]
730
- # Else, it's a lock. Acquire it to serialize the following tests.
731
- with x[1]:
732
- # Read again from _init_once_cache the current status.
733
- x = self._init_once_cache[tag]
734
- if x[0]:
735
- return x[1]
736
- # Call the function and store the result back.
737
- result = func()
738
- self._init_once_cache[tag] = (True, result)
739
- return result
740
-
741
- def embedding_init_code(self, pysource):
742
- if self._embedding:
743
- raise ValueError("embedding_init_code() can only be called once")
744
- # fix 'pysource' before it gets dumped into the C file:
745
- # - remove empty lines at the beginning, so it starts at "line 1"
746
- # - dedent, if all non-empty lines are indented
747
- # - check for SyntaxErrors
748
- import re
749
- match = re.match(r'\s*\n', pysource)
750
- if match:
751
- pysource = pysource[match.end():]
752
- lines = pysource.splitlines() or ['']
753
- prefix = re.match(r'\s*', lines[0]).group()
754
- for i in range(1, len(lines)):
755
- line = lines[i]
756
- if line.rstrip():
757
- while not line.startswith(prefix):
758
- prefix = prefix[:-1]
759
- i = len(prefix)
760
- lines = [line[i:]+'\n' for line in lines]
761
- pysource = ''.join(lines)
762
- #
763
- compile(pysource, "cffi_init", "exec")
764
- #
765
- self._embedding = pysource
766
-
767
- def def_extern(self, *args, **kwds):
768
- raise ValueError("ffi.def_extern() is only available on API-mode FFI "
769
- "objects")
770
-
771
- def list_types(self):
772
- """Returns the user type names known to this FFI instance.
773
- This returns a tuple containing three lists of names:
774
- (typedef_names, names_of_structs, names_of_unions)
775
- """
776
- typedefs = []
777
- structs = []
778
- unions = []
779
- for key in self._parser._declarations:
780
- if key.startswith('typedef '):
781
- typedefs.append(key[8:])
782
- elif key.startswith('struct '):
783
- structs.append(key[7:])
784
- elif key.startswith('union '):
785
- unions.append(key[6:])
786
- typedefs.sort()
787
- structs.sort()
788
- unions.sort()
789
- return (typedefs, structs, unions)
790
-
791
-
792
- def _load_backend_lib(backend, name, flags):
793
- import os
794
- if not isinstance(name, basestring):
795
- if sys.platform != "win32" or name is not None:
796
- return backend.load_library(name, flags)
797
- name = "c" # Windows: load_library(None) fails, but this works
798
- # on Python 2 (backward compatibility hack only)
799
- first_error = None
800
- if '.' in name or '/' in name or os.sep in name:
801
- try:
802
- return backend.load_library(name, flags)
803
- except OSError as e:
804
- first_error = e
805
- import ctypes.util
806
- path = ctypes.util.find_library(name)
807
- if path is None:
808
- if name == "c" and sys.platform == "win32" and sys.version_info >= (3,):
809
- raise OSError("dlopen(None) cannot work on Windows for Python 3 "
810
- "(see http://bugs.python.org/issue23606)")
811
- msg = ("ctypes.util.find_library() did not manage "
812
- "to locate a library called %r" % (name,))
813
- if first_error is not None:
814
- msg = "%s. Additionally, %s" % (first_error, msg)
815
- raise OSError(msg)
816
- return backend.load_library(path, flags)
817
-
818
- def _make_ffi_library(ffi, libname, flags):
819
- backend = ffi._backend
820
- backendlib = _load_backend_lib(backend, libname, flags)
821
- #
822
- def accessor_function(name):
823
- key = 'function ' + name
824
- tp, _ = ffi._parser._declarations[key]
825
- BType = ffi._get_cached_btype(tp)
826
- value = backendlib.load_function(BType, name)
827
- library.__dict__[name] = value
828
- #
829
- def accessor_variable(name):
830
- key = 'variable ' + name
831
- tp, _ = ffi._parser._declarations[key]
832
- BType = ffi._get_cached_btype(tp)
833
- read_variable = backendlib.read_variable
834
- write_variable = backendlib.write_variable
835
- setattr(FFILibrary, name, property(
836
- lambda self: read_variable(BType, name),
837
- lambda self, value: write_variable(BType, name, value)))
838
- #
839
- def addressof_var(name):
840
- try:
841
- return addr_variables[name]
842
- except KeyError:
843
- with ffi._lock:
844
- if name not in addr_variables:
845
- key = 'variable ' + name
846
- tp, _ = ffi._parser._declarations[key]
847
- BType = ffi._get_cached_btype(tp)
848
- if BType.kind != 'array':
849
- BType = model.pointer_cache(ffi, BType)
850
- p = backendlib.load_function(BType, name)
851
- addr_variables[name] = p
852
- return addr_variables[name]
853
- #
854
- def accessor_constant(name):
855
- raise NotImplementedError("non-integer constant '%s' cannot be "
856
- "accessed from a dlopen() library" % (name,))
857
- #
858
- def accessor_int_constant(name):
859
- library.__dict__[name] = ffi._parser._int_constants[name]
860
- #
861
- accessors = {}
862
- accessors_version = [False]
863
- addr_variables = {}
864
- #
865
- def update_accessors():
866
- if accessors_version[0] is ffi._cdef_version:
867
- return
868
- #
869
- for key, (tp, _) in ffi._parser._declarations.items():
870
- if not isinstance(tp, model.EnumType):
871
- tag, name = key.split(' ', 1)
872
- if tag == 'function':
873
- accessors[name] = accessor_function
874
- elif tag == 'variable':
875
- accessors[name] = accessor_variable
876
- elif tag == 'constant':
877
- accessors[name] = accessor_constant
878
- else:
879
- for i, enumname in enumerate(tp.enumerators):
880
- def accessor_enum(name, tp=tp, i=i):
881
- tp.check_not_partial()
882
- library.__dict__[name] = tp.enumvalues[i]
883
- accessors[enumname] = accessor_enum
884
- for name in ffi._parser._int_constants:
885
- accessors.setdefault(name, accessor_int_constant)
886
- accessors_version[0] = ffi._cdef_version
887
- #
888
- def make_accessor(name):
889
- with ffi._lock:
890
- if name in library.__dict__ or name in FFILibrary.__dict__:
891
- return # added by another thread while waiting for the lock
892
- if name not in accessors:
893
- update_accessors()
894
- if name not in accessors:
895
- raise AttributeError(name)
896
- accessors[name](name)
897
- #
898
- class FFILibrary(object):
899
- def __getattr__(self, name):
900
- make_accessor(name)
901
- return getattr(self, name)
902
- def __setattr__(self, name, value):
903
- try:
904
- property = getattr(self.__class__, name)
905
- except AttributeError:
906
- make_accessor(name)
907
- setattr(self, name, value)
908
- else:
909
- property.__set__(self, value)
910
- def __dir__(self):
911
- with ffi._lock:
912
- update_accessors()
913
- return accessors.keys()
914
- def __addressof__(self, name):
915
- if name in library.__dict__:
916
- return library.__dict__[name]
917
- if name in FFILibrary.__dict__:
918
- return addressof_var(name)
919
- make_accessor(name)
920
- if name in library.__dict__:
921
- return library.__dict__[name]
922
- if name in FFILibrary.__dict__:
923
- return addressof_var(name)
924
- raise AttributeError("cffi library has no function or "
925
- "global variable named '%s'" % (name,))
926
- def __cffi_close__(self):
927
- backendlib.close_lib()
928
- self.__dict__.clear()
929
- #
930
- if isinstance(libname, basestring):
931
- try:
932
- if not isinstance(libname, str): # unicode, on Python 2
933
- libname = libname.encode('utf-8')
934
- FFILibrary.__name__ = 'FFILibrary_%s' % libname
935
- except UnicodeError:
936
- pass
937
- library = FFILibrary()
938
- return library, library.__dict__
939
-
940
- def _builtin_function_type(func):
941
- # a hack to make at least ffi.typeof(builtin_function) work,
942
- # if the builtin function was obtained by 'vengine_cpy'.
943
- import sys
944
- try:
945
- module = sys.modules[func.__module__]
946
- ffi = module._cffi_original_ffi
947
- types_of_builtin_funcs = module._cffi_types_of_builtin_funcs
948
- tp = types_of_builtin_funcs[func]
949
- except (KeyError, AttributeError, TypeError):
950
- return None
951
- else:
952
- with ffi._lock:
953
- return ffi._get_cached_btype(tp)