You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently working on this but it is in no shape for a PR yet.
The idea is that BridgedCallables should behave as close as possible to actual local Callables to allow the inspect features and IPython features building on top of that to work as good as possible.
The concrete goal is the following:
Assume a function like:
defadd(x: int, y:int ) ->int:
returnx+y
IPython help returns the following.
In [34]: add?
Signature: add(x: int, y: int) -> int
Docstring: <no docstring>
File: ~/Projects/ghidra_bridge/dev.py
Type: function
This behavior should be replicated with BrigdedCallables. What is needed for this is that is after several layers of IPython code the inspect module can generate a valid signature for it by using Signature.from_callable. This currently fails with the following:
ValueError Traceback (most recent call last)
<ipython-input-36-6e450cf1e523> in <module>
----> 1 Signature.from_callable(f)
/usr/lib64/python3.7/inspect.py in from_callable(cls, obj, follow_wrapped)
2831 """Constructs Signature for the given callable object."""
2832 return _signature_from_callable(obj, sigcls=cls,
-> 2833 follow_wrapper_chains=follow_wrapped)
2834
2835 @property
/usr/lib64/python3.7/inspect.py in _signature_from_callable(obj, follow_wrapper_chains, skip_bound_arg, sigcls)
2286 if _signature_is_builtin(obj):
2287 return _signature_from_builtin(sigcls, obj,
-> 2288 skip_bound_arg=skip_bound_arg)
2289
2290 if isinstance(obj, functools.partial):
/usr/lib64/python3.7/inspect.py in _signature_from_builtin(cls, func, skip_bound_arg)
2110 s = getattr(func, "__text_signature__", None)
2111 if not s:
-> 2112 raise ValueError("no signature found for builtin {!r}".format(func))
2113
2114 return _signature_fromstr(cls, func, s, skip_bound_arg)
ValueError: no signature found for builtin <BridgedCallable('<bound method ghidra.program.database.function.FunctionManagerDB.getFunctionAt of ghidra.program.database.function.FunctionManagerDB@5f0ef8c4>', type=instancemethod, handle=99f4707d-9f4a-4205-b820-7dac1b5a811b)>
The first hint is that no signature found for builtin is weird because a BridgedCallable is in no way a builtin so something is going quite wrong.
The first divergence from the Jython shell is that in the Jython shell isinstance(f, types.MethodType) is True while in the bridge client it is false. I am unsure how to fix this exactly as isinstance is a builtin that might be hard to trick.
An alternative to bypass this all is to fake __signature__ directly and just build one ourselves. Slightly annoying and ignores the potential actual problem.
It gets recognized as a builtin because ismethoddescriptor returns True, which in happens because ismethod returns False for currentProgram.functionManager.getFunctionAt
One core issue is: Is there some way to make isinstance(obj, type) go over to the bridge and is that even the correct way to do it?
I will look into how other environments like rpyc and Jython handle this and might have more concrete ideas then.
The text was updated successfully, but these errors were encountered:
Turns out building our own Signature is fairly easy, so I don't quite care about isinstance working for all those types. I'll leave this issue open in case someone else runs into this, but won't work on it.
More or less accidentally gathered results: If hacking e.g. inspect.isclass to recognize BridgedObjects of Java Classes things break in IPython anyway.
One possible solution to fix isinstance in general though might be overriding the builtin (which I think works and should get picked up by the inspect module). Currently the builtin is used in https://github.com/justfoxing/ghidra_bridge/blob/master/ghidra_bridge/bridge.py#L985-L997 so that code would need to be changed to save the original version once and then change it.
fmagin
changed the title
Make inspection of BridgedCallables as transparent as possible
Get isinstance to return reasonable results for BridgedObjects for type, callable, etc
Nov 22, 2019
I am currently working on this but it is in no shape for a PR yet.
The idea is that BridgedCallables should behave as close as possible to actual local Callables to allow the inspect features and IPython features building on top of that to work as good as possible.
The concrete goal is the following:
Assume a function like:
IPython help returns the following.
This behavior should be replicated with BrigdedCallables. What is needed for this is that is after several layers of IPython code the
inspect
module can generate a valid signature for it by usingSignature.from_callable
. This currently fails with the following:The first hint is that
no signature found for builtin
is weird because aBridgedCallable
is in no way a builtin so something is going quite wrong.The first divergence from the Jython shell is that in the Jython shell
isinstance(f, types.MethodType)
isTrue
while in the bridge client it is false. I am unsure how to fix this exactly as isinstance is a builtin that might be hard to trick.An alternative to bypass this all is to fake
__signature__
directly and just build one ourselves. Slightly annoying and ignores the potential actual problem.It gets recognized as a builtin because
ismethoddescriptor
returnsTrue
, which in happens becauseismethod
returnsFalse
forcurrentProgram.functionManager.getFunctionAt
One core issue is: Is there some way to make
isinstance(obj, type)
go over to the bridge and is that even the correct way to do it?I will look into how other environments like rpyc and Jython handle this and might have more concrete ideas then.
The text was updated successfully, but these errors were encountered: