On 21 May 2025 11:20:55 GMT, Stefan Ram wrote:
... I have this setup where I lay out a table to map out my markup
language [1] and then use some dynamic code to spin up the classes
based on that table [0] ...
The main way I like to do it is start with a basic class object,
assign some basic attributes like __name__ and __doc__, and
dynamically attach additional members to it with setattr.
Here’s a partial example, taken from <
https://gitlab.com/ldo/dbussy>.
Note the heavy use of lexical binding:
class proxy(BusPeer.Object.ProxyInterface) :
# class that will be constructed, to be instantiated for a given connection,
# destination and path.
# class field _iface_name contains interface name.
__slots__ = ("_parent", "_conn", "_dest", "_path", "_timeout")
def __init__(self, *, parent, connection, dest, path, timeout = DBUS.TIMEOUT_USE_DEFAULT) :
if is_async :
assert connection.loop != None, "no event loop to attach coroutines to"
#end if
self._parent = parent
self._conn = connection
self._dest = dest
self._path = path
self._timeout = timeout
#end __init__
# rest filled in dynamically below.
#end proxy
def def_method(intr_method) :
# constructs a method-call method.
if is_async :
async def call_method(self, *args, **kwargs) :
message = dbus.Message.new_method_call \
(
destination = self._dest,
path = dbus.unsplit_path(self._path),
iface = self._iface_name,
method = intr_method.name
)
_append_args(message, intr_method, args, kwargs)
if intr_method.expect_reply :
reply = await self._conn.send_await_reply(message, self._timeout)
result = reply.expect_return_objects(intr_method.out_signature)
else :
message.no_reply = True
self._conn.send(message)
result = None
#end if
return \
result
#end call_method
else :
def call_method(self, *args, **kwargs) :
message = dbus.Message.new_method_call \
(
destination = self._dest,
path = dbus.unsplit_path(self._path),
iface = self._iface_name,
method = intr_method.name
)
_append_args(message, intr_method, args, kwargs)
if intr_method.expect_reply :
reply = self._conn.send_with_reply_and_block(message, self._timeout)
result = reply.expect_return_objects(intr_method.out_signature)
else :
message.no_reply = True
self._conn.send(message)
result = None
#end if
return \
result
#end call_method
#end if
#begin def_method
call_method.__name__ = intr_method.name
call_method.__doc__ = \
(
"method, %(args)s, %(result)s"
%
{
"args" :
(
lambda : "no args",
lambda : "args %s" % dbus.unparse_signature(intr_method.in_signature),
)[len(intr_method.in_signature) != 0](),
"result" :
(
lambda : "no result",
lambda : "result %s" % dbus.unparse_signature(intr_method.out_signature),
)[len(intr_method.out_signature) != 0](),
}
)
setattr(proxy, intr_method.name, call_method)
#end def_method