~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/ctypes/__init__.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""create and manipulate C data types in Python"""
 
2
 
 
3
import os as _os, sys as _sys
 
4
 
 
5
__version__ = "1.1.0"
 
6
 
 
7
from _ctypes import Union, Structure, Array
 
8
from _ctypes import _Pointer
 
9
from _ctypes import CFuncPtr as _CFuncPtr
 
10
from _ctypes import __version__ as _ctypes_version
 
11
from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
 
12
from _ctypes import ArgumentError
 
13
 
 
14
from struct import calcsize as _calcsize
 
15
 
 
16
if __version__ != _ctypes_version:
 
17
    raise Exception("Version number mismatch", __version__, _ctypes_version)
 
18
 
 
19
if _os.name in ("nt", "ce"):
 
20
    from _ctypes import FormatError
 
21
 
 
22
DEFAULT_MODE = RTLD_LOCAL
 
23
if _os.name == "posix" and _sys.platform == "darwin":
 
24
    # On OS X 10.3, we use RTLD_GLOBAL as default mode
 
25
    # because RTLD_LOCAL does not work at least on some
 
26
    # libraries.  OS X 10.3 is Darwin 7, so we check for
 
27
    # that.
 
28
 
 
29
    if int(_os.uname()[2].split('.')[0]) < 8:
 
30
        DEFAULT_MODE = RTLD_GLOBAL
 
31
 
 
32
from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
 
33
     FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \
 
34
     FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
 
35
     FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
 
36
 
 
37
"""
 
38
WINOLEAPI -> HRESULT
 
39
WINOLEAPI_(type)
 
40
 
 
41
STDMETHODCALLTYPE
 
42
 
 
43
STDMETHOD(name)
 
44
STDMETHOD_(type, name)
 
45
 
 
46
STDAPICALLTYPE
 
47
"""
 
48
 
 
49
def create_string_buffer(init, size=None):
 
50
    """create_string_buffer(aBytes) -> character array
 
51
    create_string_buffer(anInteger) -> character array
 
52
    create_string_buffer(aString, anInteger) -> character array
 
53
    """
 
54
    if isinstance(init, (str, bytes)):
 
55
        if size is None:
 
56
            size = len(init)+1
 
57
        buftype = c_char * size
 
58
        buf = buftype()
 
59
        buf.value = init
 
60
        return buf
 
61
    elif isinstance(init, int):
 
62
        buftype = c_char * init
 
63
        buf = buftype()
 
64
        return buf
 
65
    raise TypeError(init)
 
66
 
 
67
def c_buffer(init, size=None):
 
68
##    "deprecated, use create_string_buffer instead"
 
69
##    import warnings
 
70
##    warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
 
71
##                  DeprecationWarning, stacklevel=2)
 
72
    return create_string_buffer(init, size)
 
73
 
 
74
_c_functype_cache = {}
 
75
def CFUNCTYPE(restype, *argtypes, **kw):
 
76
    """CFUNCTYPE(restype, *argtypes,
 
77
                 use_errno=False, use_last_error=False) -> function prototype.
 
78
 
 
79
    restype: the result type
 
80
    argtypes: a sequence specifying the argument types
 
81
 
 
82
    The function prototype can be called in different ways to create a
 
83
    callable object:
 
84
 
 
85
    prototype(integer address) -> foreign function
 
86
    prototype(callable) -> create and return a C callable function from callable
 
87
    prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
 
88
    prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
 
89
    prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
 
90
    """
 
91
    flags = _FUNCFLAG_CDECL
 
92
    if kw.pop("use_errno", False):
 
93
        flags |= _FUNCFLAG_USE_ERRNO
 
94
    if kw.pop("use_last_error", False):
 
95
        flags |= _FUNCFLAG_USE_LASTERROR
 
96
    if kw:
 
97
        raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
 
98
    try:
 
99
        return _c_functype_cache[(restype, argtypes, flags)]
 
100
    except KeyError:
 
101
        class CFunctionType(_CFuncPtr):
 
102
            _argtypes_ = argtypes
 
103
            _restype_ = restype
 
104
            _flags_ = flags
 
105
        _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
 
106
        return CFunctionType
 
107
 
 
108
if _os.name in ("nt", "ce"):
 
109
    from _ctypes import LoadLibrary as _dlopen
 
110
    from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
 
111
    if _os.name == "ce":
 
112
        # 'ce' doesn't have the stdcall calling convention
 
113
        _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
 
114
 
 
115
    _win_functype_cache = {}
 
116
    def WINFUNCTYPE(restype, *argtypes, **kw):
 
117
        # docstring set later (very similar to CFUNCTYPE.__doc__)
 
118
        flags = _FUNCFLAG_STDCALL
 
119
        if kw.pop("use_errno", False):
 
120
            flags |= _FUNCFLAG_USE_ERRNO
 
121
        if kw.pop("use_last_error", False):
 
122
            flags |= _FUNCFLAG_USE_LASTERROR
 
123
        if kw:
 
124
            raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
 
125
        try:
 
126
            return _win_functype_cache[(restype, argtypes, flags)]
 
127
        except KeyError:
 
128
            class WinFunctionType(_CFuncPtr):
 
129
                _argtypes_ = argtypes
 
130
                _restype_ = restype
 
131
                _flags_ = flags
 
132
            _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
 
133
            return WinFunctionType
 
134
    if WINFUNCTYPE.__doc__:
 
135
        WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
 
136
 
 
137
elif _os.name == "posix":
 
138
    from _ctypes import dlopen as _dlopen
 
139
 
 
140
from _ctypes import sizeof, byref, addressof, alignment, resize
 
141
from _ctypes import get_errno, set_errno
 
142
from _ctypes import _SimpleCData
 
143
 
 
144
def _check_size(typ, typecode=None):
 
145
    # Check if sizeof(ctypes_type) against struct.calcsize.  This
 
146
    # should protect somewhat against a misconfigured libffi.
 
147
    from struct import calcsize
 
148
    if typecode is None:
 
149
        # Most _type_ codes are the same as used in struct
 
150
        typecode = typ._type_
 
151
    actual, required = sizeof(typ), calcsize(typecode)
 
152
    if actual != required:
 
153
        raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
 
154
                          (typ, actual, required))
 
155
 
 
156
class py_object(_SimpleCData):
 
157
    _type_ = "O"
 
158
    def __repr__(self):
 
159
        try:
 
160
            return super().__repr__()
 
161
        except ValueError:
 
162
            return "%s(<NULL>)" % type(self).__name__
 
163
_check_size(py_object, "P")
 
164
 
 
165
class c_short(_SimpleCData):
 
166
    _type_ = "h"
 
167
_check_size(c_short)
 
168
 
 
169
class c_ushort(_SimpleCData):
 
170
    _type_ = "H"
 
171
_check_size(c_ushort)
 
172
 
 
173
class c_long(_SimpleCData):
 
174
    _type_ = "l"
 
175
_check_size(c_long)
 
176
 
 
177
class c_ulong(_SimpleCData):
 
178
    _type_ = "L"
 
179
_check_size(c_ulong)
 
180
 
 
181
if _calcsize("i") == _calcsize("l"):
 
182
    # if int and long have the same size, make c_int an alias for c_long
 
183
    c_int = c_long
 
184
    c_uint = c_ulong
 
185
else:
 
186
    class c_int(_SimpleCData):
 
187
        _type_ = "i"
 
188
    _check_size(c_int)
 
189
 
 
190
    class c_uint(_SimpleCData):
 
191
        _type_ = "I"
 
192
    _check_size(c_uint)
 
193
 
 
194
class c_float(_SimpleCData):
 
195
    _type_ = "f"
 
196
_check_size(c_float)
 
197
 
 
198
class c_double(_SimpleCData):
 
199
    _type_ = "d"
 
200
_check_size(c_double)
 
201
 
 
202
class c_longdouble(_SimpleCData):
 
203
    _type_ = "g"
 
204
if sizeof(c_longdouble) == sizeof(c_double):
 
205
    c_longdouble = c_double
 
206
 
 
207
if _calcsize("l") == _calcsize("q"):
 
208
    # if long and long long have the same size, make c_longlong an alias for c_long
 
209
    c_longlong = c_long
 
210
    c_ulonglong = c_ulong
 
211
else:
 
212
    class c_longlong(_SimpleCData):
 
213
        _type_ = "q"
 
214
    _check_size(c_longlong)
 
215
 
 
216
    class c_ulonglong(_SimpleCData):
 
217
        _type_ = "Q"
 
218
    ##    def from_param(cls, val):
 
219
    ##        return ('d', float(val), val)
 
220
    ##    from_param = classmethod(from_param)
 
221
    _check_size(c_ulonglong)
 
222
 
 
223
class c_ubyte(_SimpleCData):
 
224
    _type_ = "B"
 
225
c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
 
226
# backward compatibility:
 
227
##c_uchar = c_ubyte
 
228
_check_size(c_ubyte)
 
229
 
 
230
class c_byte(_SimpleCData):
 
231
    _type_ = "b"
 
232
c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
 
233
_check_size(c_byte)
 
234
 
 
235
class c_char(_SimpleCData):
 
236
    _type_ = "c"
 
237
c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
 
238
_check_size(c_char)
 
239
 
 
240
class c_char_p(_SimpleCData):
 
241
    _type_ = "z"
 
242
    if _os.name == "nt":
 
243
        def __repr__(self):
 
244
            if not windll.kernel32.IsBadStringPtrA(self, -1):
 
245
                return "%s(%r)" % (self.__class__.__name__, self.value)
 
246
            return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
 
247
    else:
 
248
        def __repr__(self):
 
249
            return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
 
250
_check_size(c_char_p, "P")
 
251
 
 
252
class c_void_p(_SimpleCData):
 
253
    _type_ = "P"
 
254
c_voidp = c_void_p # backwards compatibility (to a bug)
 
255
_check_size(c_void_p)
 
256
 
 
257
class c_bool(_SimpleCData):
 
258
    _type_ = "?"
 
259
 
 
260
from _ctypes import POINTER, pointer, _pointer_type_cache
 
261
 
 
262
try:
 
263
    from _ctypes import set_conversion_mode
 
264
except ImportError:
 
265
    pass
 
266
else:
 
267
    if _os.name in ("nt", "ce"):
 
268
        set_conversion_mode("mbcs", "ignore")
 
269
    else:
 
270
        set_conversion_mode("ascii", "strict")
 
271
 
 
272
    class c_wchar_p(_SimpleCData):
 
273
        _type_ = "Z"
 
274
 
 
275
    class c_wchar(_SimpleCData):
 
276
        _type_ = "u"
 
277
 
 
278
    POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
 
279
 
 
280
    def create_unicode_buffer(init, size=None):
 
281
        """create_unicode_buffer(aString) -> character array
 
