Skip to content

Instantly share code, notes, and snippets.

@ynkdir
Created January 27, 2024 09:50
Show Gist options
  • Save ynkdir/3af18fbbf7f61a97c2cc9da0e28ef0df to your computer and use it in GitHub Desktop.
Save ynkdir/3af18fbbf7f61a97c2cc9da0e28ef0df to your computer and use it in GitHub Desktop.
Meta class for ctypes definition
import ctypes
import inspect
class GlobalFirstAndNoClassPrivateNamespace:
def __init__(self, name, globals_):
self._class_scope = f"_{name}"
self._globals = globals_
self._dict = {}
def __getitem__(self, key):
if key.startswith(self._class_scope):
key = key[len(self._class_scope):]
if key in self._globals:
return self._globals[key]
return self._dict[key]
def __setitem__(self, key, value):
self._dict[key] = value
class Define(type):
@classmethod
def __prepare__(metacls, name, bases):
return GlobalFirstAndNoClassPrivateNamespace(name, inspect.stack()[1][0].f_globals)
def __new__(metacls, name, bases, classdict):
if name in classdict._globals:
cls = classdict._globals[name]
for key, value in classdict._dict.items():
setattr(cls, key, value)
return cls
elif not bases:
return super().__new__(metacls, name, bases, classdict._dict)
elif bases[0] is ComPtr:
return type(ctypes.c_void_p)(name, (ctypes.c_void_p,), classdict._dict)
elif bases[0] is Structure:
return type(ctypes.Structure)(name, (ctypes.Structure,), classdict._dict)
elif bases[0] is Union:
return type(ctypes.Union)(name, (ctypes.Union,), classdict._dict)
class ComPtr(metaclass=Define):
pass
class Structure(metaclass=Define):
pass
class Union(metaclass=Define):
pass
# test
class A(Structure):
a = 99
__x = str
class A(Structure):
class B(Structure):
_fields_ = [("b", ctypes.c_int)]
b = B
x = __x
y = int
print(type(A))
print(A.a)
print(A.x)
print(A.y)
print(type(A.b))
print(A.b)
print(A.b.b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment