How to get a GObject.Callback from PyGObject? - python

I'm trying to add callback functions to a Gtk.Builder using Gtk.Builder.add_callback_symbol. I tried to pass a python function to it, but that does not work. Documentation says I need to pass a GObject.Callback instead, so I tried to cast one by calling GObject.Callback(myfunc) but got a NotImplementedError. The C-Documentation on GCallback says I need to use something called G_CALLBACK to typecast. But there does not seem to be any reference to this in PyGObject and I'm lost at that point.
I would like to say beforehand, that I know callback can be also added by using 'Gtk.Builder.connect_signals', but that's not the question here.

The GObject.Callback function is just there for documentation purposes atm. You can just pass a function matching the signature of the callback type, in this case a function which doesn't take any arguments and has no return value.

Related

Custom 'self' expression for functions

First of all, I'm super new to stackoverflow and don't really know a lot about how to ask questions and all, so please excuse any major mistakes I made.
Anyways, I'm currently trying to create a way for functions to reference themselves. For that I have created a wrapper which looks like this:
def custom_self(func):
def wrapped(*args, **kwargs):
return func(func, *args, **kwargs)
return wrapped
Pretty standard stuff, honestly. I can now use this wrapper as a decorator on any new function which is supposed to reference itself. However, I'm using Visual Studio Code as editor and whenever I hover over my new function it shows something like this:
Screenshot (Sorry, apparently I'm not allowed to add pictures yet)
Now, as you can see, the code lens shows all parameters the function requires. However this includes the parameter 'own' which is supposed to be a reference to the function itself. Therefore it isn't a parameter, that you can actually pass to the function, similar to how class methods work. My question now is: How can I make it so that the code lens only shows the parameters 'arg_1' and 'arg_2'?
(This is what is displayed. As you can see the editor thinks I pass the parameter 'own' when actually I'm passing the parameter 'arg_1'. The code works just as I want it to but the displaying kinda fails.)
I already tried using 'typing.overload' as a decorator like so:
#typing.overload
def new_func(arg_1, arg_2): ...
#custom_self
def new_func(own, arg_1, arg_2):
own.arg_1 = arg_1
own.arg_2 = arg_2
...
This works and the code lens now only shows 'arg_1' and 'arg_2' as parameters, but let's just be honest, this is not a very pretty solution, because it means I have to create a dummy for every self-referencing function and I also have to declare every function twice, which makes it less 'pythonic', I guess.
I have also tried to decorate the 'custom_self' function, but this also didn't get me the desired result.
Again, the code works just fine, this is just a display error. But it's a rather annoying one at that.
The lens indicates own, arg_1, arg_2 because that is the actual signature of the function prior to decoration.
And I guess VS Code will not execute the decorator code symbolically to determine that the actual signature will be only arg_1, arg_2 because own willl be dynamically provided.
You are asking too much at once.
Without specifying the final signature for each function (which is not what you want), apart from an extension to the IDE (which would be overkill) I can't see how to achieve that.

how to reference previous arguments of a function call in later arguments?

This is in micropython
I'm creating an API to control some hardware. The API will be implemented in C with an interface in micropython.
One example of my API is:
device.set(curr_chan.BipolarRange, curr_chan.BipolarRange.state.ON)
I'd like to be able to achieve the same functionality but shorten the second path by somehow implicitly referencing the first argument:
device.set(curr_chan.BipolarRange, <first arg?>.state.ON)
Is there anyway to do this?
The only way to do something like this now would be
device.set(curr_chan.BipolarRange.state.ON)
and then put an upward pointing C-pointer on both the ON C-object and state C-object so that I know which entry in curr_chan is being referenced.
The micropython runtime - and I assume CPython one - doesn't keep the entire object "tree" available to the developer in memory.
You could have special values for the second (state) argument which tell the function implementation to derive the state from the first argument. You could also introduce a completely separate function which has this behavior.
Or you could have a helper function which determines the state and passes it down to the set function, something like this:
device.set(*state_ON(curr_chan.BipolarRange))
Here, state_ON would return a tuple (curr_chan.BipolarRange, curr_chan.BipolarRange.state.ON).
In any case, there is no direct support for what you are trying to do in Python itself.
Pass the name of the attribute you want as the second argument. Call getattr (or PObject_GetAttr repeatedly to get each element of the .-separated string:
device.set(curr_chan.BipolarRange, 'state.ON')

Python Method Signature for Different Runtime Execution Data

Could someone tell me whether this idea is feasible in Python?
I want to have a method and the datatype of the signature is not fixed.
For example:
Foo(data1, data2) <-- Method Definition in Code
Foo(2,3) <---- Example of what would be executed in runtime
Foo(s,t) <---- Example of what would be executed in runtime
I know the code could work if i change the Foo(s,t) to Foo("s","t"). But I am trying to make the code smarter to recognize the command without the "" ...
singledispatch might be an answer, which transforms a function into a generic function, which can have different behaviors depending upon the type of its first argument.
You could see a concrete example in the above link. And you should do some special things if you want to do generic dispatch on more than one arguments.

How to SkippCall while Hooking in Deviare?

Does anyone how to SkipCall() in Deviare (Python)?
They say something like:
HRESULT SkipCall ()
Skip calling the original function.
When I try to do this, it doesn't work. It goes in a loop at the same call. I guess that I should also do some stuff on registers (like to restore EBP). But the thing is that NktCallInfo.Register set doesn't work in Python. I try something like:
NktHookCallInfo.Register(ESP, EBP)
But it doesn't work. Help please ?
I recently see this question. Expect not to be late. (I'm a Deviare developer)
When you call SkipCall, you must setup a return value and, optionally the Win32 lasterror using the provided 'INktHookCallInfo' methods. If the function being hooked is in the database, it will remove the parameters from stack depending on the calling convention.
If you are hooking an arbitrary address without assigning a function, you must do the unwind manually by setting the ESP/RSP registers as appropiate.

Functions with dependencies passed as parameters

I'm working on a project where I'm batch generating XML files which can import to the IDE of an industrial touchscreen.
Each XML file represents a screen, and most screens require the same functions and the process for dealing with them is the same, with the exception of the fact that each screen type has a unique configuration function.
I'm using a ScreenType class to hold attributes specific to a screen type, so I decided to write a unique configuration for each type, and pass it as a parameter to the __init__() of this class. This way, when I pass around my ScreenType as it is needed, it's configuration function will stay bundled and can be used whenever needed.
But I'm not sure what will happen if my configuration function itself has a dependency. For example:
def configure_inputdiag(a, b, c):
numerical_formatting = get_numerics(a)
# ...
return configured_object
Then, when it comes time to create an instance of a ScreenType
myscreentype = ScreenType(foo, man, shoe, configure_inputdiag)
get_numerics is a module scoped function, but myscreentype could (and does) get passed within other modules.
Does this create a problem with dependencies? I'd try to test it myself, but it seems like I don't have a fundamental understanding behind what's going on when I pass a function as a parameter. I don't want to draw incorrect conclusions about what's happening.
What I've tried: Googling, Search SO, and I didn't find anything specifically for Python.
Thanks in advance.
There's no problem.
The function configure_inputdiag will always refer to get_numerics in the context where it was defined. So, even if you call configure_inputdiag from some other module which knows nothing about get_numerics, it will work fine.
Passing a function as a parameter produces a reference to that function. Through that reference, you can call the function as if you had called it by name, without actually knowing the name (or the module from which it came). The reference is valid for the lifetime of the program, and will always refer to the same function. If you store the function reference, it basically becomes a different name for the same function.
What you are trying to do works in a very natural form in Python -
In the exampe above, you don't need to have the "get_numerics" function imported in the namespace (module) where the "configure_inputdiag" is - you just pass it as a normal parameter (say, call it "function") and you are going like in this example:
Module A:
def get_numerics(parm):
...
input diag = module_B.configure_inputdiag(get_numerics, a)
Module B:
def configure_inputdiag(function, parm):
result = function(parm)
Oh - I saw your doubt iwas the other waya round - anyway, there is no problem - in Python, functions are first class objects- jsut like ints and strings, and they can be passed around as parametrs to other functions in other modules as you wish. I think the example above clarifies that.
get_numerics is resolved in the scope of the function body, so it does not also need to be in the scope of the caller.

Categories

Resources