282
        create_unicode_buffer(anInteger) -> character array
 
283
        create_unicode_buffer(aString, anInteger) -> character array
 
284
        """
 
285
        if isinstance(init, (str, bytes)):
 
286
            if size is None:
 
287
                size = len(init)+1
 
288
            buftype = c_wchar * size
 
289
            buf = buftype()
 
290
            buf.value = init
 
291
            return buf
 
292
        elif isinstance(init, int):
 
293
            buftype = c_wchar * init
 
294
            buf = buftype()
 
295
            return buf
 
296
        raise TypeError(init)
 
297
 
 
298
POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
 
299
 
 
300
# XXX Deprecated
 
301
def SetPointerType(pointer, cls):
 
302
    if _pointer_type_cache.get(cls, None) is not None:
 
303
        raise RuntimeError("This type already exists in the cache")
 
304
    if id(pointer) not in _pointer_type_cache:
 
305
        raise RuntimeError("What's this???")
 
306
    pointer.set_type(cls)
 
307
    _pointer_type_cache[cls] = pointer
 
308
    del _pointer_type_cache[id(pointer)]
 
309
 
 
310
# XXX Deprecated
 
311
def ARRAY(typ, len):
 
312
    return typ * len
 
313
 
 
314
################################################################
 
315
 
 
316
 
 
317
class CDLL(object):
 
318
    """An instance of this class represents a loaded dll/shared
 
319
    library, exporting functions using the standard C calling
 
320
    convention (named 'cdecl' on Windows).
 
321
 
 
322
    The exported functions can be accessed as attributes, or by
 
323
    indexing with the function name.  Examples:
 
324
 
 
325
    <obj>.qsort -> callable object
 
326
    <obj>['qsort'] -> callable object
 
327
 
 
328
    Calling the functions releases the Python GIL during the call and
 
329
    reacquires it afterwards.
 
