lawrence_danna added inline comments.

================
Comment at: lldb/include/lldb/Interpreter/ScriptInterpreter.h:469
+  
+  virtual int GetNumArgumentsForCallable(const char *callable_name) { 
+    return -1;
----------------
jingham wrote:
> lawrence_danna wrote:
> > labath wrote:
> > > jingham wrote:
> > > > lawrence_danna wrote:
> > > > > labath wrote:
> > > > > > In light of varargs functions (`*args, **kwargs`), which are fairly 
> > > > > > popular in python, the concept of "number of arguments of a 
> > > > > > callable" does not seem that well defined. The current 
> > > > > > implementation seems to return the number of fixed arguments, which 
> > > > > > might be fine, but I think this behavior should be documented. 
> > > > > > Also, it would be good to modernize this function signature -- have 
> > > > > > it take a StringRef, and return a `Expected<unsigned (?)>` -- 
> > > > > > ongoing work by @lawrence_danna will make it possible to return 
> > > > > > errors from the python interpreter, and this will make it possible 
> > > > > > to display those, instead of just guessing that this is because the 
> > > > > > callable was not found (it could in fact be because the named thing 
> > > > > > is not a callable, of because resolving the name produced an 
> > > > > > exception, ...).
> > > > > I just took a look at PythonCallable::GetNumArguments() and it's 
> > > > > horribly broken.  
> > > > > 
> > > > > It doesn't even work for the simplest test case I could think of.
> > > > > 
> > > > > ```  
> > > > > auto builtins = PythonModule::Import("builtins");
> > > > > ASSERT_THAT_EXPECTED(builtins, llvm::Succeeded());
> > > > > auto hex = As<PythonCallable>(builtins.get().GetAttribute("hex"));
> > > > > ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());  
> > > > > EXPECT_EQ(hex.get().GetNumArguments().count, 1u);
> > > > > ```
> > > > > 
> > > > > we should really re-write it to use inspect.signature.
> > > > Interesting.  We use it for free functions (what you pass to the -F 
> > > > option of `breakpoint command add`) and for the __init__ and __call__ 
> > > > method in the little classes you can make up for scripted thread plans 
> > > > and for the class version of Python implemented command-line commands.  
> > > > We have tests for telling 3 vrs. 4 vrs. not enough or too many, and 
> > > > they all pass.  So it seems to work in the cases we currently need it 
> > > > to work for...
> > > > 
> > > > "inspect.signature" is python 3 only, and the python 2 equivalent is 
> > > > deprecated.  So it will take a little fancy footwork to use it in the 
> > > > transition period.
> > > lol :)
> > > 
> > > I would actually say that we should try not to use this function(ality) 
> > > wherever possible. Making decisions based on the number of arguments the 
> > > thing you're about to call takes sounds weird. I don't want to get too 
> > > involved in this, but I was designing this, I'd just say that if one 
> > > tries to pass arguments to the callback then the callback MUST take three 
> > > arguments (or we'll abort processing the breakpoint command). If he wants 
> > > his function to be called both with arguments and without, he can just 
> > > add a default value to the third argument. (And if his function takes two 
> > > arguments, but he still tries to pass something... well, it's his own 
> > > fault).
> > > 
> > > Anyway, feel free to ignore this comment, but I felt like I had to say 
> > > something. :)
> > I completely agree with Pavel.    Inspecting a function signature before 
> > calling it is a big code smell in python.    If there's a way to avoid 
> > doing that introspection, that would be better.
> Unfortunately, we originally designed this interface to take three arguments, 
> the frame pointer, the breakpoint location and the Python session dict.  Then 
> it became clear that it would be better to add this extra args argument (and 
> in the case of Python based commands the ExecutionContext pointer).  At that 
> point we had three choices, abandon the improvement; switch to 
> unconditionally passing the extra arguments, and break everybody's extant 
> uses; or switch off of the number of arguments to decide whether the user had 
> provided the old or new forms.
> 
> My feeling about lldb Python scripts/commands etc. that people use in the 
> debugger is that a lot of users don't know how they work at all, they just 
> got them from somebody else; and many more figured out how to write them for 
> some specific purpose, and then pretty much forgot how they worked.  So 
> suddenly breaking all these bits of functionality will result in folks just 
> deciding that this affordance is not reliable and not worth their time, which 
> would be a shame.
> 
> So instead we accommodate both forms, which requires that we know which one 
> the user provided.  If you see a better way to do this, (and are willing to 
> implement it because so far as I can see this method is going to work just 
> fine) dig in, I'm not wedded to the particular approach.  But I am not 
> excited about penalizing our users because we didn't get the API design right 
> the first time through.
makes sense.   

The only other way I can think of to solve it would be to have some indication 
in the `break com add` command of what signature it expects from the function.  
 But that's really ugly too because now you're asking users to understand yet 
another option.

I put up https://reviews.llvm.org/D68995 this morning which adds 
`inspect.signature` support for pythons that have it.

Currently we have really gnarly ArgInfo tests like this:
```
    if (argc.count == 5 || argc.is_bound_method || argc.has_varargs)
        pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, 
dict);
    else
        pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
```

😖

I think if we replace `count`  with `max_positional_args` we should be able to 
replace that kindof test with just 
```
if (argc.max_positional_args < 5)
   old_version
else
   new_version
```




Repository:
  rLLDB LLDB

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68671/new/

https://reviews.llvm.org/D68671



_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to