cwrap 1.6.6__py3-none-any.whl → 1.6.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cwrap/__init__.py CHANGED
@@ -28,26 +28,36 @@ the process of interacting with a C library:
28
28
  FILE pointer.
29
29
  """
30
30
 
31
- try: from .version import version as __version__
32
- except ImportError: __version__ = '0.0.0'
31
+ try:
32
+ from .version import version as __version__
33
+ except ImportError:
34
+ __version__ = "0.0.0"
33
35
 
34
- __author__ = 'Statoil ASA'
35
- __copyright__ = 'Copyright 2016, Statoil ASA'
36
+ __author__ = "Statoil ASA"
37
+ __copyright__ = "Copyright 2016, Statoil ASA"
36
38
  __credits__ = __author__
37
- __license__ = 'GPL'
39
+ __license__ = "GPL"
38
40
  __maintainer__ = __author__
39
- __email__ = 'fg_gpl@statoil.com'
40
- __status__ = 'Prototype'
41
+ __email__ = "fg_gpl@statoil.com"
42
+ __status__ = "Prototype"
41
43
 
42
44
  from .basecclass import BaseCClass
43
45
  from .basecenum import BaseCEnum
44
46
  from .basecvalue import BaseCValue
45
-
46
- from .cfile import CFILE, copen as open
47
- from .clib import load, lib_name
48
-
47
+ from .cfile import CFILE
48
+ from .cfile import copen as open
49
+ from .clib import lib_name, load
49
50
  from .metacwrap import MetaCWrap
50
- from .prototype import REGISTERED_TYPES, Prototype, PrototypeError
51
-
52
- __all__ = ['BaseCClass', 'BaseCEnum', 'BaseCValue', 'CFILE', 'open',
53
- 'MetaCWrap', 'Prototype', 'load', 'lib_name']
51
+ from .prototype import REGISTERED_TYPES, Prototype, PrototypeError # noqa
52
+
53
+ __all__ = [
54
+ "BaseCClass",
55
+ "BaseCEnum",
56
+ "BaseCValue",
57
+ "CFILE",
58
+ "open",
59
+ "MetaCWrap",
60
+ "Prototype",
61
+ "load",
62
+ "lib_name",
63
+ ]
cwrap/basecclass.py CHANGED
@@ -14,16 +14,12 @@
14
14
  # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
15
15
  # for more details.
16
16
 
17
- from __future__ import (absolute_import, division,
18
- print_function, unicode_literals)
19
-
20
- import six
21
-
22
17
  import ctypes
18
+
23
19
  from .metacwrap import MetaCWrap
24
20
 
25
- @six.add_metaclass(MetaCWrap)
26
- class BaseCClass(object):
21
+
22
+ class BaseCClass(metaclass=MetaCWrap):
27
23
  namespaces = {}
28
24
 
29
25
  def __init__(self, c_pointer, parent=None, is_reference=False):
@@ -31,14 +27,16 @@ class BaseCClass(object):
31
27
  raise ValueError("Must have a valid (not null) pointer value!")
32
28
 
33
29
  if c_pointer < 0:
34
- raise ValueError("The pointer value is negative! This may be correct, but usually is not!")
30
+ raise ValueError(
31
+ "The pointer value is negative! This may be correct, but usually is not!"
32
+ )
35
33
 
36
34
  self.__c_pointer = c_pointer
37
35
  self.__parent = parent
38
36
  self.__is_reference = is_reference
39
37
 
40
38
  def __new__(cls, *more, **kwargs):
41
- obj = super(BaseCClass, cls).__new__(cls)
39
+ obj = super().__new__(cls)
42
40
  obj.__c_pointer = None
43
41
  obj.__parent = None
44
42
  obj.__is_reference = False
@@ -52,7 +50,7 @@ class BaseCClass(object):
52
50
  return self.__c_pointer
53
51
 
54
52
  def _ad_str(self):
55
- return 'at 0x%x' % self._address()
53
+ return f"at 0x{self._address():x}"
56
54
 
57
55
  @classmethod
58
56
  def from_param(cls, c_class_object):
@@ -61,14 +59,16 @@ class BaseCClass(object):
61
59
 
62
60
  if c_class_object is None:
63
61
  return ctypes.c_void_p()
64
- else:
65
- return ctypes.c_void_p(c_class_object.__c_pointer)
62
+
63
+ return ctypes.c_void_p(c_class_object.__c_pointer)
66
64
 
67
65
  @classmethod
68
66
  def createPythonObject(cls, c_pointer):
69
67
  if c_pointer is not None:
70
68
  new_obj = cls.__new__(cls)
71
- BaseCClass.__init__(new_obj, c_pointer=c_pointer, parent=None, is_reference=False)
69
+ BaseCClass.__init__(
70
+ new_obj, c_pointer=c_pointer, parent=None, is_reference=False
71
+ )
72
72
  return new_obj
73
73
  else:
74
74
  return None
@@ -77,7 +77,9 @@ class BaseCClass(object):
77
77
  def createCReference(cls, c_pointer, parent=None):
78
78
  if c_pointer is not None:
79
79
  new_obj = cls.__new__(cls)
80
- BaseCClass.__init__(new_obj, c_pointer=c_pointer, parent=parent, is_reference=True)
80
+ BaseCClass.__init__(
81
+ new_obj, c_pointer=c_pointer, parent=parent, is_reference=True
82
+ )
81
83
  return new_obj
82
84
  else:
83
85
  return None
@@ -90,7 +92,6 @@ class BaseCClass(object):
90
92
  self.__is_reference = True
91
93
  self.__parent = parent
92
94
 
93
-
94
95
  def setParent(self, parent=None):
95
96
  if self.__is_reference:
96
97
  self.__parent = parent
@@ -100,7 +101,7 @@ class BaseCClass(object):
100
101
  return self
101
102
 
102
103
  def isReference(self):
103
- """ @rtype: bool """
104
+ """@rtype: bool"""
104
105
  return self.__is_reference
105
106
 
106
107
  def parent(self):
@@ -113,7 +114,7 @@ class BaseCClass(object):
113
114
  if isinstance(other, BaseCClass):
114
115
  return self.__c_pointer == other.__c_pointer
115
116
  else:
116
- return super(BaseCClass , self) == other
117
+ return super() == other
117
118
 
118
119
  def __hash__(self):
119
120
  # Similar to last resort comparison; this returns the hash of the
@@ -123,37 +124,31 @@ class BaseCClass(object):
123
124
  def free(self):
124
125
  raise NotImplementedError("A BaseCClass requires a free method implementation!")
125
126
 
126
- def _create_repr(self, args = ''):
127
+ def _create_repr(self, args=""):
127
128
  """Representation on the form (e.g.) 'EclFile(...) at 0x1729'."""
128
- return "{0}({1}) {2}".format(self.__class__.__name__, args, self._ad_str())
129
+ return f"{self.__class__.__name__}({args}) {self._ad_str()}"
129
130
 
130
131
  def __repr__(self):
131
132
  """Representation on the form (e.g.) 'EclFile(...) at 0x1729'."""
132
133
  return self._create_repr()
133
134
 
134
135
  def __del__(self):
135
- if self.free is not None:
136
- if not self.__is_reference:
137
- # Important to check the c_pointer; in the case of failed object creation
138
- # we can have a Python object with c_pointer == None.
139
- if self.__c_pointer:
140
- self.free()
136
+ if self.free is not None and not self.__is_reference and self.__c_pointer:
137
+ # Important to check the c_pointer; in the case of failed object creation
138
+ # we can have a Python object with c_pointer == None.
139
+ self.free()
141
140
 
142
141
  def _invalidateCPointer(self):
143
142
  self.__c_pointer = None
144
143
 
145
-
146
144
  def __bool__(self):
147
145
  """The BaseCClass instance will evaluate to true if it is bound to an
148
146
  underlying C object, otherwise it will evaluate to False. More
149
147
  elaborate bool tests should be implemented in the derived
150
148
  class.
151
149
  """
152
- if self.__c_pointer:
153
- return True
154
- else:
155
- return False
156
150
 
151
+ return bool(self.__c_pointer)
157
152
 
158
153
  def __nonzero__(self):
159
- return self.__bool__( )
154
+ return self.__bool__()
cwrap/basecenum.py CHANGED
@@ -14,17 +14,12 @@
14
14
  # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
15
15
  # for more details.
16
16
 
17
- from __future__ import absolute_import, division, print_function, unicode_literals
18
-
19
17
  import ctypes
20
18
 
21
- import six
22
-
23
19
  from .metacwrap import MetaCWrap
24
20
 
25
21
 
26
- @six.add_metaclass(MetaCWrap)
27
- class BaseCEnum(object):
22
+ class BaseCEnum(metaclass=MetaCWrap):
28
23
  enum_namespace = {}
29
24
 
30
25
  def __init__(self, *args, **kwargs):
@@ -36,11 +31,11 @@ class BaseCEnum(object):
36
31
  enum = cls.__resolveEnum(args[0])
37
32
 
38
33
  if enum is None:
39
- raise ValueError("Unknown enum value: %i" % args[0])
34
+ raise ValueError(f"Unknown enum value: {args[0]}")
40
35
 
41
36
  return enum
42
37
  else:
43
- obj = super(BaseCEnum, cls).__new__(cls, *args)
38
+ obj = super().__new__(cls, *args)
44
39
  obj.name = None
45
40
  obj.value = None
46
41
  return obj
@@ -57,7 +52,7 @@ class BaseCEnum(object):
57
52
  if enum.name == name:
58
53
  return enum
59
54
 
60
- raise ValueError("No such enum:%s" % name)
55
+ raise ValueError(f"No such enum: {name}")
61
56
 
62
57
  @classmethod
63
58
  def addEnum(cls, name, value):
@@ -102,7 +97,7 @@ class BaseCEnum(object):
102
97
  cn = self.__class__.__name__
103
98
  na = self.name
104
99
  va = self.value
105
- return '%s(name = "%s", value = %s)' % (cn, na, va)
100
+ return f'{cn}(name = "{na}", value = {va})'
106
101
 
107
102
  def __add__(self, other):
108
103
  self.__assertOtherIsSameType(other)
@@ -126,7 +121,7 @@ class BaseCEnum(object):
126
121
 
127
122
  def __int__(self):
128
123
  return self.value
129
-
124
+
130
125
  def __index__(self):
131
126
  return self.value
132
127
 
@@ -136,7 +131,7 @@ class BaseCEnum(object):
136
131
  @classmethod
137
132
  def __createEnum(cls, value):
138
133
  enum = cls.__new__(cls)
139
- enum.name = "Unnamed '%s' enum with value: %i" % (str(cls.__name__), value)
134
+ enum.name = f"Unnamed '{cls.__name__}' enum with value: {value}"
140
135
  enum.value = value
141
136
  return enum
142
137
 
@@ -157,22 +152,18 @@ class BaseCEnum(object):
157
152
  return None
158
153
 
159
154
  def __assertOtherIsSameType(self, other):
160
- assert isinstance(
161
- other, self.__class__
162
- ), "Can only operate on enums of same type: %s =! %s" % (
163
- self.__class__.__name__,
164
- other.__class__.__name__,
155
+ assert isinstance(other, self.__class__), (
156
+ f"Can only operate on enums of same type: {self.__class__.__name__} != {other.__class__.__name__}"
165
157
  )
166
158
 
167
159
  @classmethod
168
160
  def populateEnum(cls, library, enum_provider_function):
169
161
  try:
170
162
  func = getattr(library, enum_provider_function)
171
- except AttributeError:
163
+ except AttributeError as err:
172
164
  raise ValueError(
173
- "Could not find enum description function: %s - can not load enum: %s."
174
- % (enum_provider_function, cls.__name__)
175
- )
165
+ f"Could not find enum description function: {enum_provider_function} - can not load enum: {cls.__name__}."
166
+ ) from err
176
167
 
177
168
  func.restype = ctypes.c_char_p
178
169
  func.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
cwrap/basecvalue.py CHANGED
@@ -14,30 +14,52 @@
14
14
  # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
15
15
  # for more details.
16
16
 
17
- from __future__ import (absolute_import, division,
18
- print_function, unicode_literals)
19
-
20
- import six
21
-
22
- from ctypes import (pointer, c_long, c_int, c_bool, c_float, c_double, c_byte,
23
- c_short, c_char, c_ubyte, c_ushort, c_uint, c_ulong)
17
+ from ctypes import (
18
+ c_bool,
19
+ c_byte,
20
+ c_char,
21
+ c_double,
22
+ c_float,
23
+ c_int,
24
+ c_long,
25
+ c_short,
26
+ c_ubyte,
27
+ c_uint,
28
+ c_ulong,
29
+ c_ushort,
30
+ pointer,
31
+ )
24
32
 
25
33
  from .metacwrap import MetaCWrap
26
34
 
27
- @six.add_metaclass(MetaCWrap)
28
- class BaseCValue(object):
35
+
36
+ class BaseCValue(metaclass=MetaCWrap):
29
37
  DATA_TYPE = None
30
- LEGAL_TYPES = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, c_long, c_ulong, c_bool, c_char, c_float, c_double]
38
+ LEGAL_TYPES = [
39
+ c_byte,
40
+ c_ubyte,
41
+ c_short,
42
+ c_ushort,
43
+ c_int,
44
+ c_uint,
45
+ c_long,
46
+ c_ulong,
47
+ c_bool,
48
+ c_char,
49
+ c_float,
50
+ c_double,
51
+ ]
31
52
 
32
53
  def __init__(self, value):
33
- super(BaseCValue, self).__init__()
54
+ super().__init__()
34
55
 
35
56
  if not self.DATA_TYPE in self.LEGAL_TYPES:
36
- raise ValueError("DATA_TYPE must be one of these CTypes classes: %s" % BaseCValue.LEGAL_TYPES)
57
+ raise ValueError(
58
+ f"DATA_TYPE must be one of these CTypes classes: {BaseCValue.LEGAL_TYPES}"
59
+ )
37
60
 
38
61
  self.__value = self.cast(value)
39
62
 
40
-
41
63
  def value(self):
42
64
  return self.__value.value
43
65
 
cwrap/cfile.py CHANGED
@@ -15,160 +15,95 @@
15
15
  # for more details.
16
16
 
17
17
  import os
18
- import six
19
- import sys
20
- from .prototype import Prototype
21
- from .basecclass import BaseCClass
22
18
 
19
+ from .basecclass import BaseCClass
20
+ from .clib import load as cwrapload
21
+ from .prototype import Prototype
23
22
 
24
- if six.PY2:
25
- import ctypes
26
-
27
- def copen(filename, mode='r'):
28
- """
29
- This is a compatibility layer for functions taking FILE* pointers, and
30
- should not be used unless absolutely needed.
31
23
 
32
- In Python 2 this function is simply an alias for open. In Python 3,
33
- however, it returns an instance of CWrapFile, a very light weight
34
- wrapper around a FILE* instance.
35
- """
36
- return open(filename, mode)
37
-
38
- class CFILE(BaseCClass):
39
- """
40
- Utility class to map a Python file handle <-> FILE* in C
41
- """
42
- TYPE_NAME = "FILE"
43
-
44
- _as_file = Prototype(ctypes.pythonapi, "void* PyFile_AsFile(py_object)")
45
-
46
- def __init__(self, py_file):
47
- """
48
- Takes a python file handle and looks up the underlying FILE *
49
-
50
- The purpose of the CFILE class is to be able to use python
51
- file handles when calling C functions which expect a FILE
52
- pointer. A CFILE instance should be created based on the
53
- Python file handle, and that should be passed to the function
54
- expecting a FILE pointer.
55
-
56
- The implementation is based on the ctypes object
57
- pythonapi which is ctypes wrapping of the CPython api.
58
-
59
- C-function:
60
- void fprintf_hello(FILE * stream , const char * msg);
61
-
62
- Python wrapper:
63
- lib = clib.load( "lib.so" )
64
- fprintf_hello = Prototype(lib, "void fprintf_hello( FILE , char* )")
65
-
66
- Python use:
67
- py_fileH = open("file.txt" , "w")
68
- fprintf_hello( CFILE( py_fileH ) , "Message ...")
69
- py_fileH.close()
70
-
71
- If the supplied argument is not of type py_file the function
72
- will raise a TypeException.
73
-
74
- Examples: ecl.ecl.ecl_kw.EclKW.fprintf_grdecl()
75
- """
76
- c_ptr = self._as_file(py_file)
77
- try:
78
- super(CFILE, self).__init__(c_ptr)
79
- except ValueError:
80
- raise TypeError("Sorry - the supplied argument is not a valid "
81
- " Python file handle!")
82
-
83
- self.py_file = py_file
84
-
85
- def __del__(self):
86
- pass
87
-
88
-
89
- if six.PY3:
90
- from .clib import load as cwrapload
91
-
92
- class LibcPrototype(Prototype):
93
- # Load the c standard library (on Linux passsing None does the trick)
94
- lib = cwrapload('msvcrt' if os.name == 'nt' else None)
95
-
96
- def __init__(self, prototype, bind=False, allow_attribute_error=False):
97
- super(LibcPrototype, self).__init__(
98
- LibcPrototype.lib,
99
- prototype,
100
- bind=bind,
101
- allow_attribute_error=allow_attribute_error)
102
-
103
- def copen(filename, mode='r'):
104
- """
105
- This is a compatibility layer for functions taking FILE* pointers, and
106
- should not be used unless absolutely needed.
107
-
108
- In Python 2 this function is simply an alias for open. In Python 3,
109
- however, it returns an instance of CWrapFile, a very lightweight
110
- wrapper around a FILE* instance.
111
- """
112
- return CWrapFile(filename, mode)
113
-
114
- class CWrapFile(BaseCClass):
115
- """
116
- This is a compatibility layer for functions taking FILE* pointers, and
117
- should not be used unless absolutely needed.
118
-
119
- CWrapFile is a very lightweight wrapper around FILE* instances. It is
120
- meant be used inplace of python file objects that are to be passed to
121
- foreign function calls under python 3.
122
-
123
- Example:
124
- with cwrap.open('filename', 'mode') as f:
125
- foreign_function_call(f)
126
- """
127
-
128
- TYPE_NAME = "FILE"
129
-
130
- _fopen = LibcPrototype("void* fopen (char*, char*)")
131
- _fclose = LibcPrototype("int fclose (FILE)", bind=True)
132
- _fflush = LibcPrototype("int fflush (FILE)", bind=True)
133
-
134
- def __init__(self, fname, mode):
135
- c_ptr = self._fopen(fname, mode)
136
- self._mode = mode
137
- self._fname = fname
138
- self._closed = False
139
-
140
- try:
141
- super(CWrapFile, self).__init__(c_ptr)
142
- except ValueError:
143
- self._closed = True
144
- raise IOError('Could not open file "{}" in mode {}'
145
- .format(fname, mode))
146
-
147
- def close(self):
148
- if not self._closed:
149
- self._fflush()
150
- cs = self._fclose()
151
- if (cs != 0):
152
- raise IOError("Failed to close file")
153
- self._closed = True
154
-
155
- def __enter__(self):
156
- return self
157
-
158
- def __exit__(self, exc_type, exc_val, exc_tb):
159
- self.close()
160
- return exc_type is None
161
-
162
- def free(self):
163
- self.close()
164
-
165
- def __del__(self):
166
- self.close()
167
-
168
- def CFILE(f):
169
- if not isinstance(f, CWrapFile):
170
- raise TypeError("This function requires the use of CWrapFile, "
171
- "not {} when running Python 3. See "
172
- "help(cwrap.open) for more info"
173
- .format(type(f).__name__))
174
- return f
24
+ class LibcPrototype(Prototype):
25
+ # Load the c standard library (on Linux passsing None does the trick)
26
+ lib = cwrapload("msvcrt" if os.name == "nt" else None)
27
+
28
+ def __init__(self, prototype, bind=False, allow_attribute_error=False):
29
+ super().__init__(
30
+ LibcPrototype.lib,
31
+ prototype,
32
+ bind=bind,
33
+ allow_attribute_error=allow_attribute_error,
34
+ )
35
+
36
+
37
+ def copen(filename, mode="r"):
38
+ """
39
+ This is a compatibility layer for functions taking FILE* pointers, and
40
+ should not be used unless absolutely needed.
41
+
42
+ It returns an instance of CWrapFile, a very lightweight
43
+ wrapper around a FILE* instance.
44
+ """
45
+ return CWrapFile(filename, mode)
46
+
47
+
48
+ class CWrapFile(BaseCClass):
49
+ """
50
+ This is a compatibility layer for functions taking FILE* pointers, and
51
+ should not be used unless absolutely needed.
52
+
53
+ CWrapFile is a very lightweight wrapper around FILE* instances. It is
54
+ meant be used inplace of python file objects that are to be passed to
55
+ foreign function calls under python 3.
56
+
57
+ Example:
58
+ with cwrap.open('filename', 'mode') as f:
59
+ foreign_function_call(f)
60
+ """
61
+
62
+ TYPE_NAME = "FILE"
63
+
64
+ _fopen = LibcPrototype("void* fopen (char*, char*)")
65
+ _fclose = LibcPrototype("int fclose (FILE)", bind=True)
66
+ _fflush = LibcPrototype("int fflush (FILE)", bind=True)
67
+
68
+ def __init__(self, fname, mode):
69
+ c_ptr = self._fopen(fname, mode)
70
+ self._mode = mode
71
+ self._fname = fname
72
+ self._closed = False
73
+
74
+ try:
75
+ super().__init__(c_ptr)
76
+ except ValueError as err:
77
+ self._closed = True
78
+ raise OSError(f'Could not open file "{fname}" in mode {mode}') from err
79
+
80
+ def close(self):
81
+ if not self._closed:
82
+ self._fflush()
83
+ cs = self._fclose()
84
+ if cs != 0:
85
+ raise OSError("Failed to close file")
86
+ self._closed = True
87
+
88
+ def __enter__(self):
89
+ return self
90
+
91
+ def __exit__(self, exc_type, exc_val, exc_tb):
92
+ self.close()
93
+ return exc_type is None
94
+
95
+ def free(self):
96
+ self.close()
97
+
98
+ def __del__(self):
99
+ self.close()
100
+
101
+
102
+ def CFILE(f):
103
+ if not isinstance(f, CWrapFile):
104
+ raise TypeError(
105
+ "This function requires the use of CWrapFile, "
106
+ f"not {type(f).__name__} when running Python 3. See "
107
+ "help(cwrap.open) for more info"
108
+ )
109
+ return f
cwrap/clib.py CHANGED
@@ -31,45 +31,46 @@ be invoked when loading libert_geometry, and that could in principle
31
31
  lead to loading a different version of libert_util.so
32
32
  """
33
33
 
34
- import platform
35
34
  import ctypes
36
35
  import os
36
+ import platform
37
37
 
38
- so_extension = {"linux" : "so",
39
- "linux2" : "so",
40
- "linux3" : "so",
41
- "windows": "dll",
42
- "darwin" : "dylib" }
38
+ so_extension = {
39
+ "linux": "so",
40
+ "linux2": "so",
41
+ "linux3": "so",
42
+ "windows": "dll",
43
+ "darwin": "dylib",
44
+ }
43
45
 
44
46
 
45
47
  # Passing None to the CDLL() function means to open a lib handle to
46
48
  # the current runnning process, i.e. like dlopen( NULL ). We must
47
49
  # special case this to avoid creating the bogus argument 'None.so'.
48
50
 
49
- def lib_name(lib , path = None , so_version = None, so_ext = None):
51
+
52
+ def lib_name(lib, path=None, so_version=None, so_ext=None):
50
53
  if lib is None:
51
54
  return None
52
55
  else:
53
56
  platform_key = platform.system().lower()
54
57
  if so_version is None:
55
- so_version = ''
58
+ so_version = ""
56
59
 
57
60
  if so_ext:
58
- so_name = "%s.%s%s" % (lib, so_ext, so_version)
61
+ so_name = f"{lib}.{so_ext}{so_version}"
59
62
  elif platform_key == "darwin":
60
- so_name = "%s%s.%s" % (lib, so_version, so_extension[ platform_key ])
63
+ so_name = f"{lib}{so_version}.{so_extension[platform_key]}"
61
64
  else:
62
- so_name = "%s.%s%s" % (lib, so_extension[ platform_key ], so_version)
65
+ so_name = f"{lib}.{so_extension[platform_key]}{so_version}"
63
66
 
64
67
  if path:
65
- return os.path.join( path , so_name )
68
+ return os.path.join(path, so_name)
66
69
  else:
67
70
  return so_name
68
71
 
69
72
 
70
-
71
-
72
- def load( lib, so_version = None, path = None, so_ext = None):
73
+ def load(lib, so_version=None, path=None, so_ext=None):
73
74
  """Thin wrapper around the ctypes.CDLL function for loading shared
74
75
  library.
75
76
 
@@ -79,32 +80,33 @@ def load( lib, so_version = None, path = None, so_ext = None):
79
80
  """
80
81
 
81
82
  dll = None
82
- lib_files = [ lib_name( lib, path = None, so_version = so_version ),
83
- lib_name( lib, path = None, so_version = so_version, so_ext = so_ext ),
84
- lib_name( lib, path = path, so_version = so_version ),
85
- lib_name( lib, path = path, so_version = so_version, so_ext = so_ext )
86
- ]
83
+ lib_files = [
84
+ lib_name(lib, path=None, so_version=so_version),
85
+ lib_name(lib, path=None, so_version=so_version, so_ext=so_ext),
86
+ lib_name(lib, path=path, so_version=so_version),
87
+ lib_name(lib, path=path, so_version=so_version, so_ext=so_ext),
88
+ ]
87
89
 
88
90
  for lib_file in lib_files:
89
91
  try:
90
- dll = ctypes.CDLL(lib_file , ctypes.RTLD_GLOBAL)
92
+ dll = ctypes.CDLL(lib_file, ctypes.RTLD_GLOBAL)
91
93
  return dll
92
94
  except Exception as exc:
93
95
  error = exc
94
96
 
95
- error_msg = "\nFailed to load shared library:%s\n\ndlopen() error: %s\n" % (lib , error)
97
+ error_msg = f"\nFailed to load shared library:{lib}\n\ndlopen() error: {error}\n"
96
98
 
97
99
  LD_LIBRARY_PATH = os.getenv("LD_LIBRARY_PATH")
98
100
  if not LD_LIBRARY_PATH:
99
101
  LD_LIBRARY_PATH = ""
100
102
 
101
- error_msg += """
103
+ error_msg += f"""
102
104
  The runtime linker has searched through the default location of shared
103
105
  libraries, and also the locations mentioned in your LD_LIBRARY_PATH
104
106
  variable. Your current LD_LIBRARY_PATH setting is:
105
107
 
106
- LD_LIBRARY_PATH: %s
108
+ LD_LIBRARY_PATH: {LD_LIBRARY_PATH}
107
109
 
108
110
  You might need to update this variable?
109
- """ % LD_LIBRARY_PATH
111
+ """
110
112
  raise ImportError(error_msg)
cwrap/metacwrap.py CHANGED
@@ -15,27 +15,23 @@
15
15
  # for more details.
16
16
 
17
17
  import re
18
- from types import MethodType
19
18
 
20
19
  from .prototype import Prototype
21
20
 
22
21
 
23
22
  def snakeCase(name):
24
- s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
25
- return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
23
+ s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
24
+ return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
26
25
 
27
26
 
28
27
  class MetaCWrap(type):
29
28
  def __init__(cls, name, bases, attrs):
30
- super(MetaCWrap, cls).__init__(name, bases, attrs)
29
+ super().__init__(name, bases, attrs)
31
30
 
32
31
  is_return_type = False
33
32
  storage_type = None
34
33
 
35
- if "TYPE_NAME" in attrs:
36
- type_name = attrs["TYPE_NAME"]
37
- else:
38
- type_name = snakeCase(name)
34
+ type_name = attrs["TYPE_NAME"] if "TYPE_NAME" in attrs else snakeCase(name)
39
35
 
40
36
  if hasattr(cls, "DATA_TYPE") or hasattr(cls, "enums"):
41
37
  is_return_type = True
@@ -43,14 +39,25 @@ class MetaCWrap(type):
43
39
  if hasattr(cls, "storageType"):
44
40
  storage_type = cls.storageType()
45
41
 
46
- Prototype.registerType(type_name, cls, is_return_type=is_return_type, storage_type=storage_type)
42
+ Prototype.registerType(
43
+ type_name, cls, is_return_type=is_return_type, storage_type=storage_type
44
+ )
47
45
 
48
46
  if hasattr(cls, "createCReference"):
49
- Prototype.registerType("%s_ref" % type_name, cls.createCReference, is_return_type=True, storage_type=storage_type)
47
+ Prototype.registerType(
48
+ f"{type_name}_ref",
49
+ cls.createCReference,
50
+ is_return_type=True,
51
+ storage_type=storage_type,
52
+ )
50
53
 
51
54
  if hasattr(cls, "createPythonObject"):
52
- Prototype.registerType("%s_obj" % type_name, cls.createPythonObject, is_return_type=True, storage_type=storage_type)
53
-
55
+ Prototype.registerType(
56
+ f"{type_name}_obj",
57
+ cls.createPythonObject,
58
+ is_return_type=True,
59
+ storage_type=storage_type,
60
+ )
54
61
 
55
62
  for key, attr in attrs.items():
56
63
  if isinstance(attr, Prototype):
cwrap/prototype.py CHANGED
@@ -20,10 +20,8 @@ import re
20
20
  import sys
21
21
  from types import MethodType
22
22
 
23
- import six
24
23
 
25
-
26
- class TypeDefinition(object):
24
+ class TypeDefinition:
27
25
  def __init__(self, type_class_or_function, is_return_type, storage_type, errcheck):
28
26
  self.storage_type = storage_type
29
27
  self.is_return_type = is_return_type
@@ -34,36 +32,32 @@ class TypeDefinition(object):
34
32
  self.errcheck = errcheck
35
33
 
36
34
 
37
- if six.PY3:
38
-
39
- class CStringHelper(object):
40
- @classmethod
41
- def from_param(cls, value):
42
- if value is None:
43
- return None
44
- elif isinstance(value, bytes):
45
- return value
46
- elif isinstance(value, ctypes.Array):
47
- return value
48
- else:
49
- e = value.encode()
50
- return e
51
-
52
- @staticmethod
53
- def toStr(result, func, arguments):
54
- """
55
- Transform a foreign char* type to str (if python 3).
56
-
57
- ctypes functions have an attribute called errcheck that can not
58
- only be used for error checking but also to alter the result. If
59
- errcheck is defined, the value returned from that function is what
60
- is returned from the foreign function call. In this case, C returns
61
- strings in the form of zero-terminated char* strings. To use these
62
- as python strings (str) they must be decoded.
63
- """
64
- if result is None or result == 0:
65
- return None
66
- return result.decode()
35
+ class CStringHelper:
36
+ @classmethod
37
+ def from_param(cls, value):
38
+ if value is None:
39
+ return None
40
+ elif isinstance(value, (bytes | ctypes.Array)):
41
+ return value
42
+ else:
43
+ e = value.encode()
44
+ return e
45
+
46
+ @staticmethod
47
+ def toStr(result, func, arguments):
48
+ """
49
+ Transform a foreign char* type to str.
50
+
51
+ ctypes functions have an attribute called errcheck that can not
52
+ only be used for error checking but also to alter the result. If
53
+ errcheck is defined, the value returned from that function is what
54
+ is returned from the foreign function call. In this case, C returns
55
+ strings in the form of zero-terminated char* strings. To use these
56
+ as python strings (str) they must be decoded.
57
+ """
58
+ if result is None or result == 0:
59
+ return None
60
+ return result.decode()
67
61
 
68
62
 
69
63
  REGISTERED_TYPES = {}
@@ -78,7 +72,7 @@ def _registerType(
78
72
  errcheck=None,
79
73
  ):
80
74
  if type_name in REGISTERED_TYPES:
81
- raise PrototypeError("Type: '%s' already registered!" % type_name)
75
+ raise PrototypeError(f"Type: '{type_name}' already registered!")
82
76
 
83
77
  REGISTERED_TYPES[type_name] = TypeDefinition(
84
78
  type_class_or_function, is_return_type, storage_type, errcheck
@@ -100,16 +94,14 @@ _registerType("bool*", ctypes.POINTER(ctypes.c_bool))
100
94
  _registerType("long", ctypes.c_long)
101
95
  _registerType("long*", ctypes.POINTER(ctypes.c_long))
102
96
  _registerType("char", ctypes.c_char)
103
- if six.PY2:
104
- _registerType("char*", ctypes.c_char_p)
105
- _registerType("char**", ctypes.POINTER(ctypes.c_char_p))
106
- if six.PY3:
107
- _registerType(
108
- "char*",
109
- CStringHelper,
110
- storage_type=ctypes.c_char_p,
111
- errcheck=CStringHelper.toStr,
112
- )
97
+
98
+
99
+ _registerType(
100
+ "char*",
101
+ CStringHelper,
102
+ storage_type=ctypes.c_char_p,
103
+ errcheck=CStringHelper.toStr,
104
+ )
113
105
  _registerType("float", ctypes.c_float)
114
106
  _registerType("float*", ctypes.POINTER(ctypes.c_float))
115
107
  _registerType("double", ctypes.c_double)
@@ -127,11 +119,11 @@ class PrototypeError(Exception):
127
119
  pass
128
120
 
129
121
 
130
- class Prototype(object):
122
+ class Prototype:
131
123
  pattern = re.compile(PROTOTYPE_PATTERN)
132
124
 
133
125
  def __init__(self, lib, prototype, bind=False, allow_attribute_error=False):
134
- super(Prototype, self).__init__()
126
+ super().__init__()
135
127
  self._lib = lib
136
128
  self._prototype = prototype
137
129
  self._bind = bind
@@ -151,7 +143,7 @@ class Prototype(object):
151
143
  type_definition.storage_type,
152
144
  type_definition.errcheck,
153
145
  )
154
- raise ValueError("Unknown type: %s" % type_name)
146
+ raise ValueError(f"Unknown type: {type_name}")
155
147
 
156
148
  def shouldBeBound(self):
157
149
  return self._bind
@@ -159,7 +151,7 @@ class Prototype(object):
159
151
  def resolve(self):
160
152
  match = re.match(Prototype.pattern, self._prototype)
161
153
  if not match:
162
- raise PrototypeError("Illegal prototype definition: %s\n" % self._prototype)
154
+ raise PrototypeError(f"Illegal prototype definition: {self._prototype}\n")
163
155
  else:
164
156
  restype = match.groupdict()["return"]
165
157
  function_name = match.groupdict()["function"]
@@ -168,29 +160,26 @@ class Prototype(object):
168
160
 
169
161
  try:
170
162
  func = getattr(self._lib, function_name)
171
- except AttributeError:
163
+ except AttributeError as err:
172
164
  if self._allow_attribute_error:
173
165
  return
174
166
  raise PrototypeError(
175
- "Can not find function: %s in library: %s"
176
- % (function_name, self._lib)
177
- )
167
+ f"Can not find function: {function_name} in library: {self._lib}"
168
+ ) from err
178
169
 
179
170
  if (
180
171
  not restype in REGISTERED_TYPES
181
172
  or not REGISTERED_TYPES[restype].is_return_type
182
173
  ):
183
174
  sys.stderr.write(
184
- "The type used as return type: %s is not registered as a return type.\n"
185
- % restype
175
+ f"The type used as return type: {restype} is not registered as a return type.\n"
186
176
  )
187
177
 
188
178
  return_type, storage_type, errcheck = self._parseType(restype)
189
179
 
190
180
  if inspect.isclass(return_type):
191
181
  sys.stderr.write(
192
- " Correct type may be: %s_ref or %s_obj.\n"
193
- % (restype, restype)
182
+ f" Correct type may be: {restype}_ref or {restype}_obj.\n"
194
183
  )
195
184
 
196
185
  return None
@@ -227,7 +216,7 @@ class Prototype(object):
227
216
  if self._func is None:
228
217
  if self._allow_attribute_error:
229
218
  raise NotImplementedError(
230
- "Function:%s has not been properly resolved" % self.__name__
219
+ f"Function:{self.__name__} has not been properly resolved"
231
220
  )
232
221
  else:
233
222
  raise PrototypeError("Prototype has not been properly resolved")
@@ -249,15 +238,8 @@ class Prototype(object):
249
238
  tokens = re.split("[ :]", errMsg)
250
239
  argidx = int(tokens[1]) - 1 # it starts from 1
251
240
  raise TypeError(
252
- (
253
- "Argument {argidx}: cannot create a {argtype} from the given "
254
- "value {actval} ({acttype})"
255
- ).format(
256
- argtype=self._func.argtypes[argidx],
257
- argidx=argidx,
258
- actval=repr(args[argidx]),
259
- acttype=type(args[argidx]),
260
- )
241
+ f"Argument {argidx}: cannot create a {self._func.argtypes[argidx]} from the given "
242
+ f"value {repr(args[argidx])} ({type(args[argidx])})"
261
243
  ) from err
262
244
 
263
245
  def __get__(self, instance, owner):
@@ -265,10 +247,7 @@ class Prototype(object):
265
247
  self.resolve()
266
248
  self._resolved = True
267
249
  if self.shouldBeBound():
268
- if six.PY2:
269
- return MethodType(self, instance, owner)
270
- if six.PY3:
271
- return MethodType(self, instance)
250
+ return MethodType(self, instance)
272
251
  else:
273
252
  return self
274
253
 
@@ -277,7 +256,7 @@ class Prototype(object):
277
256
  if self.shouldBeBound():
278
257
  bound = ", bind=True"
279
258
 
280
- return 'Prototype("%s"%s)' % (self._prototype, bound)
259
+ return f'Prototype("{self._prototype}"{bound})'
281
260
 
282
261
  @classmethod
283
262
  def registerType(
cwrap/version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.6.6'
16
- __version_tuple__ = version_tuple = (1, 6, 6)
15
+ __version__ = version = '1.6.9'
16
+ __version_tuple__ = version_tuple = (1, 6, 9)
@@ -1,12 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: cwrap
3
- Version: 1.6.6
3
+ Version: 1.6.9
4
4
  Summary: cwrap - ctypes blanket
5
- Home-page: https://github.com/Statoil/cwrap
6
- Author: Statoil ASA
7
- Author-email: fg_gpl@statoil.com
5
+ Author-email: Equinor ASA <fg_sib-scout@equinor.com>
8
6
  License: GPL-3.0
9
- Platform: any
7
+ Project-URL: Repository, https://github.com/equinor/cwrap
8
+ Platform: all
10
9
  Classifier: Development Status :: 5 - Production/Stable
11
10
  Classifier: Environment :: Other Environment
12
11
  Classifier: Intended Audience :: Developers
@@ -14,24 +13,33 @@ Classifier: Intended Audience :: Science/Research
14
13
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
15
14
  Classifier: Natural Language :: English
16
15
  Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3.8
18
- Classifier: Programming Language :: Python :: 3.9
19
16
  Classifier: Programming Language :: Python :: 3.10
20
17
  Classifier: Programming Language :: Python :: 3.11
21
18
  Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
22
20
  Classifier: Topic :: Software Development :: Libraries
23
21
  Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: six
26
25
 
26
+ # cwrap
27
27
 
28
- =======
29
- cwrap
30
- =======
28
+ cwrap is a Python wrapper around C code, building upon ctypes.
31
29
 
32
- Introduction
33
- ------------
30
+ # Examples
34
31
 
35
- Cwrap is a meta library using ctypes to quickly load and call C functions from
36
- Python. It's primarily desgined to be practicaul and useful for the ecl
37
- library https://github.com/statoil/libecl, but isn't tied to it.
32
+ See `examples/`
33
+
34
+ # Installing
35
+ ```
36
+ pip install cwrap
37
+ ```
38
+
39
+ # Running tests
40
+ Clone this repo and cd into it, then:
41
+
42
+ ```
43
+ pip install -r requirements.txt
44
+ python -m pytest -sv tests
45
+ ```
@@ -0,0 +1,14 @@
1
+ cwrap/__init__.py,sha256=jaZFUAG-rgT5RBJURcR_PCzGFmudtoAMaITTho0QIoY,1935
2
+ cwrap/basecclass.py,sha256=MtJQddSMegJ3TJ13rZM40_WV6DBnIVtdeIilbk7yLuI,4804
3
+ cwrap/basecenum.py,sha256=63af5ZpjcxoGdczot6vbF7Uyu3sma1jg8yXXD43h8qU,5121
4
+ cwrap/basecvalue.py,sha256=Idg2EnyVuRD6Eh8xjcXVuiGsqpjakKnq8hSwjczrAA8,2102
5
+ cwrap/cfile.py,sha256=vkVpZZ_BsM6etqnLja7XNbBR9bBSGxTYR7VhhC1qCJs,3233
6
+ cwrap/clib.py,sha256=E94IqKHOoGozwbrPFe38XCretUzPr5MEdTK0tg5_VKI,3591
7
+ cwrap/metacwrap.py,sha256=hZkY1piH7R8dahydIxIHd8RQjkKm9gqHGtUKsQhqpaE,2017
8
+ cwrap/prototype.py,sha256=GvoBt5i8gPT55Ovo5EHcWL_Z49trItSpIGVlXGMIUmM,9229
9
+ cwrap/version.py,sha256=H4tpGbuK5q1tqtuUh1Nr2Buwsz8VycRrcpqeBxyquBg,411
10
+ cwrap-1.6.9.dist-info/LICENSE,sha256=KdZLnTl6Qk0PT7wUW8ugRdviqwxU5wjE26sku5sicOU,674
11
+ cwrap-1.6.9.dist-info/METADATA,sha256=FlPng_1FsJoQ0pfazQw5z9p2P_JOG4sFMYdfUNnfbGI,1229
12
+ cwrap-1.6.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
13
+ cwrap-1.6.9.dist-info/top_level.txt,sha256=CUjoCmJmjoO-LFc7eRvSm7AHuFbYgwHhkQ6Al-x6sTk,6
14
+ cwrap-1.6.9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,14 +0,0 @@
1
- cwrap/__init__.py,sha256=u26LODQXzzMi3d43B6gHd0vX2FM44J-ooNnVp2nfKV0,1875
2
- cwrap/basecclass.py,sha256=HgrEyQIfa5tcrOROv-4_wQfYuESJebO1HsrgIw1zL2g,5020
3
- cwrap/basecenum.py,sha256=roAqm0v0AiVf-uDzFambT_D3YGVlQxVSweNdkJH7SFM,5319
4
- cwrap/basecvalue.py,sha256=gEcwMHdZ7q7zn7Ou1ZG-OfLSUlIZf2X1xRVUmseo88o,2091
5
- cwrap/cfile.py,sha256=1qdryUEMPbZbWccYyFSd_gT4EMk6CrlAvi2MEqmv-mY,5948
6
- cwrap/clib.py,sha256=pAOc6-uEVQxzWcx2hry35WecxTi4gmv92sQcGVghiLo,3756
7
- cwrap/metacwrap.py,sha256=He9HtExc78S9uz08u_za_N1e8DBHcyf_JT3-R3LzSNs,1931
8
- cwrap/prototype.py,sha256=op5zQGV8rA4qodajxGN-UTfuyx6XDPjypiZAB4C1YEo,10013
9
- cwrap/version.py,sha256=Nz1l8vGPOAOAlxWDepNu28nfH9fOKk0GnGSnVyZJsFE,411
10
- cwrap-1.6.6.dist-info/LICENSE,sha256=KdZLnTl6Qk0PT7wUW8ugRdviqwxU5wjE26sku5sicOU,674
11
- cwrap-1.6.6.dist-info/METADATA,sha256=bZSHL23VCIRAqONcQoeR-slRe6o-f4Fyn3ctqZTON7c,1222
12
- cwrap-1.6.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
13
- cwrap-1.6.6.dist-info/top_level.txt,sha256=CUjoCmJmjoO-LFc7eRvSm7AHuFbYgwHhkQ6Al-x6sTk,6
14
- cwrap-1.6.6.dist-info/RECORD,,
File without changes