330
    """
 
331
    _func_flags_ = _FUNCFLAG_CDECL
 
332
    _func_restype_ = c_int
 
333
 
 
334
    def __init__(self, name, mode=DEFAULT_MODE, handle=None,
 
335
                 use_errno=False,
 
336
                 use_last_error=False):
 
337
        self._name = name
 
338
        flags = self._func_flags_
 
339
        if use_errno:
 
340
            flags |= _FUNCFLAG_USE_ERRNO
 
341
        if use_last_error:
 
342
            flags |= _FUNCFLAG_USE_LASTERROR
 
343
 
 
344
        class _FuncPtr(_CFuncPtr):
 
345
            _flags_ = flags
 
346
            _restype_ = self._func_restype_
 
347
        self._FuncPtr = _FuncPtr
 
348
 
 
349
        if handle is None:
 
350
            self._handle = _dlopen(self._name, mode)
 
351
        else:
 
352
            self._handle = handle
 
353
 
 
354
    def __repr__(self):
 
355
        return "<%s '%s', handle %x at %x>" % \
 
356
               (self.__class__.__name__, self._name,
 
357
                (self._handle & (_sys.maxsize*2 + 1)),
 
358
                id(self) & (_sys.maxsize*2 + 1))
 
359
 
 
360
    def __getattr__(self, name):
 
361
        if name.startswith('__') and name.endswith('__'):
 
362
            raise AttributeError(name)
 
363
        func = self.__getitem__(name)
 
364
        setattr(self, name, func)
 
365
        return func
 
366
 
 
367
    def __getitem__(self, name_or_ordinal):
 
368
        func = self._FuncPtr((name_or_ordinal, self))
 
369
        if not isinstance(name_or_ordinal, int):
 
370
            func.__name__ = name_or_ordinal
 
371
        return func
 
372
 
 
373
class PyDLL(CDLL):
 
374
    """This class represents the Python library itself.  It allows to
 
375
    access Python API functions.  The GIL is not released, and
 
376
    Python exceptions are handled correctly.
 
377
    """
 
378
    _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
 
379
 
 
380
if _os.name in ("nt", "ce"):
 
381
 
 
382
    class WinDLL(CDLL):
 
383
        """This class represents a dll exporting functions using the
 
384
        Windows stdcall calling convention.
 
385
        """
 
386
        _func_flags_ = _FUNCFLAG_STDCALL
 
387
 
 
388
    # XXX Hm, what about HRESULT as normal parameter?
 
389
    # Mustn't it derive from c_long then?
 
390
    from _ctypes import _check_HRESULT, _SimpleCData
 
391
    class HRESULT(_SimpleCData):
 
392
        _type_ = "l"
 
393
        # _check_retval_ is called with the function's result when it
 
394
        # is used as restype.  It checks for the FAILED bit, and
 
395
        # raises a WindowsError if it is set.
 
396
        #
 
397
        # The _check_retval_ method is implemented in C, so that the
 
398
        # method definition itself is not included in the traceback
 
399
        # when it raises an error - that is what we want (and Python
 
400
        # doesn't have a way to raise an exception in the caller's
 
401
        # frame).
 
402
        _check_retval_ = _check_HRESULT
 
403
 
 
404
    class OleDLL(CDLL):
 
405
        """This class represents a dll exporting functions using the
 
406
        Windows stdcall calling convention, and returning HRESULT.
 
407
        HRESULT error values are automatically raised as WindowsError
 
408
        exceptions.
 
409
        """
 
410
        _func_flags_ = _FUNCFLAG_STDCALL
 
411
        _func_restype_ = HRESULT
 
412
 
 
413
class LibraryLoader(object):
 
414
    def __init__(self, dlltype):
 
415
        self._dlltype = dlltype
 
416
 
 
417
    def __getattr__(self, name):
 
418
        if name[0] == '_':
 
419
            raise AttributeError(name)
 
420
        dll = self._dlltype(name)
 
421
        setattr(self, name, dll)
 
422
        return dll
 
423
 
 
424
    def __getitem__(self, name):
 
425
        return getattr(self, name)
 
426
 
 
427
    def LoadLibrary(self, name):
 
428
        return self._dlltype(name)
 
429
 
 
430
cdll = LibraryLoader(CDLL)
 
431
pydll = LibraryLoader(PyDLL)
 
432
 
 
433
if _os.name in ("nt", "ce"):
 
434
    pythonapi = PyDLL("python dll", None, _sys.dllhandle)
 
435
elif _sys.platform == "cygwin":
 
436
    pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
 
437
else:
 
438
    pythonapi = PyDLL(None)
 
439
 
 
440
 
 
441
if _os.name in ("nt", "ce"):
 
442
    windll = LibraryLoader(WinDLL)
 
443
    oledll = LibraryLoader(OleDLL)
 
444
 
 
445
    if _os.name == "nt":
 
446
        GetLastError = windll.kernel32.GetLastError
 
447
    else:
 
448
        GetLastError = windll.coredll.GetLastError
 
449
    from _ctypes import get_last_error, set_last_error
 
450
 
 
451
    def WinError(code=None, descr=None):
 
452
        if code is None:
 
453
            code = GetLastError()
 
454
        if descr is None:
 
455
            descr = FormatError(code).strip()
 
456
        return WindowsError(code, descr)
 
457
 
 
458
_pointer_type_cache[None] = c_void_p
 
459
 
 
460
if sizeof(c_uint) == sizeof(c_void_p):
 
461
    c_size_t = c_uint
 
462
elif sizeof(c_ulong) == sizeof(c_void_p):
 
463
    c_size_t = c_ulong
 
464
elif sizeof(c_ulonglong) == sizeof(c_void_p):
 
465
    c_size_t = c_ulonglong
 
466
 
 
467
# functions
 
468
 
 
469
from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
 
470
 
 
471
## void *memmove(void *, const void *, size_t);
 
472
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
 
473
 
 
474
## void *memset(void *, int, size_t)
 
475
memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
 
476
 
 
477
def PYFUNCTYPE(restype, *argtypes):
 
478
    class CFunctionType(_CFuncPtr):
 
479
        _argtypes_ = argtypes
 
480
        _restype_ = restype
 
481
        _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
 
482
    return CFunctionType
 
483
 
 
484
_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
 
485
def cast(obj, typ):
 
486
    return _cast(obj, obj, typ)
 
487
 
 
488
_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
 
489
def string_at(ptr, size=-1):
 
490
    """string_at(addr[, size]) -> string
 
491
 
 
492
    Return the string at addr."""
 
493
    return _string_at(ptr, size)
 
494
 
 
495
try:
 
496
    from _ctypes import _wstring_at_addr
 
497
except ImportError:
 
498
    pass
 
499
else:
 
500
    _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
 
501
    def wstring_at(ptr, size=-1):
 
502
        """wstring_at(addr[, size]) -> string
 
503
 
 
504
        Return the string at addr."""
 
505
        return _wstring_at(ptr, size)
 
506
 
 
507
 
 
508
if _os.name in ("nt", "ce"): # COM stuff
 
509
    def DllGetClassObject(rclsid, riid, ppv):
 
510
        try:
 
511
            ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
 
512
        except ImportError:
 
513
            return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
 
514
        else:
 
515
            return ccom.DllGetClassObject(rclsid, riid, ppv)
 
516
 
 
517
    def DllCanUnloadNow():
 
518
        try:
 
519
            ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
 
520
        except ImportError:
 
521
            return 0 # S_OK
 
522
        return ccom.DllCanUnloadNow()
 
523
 
 
524
from ctypes._endian import BigEndianStructure, LittleEndianStructure
 
525
 
 
526
# Fill in specifically-sized types
 
527
c_int8 = c_byte
 
528
c_uint8 = c_ubyte
 
529
for kind in [c_short, c_int, c_long, c_longlong]:
 
530
    if sizeof(kind) == 2: c_int16 = kind
 
531
    elif sizeof(kind) == 4: c_int32 = kind
 
532
    elif sizeof(kind) == 8: c_int64 = kind
 
533
for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
 
534
    if sizeof(kind) == 2: c_uint16 = kind
 
535
    elif sizeof(kind) == 4: c_uint32 = kind
 
536
    elif sizeof(kind) == 8: c_uint64 = kind
 
537
del(kind)
 
538
 
 
539
# XXX for whatever reasons, creating the first instance of a callback
 
540
# function is needed for the unittests on Win64 to succeed.  This MAY
 
541
# be a compiler bug, since the problem occurs only when _ctypes is
 
542
# compiled with the MS SDK compiler.  Or an uninitialized variable?
 
543
CFUNCTYPE(c_int)(lambda: None)