[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-19 Thread Lawrence D'Anna via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2386537c2469: [LLDB] bugfix: command script add -f 
doesnt work for some callables (authored by lawrence_danna).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,6 +667,7 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
   }
 
@@ -678,8 +679,9 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -690,6 +692,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
   }
 
@@ -698,7 +702,18 @@
 class Foo:
   def bar(self, x):
  return x
+  @classmethod
+  def classbar(cls, x):
+ return x
+  @staticmethod
+  def staticbar(x):
+ return x
+  def __call__(self, x):
+ return x
+obj = Foo()
 bar_bound   = Foo().bar
+bar_class   = Foo().classbar
+bar_static  = Foo().staticbar
 bar_unbound = Foo.bar
 )";
 PyObject *o =
@@ -711,16 +726,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -734,9 +770,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-19 Thread Pavel Labath via Phabricator via lldb-commits
labath accepted this revision.
labath added a comment.
This revision is now accepted and ready to land.

I am happy with that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-18 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna added a comment.

@jingham , @labathwhat do you think?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-17 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna updated this revision to Diff 225373.
lawrence_danna added a comment.

rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,6 +667,7 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
   }
 
@@ -678,8 +679,9 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -690,6 +692,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
   }
 
@@ -698,7 +702,18 @@
 class Foo:
   def bar(self, x):
  return x
+  @classmethod
+  def classbar(cls, x):
+ return x
+  @staticmethod
+  def staticbar(x):
+ return x
+  def __call__(self, x):
+ return x
+obj = Foo()
 bar_bound   = Foo().bar
+bar_class   = Foo().classbar
+bar_static  = Foo().staticbar
 bar_unbound = Foo.bar
 )";
 PyObject *o =
@@ -711,16 +726,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -734,9 +770,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-17 Thread Pavel Labath via Phabricator via lldb-commits
labath added a comment.

I also think we shouldn't go out of our way (and I consider any kind of 
introspection as "going out of our way") to forbid calling with a "deprecated" 
signature for some callables even though there's technically no backward 
compatibility to worry about (because it was not possible to call those 
callables in the past). For "gentle discouragement" I'd rather just print a 
warning whenever we call any callable with a deprecated signature. That warning 
can explain the problem and how to fix it (and it's strength can be ramped up 
over time if we want to eventually remove these).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna added a comment.

Also,  @jingham, only the `#if` branch for python2 has easy access to the 
`__call__` attribute.   We could test for it in python3 but it wouldn't do what 
you're thinking it would:

  In [1]: def f(): 
 ...: return 1 
 ...:   

   
  
  In [2]: f.__call__

   
  Out[2]: 
  
  In [3]: type(f).__call__  

   
  Out[3]: 




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna updated this revision to Diff 225303.
lawrence_danna added a comment.

rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,15 +667,27 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
 const char *script = "class Foo: \n"
  "  def bar(self, x):\n"
  " return x \n"
+ "  @classmethod \n"
+ "  def classbar(cls, x):\n"
+ " return x \n"
+ "  @staticmethod \n"
+ "  def staticbar(x):\n"
+ " return x \n"
+ "  def __call__(self, x): \n"
+ " return x \n"
+ "obj = Foo() \n"
  "bar_bound   = Foo().bar \n"
+ "bar_class   = Foo().classbar \n"
+ "bar_static  = Foo().staticbar \n"
  "bar_unbound = Foo.bar \n";
 PyObject *o =
 PyRun_String(script, Py_file_input, globals.get(), globals.get());
@@ -687,16 +699,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -710,9 +743,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna updated this revision to Diff 225296.
lawrence_danna marked 3 inline comments as done.
lawrence_danna added a comment.

review fixes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,15 +667,27 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
 const char *script = "class Foo: \n"
  "  def bar(self, x):\n"
  " return x \n"
+ "  @classmethod \n"
+ "  def classbar(cls, x):\n"
+ " return x \n"
+ "  @staticmethod \n"
+ "  def staticbar(x):\n"
+ " return x \n"
+ "  def __call__(self, x): \n"
+ " return x \n"
+ "obj = Foo() \n"
  "bar_bound   = Foo().bar \n"
+ "bar_class   = Foo().classbar \n"
+ "bar_static  = Foo().staticbar \n"
  "bar_unbound = Foo.bar \n";
 PyObject *o =
 PyRun_String(script, Py_file_input, globals.get(), globals.get());
@@ -687,16 +699,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -710,9 +743,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna added a comment.

fixed


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna updated this revision to Diff 225297.
lawrence_danna added a comment.

comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,15 +667,27 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args,
+  PythonCallable::ArgInfo::UNBOUNDED);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
 const char *script = "class Foo: \n"
  "  def bar(self, x):\n"
  " return x \n"
+ "  @classmethod \n"
+ "  def classbar(cls, x):\n"
+ " return x \n"
+ "  @staticmethod \n"
+ "  def staticbar(x):\n"
+ " return x \n"
+ "  def __call__(self, x): \n"
+ " return x \n"
+ "obj = Foo() \n"
  "bar_bound   = Foo().bar \n"
+ "bar_class   = Foo().classbar \n"
+ "bar_static  = Foo().staticbar \n"
  "bar_unbound = Foo.bar \n";
 PyObject *o =
 PyRun_String(script, Py_file_input, globals.get(), globals.get());
@@ -687,16 +699,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -710,9 +743,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1u);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna added a comment.

In D69014#1711400 , @jingham wrote:

> IIUC, the only external change in this patch is that before if you 
> implemented your Python command using a class with an `__call__` method, it 
> would have to be the signature that took exe_ctx.   Since this is now 
> switching off of the number of arguments (less self) you could make an 
> `__call__` form that didn't take the extra argument.  I certainly want to 
> discourage that, since the form without the exe_ctx will do the wrong thing 
> in some contexts (e.g. if the command is used in breakpoint callbacks or 
> stop-hooks).  It looks like that would be easy to prevent, you know that 
> you've found __call__ right above where you check.  So I think it would be 
> better to explicitly disallow __call__forms that don't take the exe_ctx.
>
> This is different from the extra_args cases in the breakpoint callbacks and 
> thread plans and so forth.  In those cases, if you don't need extra_args, 
> there's no good reason why you should have to have them.  But in the case of 
> Python commands, it's actually more correct to get the state you are 
> operating on from the exe_ctx.  Otherwise you have to fall back on the 
> currently selected process/thread/frame/etc, and there are contexts (like 
> when you have multiple targets all hitting breakpoints simultaneously) where 
> it does not make sense to have the currently selected state track what 
> process/thread/frame are pertinent to the operation of a breakpoint command 
> or stop hook.  So I do want to gently discourage this form of command.


Right now what happens on trunk is that commands implemented with `__call__` 
just don't work at all on any version of python with either 4 or 5 arguments.

If you look at my latest update, you can see I fix a bug in the old 
implementation `GetNumArguments` where it looks for `im_self` on the original 
object, not the `__call__`.   I fixed it to look at the `__call__` attribute, 
but that is not even entirely correct either, because the python data model 
states that `__call__` is one of the magic methods that must be set on the 
//class//, and cannot be overridden for individual objects.   Oh wait, no, that 
was the python 2.7 data model, it looks like they changed it in 3 so `foo()` 
really is synonymous with `foo.__call__()`

My point here is that python callables are complicated.   They are code.   
Their implementation is liable to change, both because Python itself will 
change, and because users will change what they put in them.I understand 
the backwards-compatibility argument for why we should inspect them, but even 
so, we should inspect them //as little as possible//.  Ideally the only 
inspection we'll ever do is to ask "can this callable take  N arguments?".   
And when we ask that question we should ask it in the documented way, not by 
peeking inside method wrappers and python code objects and trying to understand 
them.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna updated this revision to Diff 225284.
lawrence_danna added a comment.

added tests for __call__ objects, and a fix for python2


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,15 +667,26 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, INT_MAX);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
 const char *script = "class Foo: \n"
  "  def bar(self, x):\n"
  " return x \n"
+ "  @classmethod \n"
+ "  def classbar(cls, x):\n"
+ " return x \n"
+ "  @staticmethod \n"
+ "  def staticbar(x):\n"
+ " return x \n"
+ "  def __call__(self, x): \n"
+ " return x \n"
+ "obj = Foo() \n"
  "bar_bound   = Foo().bar \n"
+ "bar_class   = Foo().classbar \n"
+ "bar_static  = Foo().staticbar \n"
  "bar_unbound = Foo.bar \n";
 PyObject *o =
 PyRun_String(script, Py_file_input, globals.get(), globals.get());
@@ -687,16 +698,37 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_class = As(globals.GetItem("bar_class"));
+ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
+arginfo = bar_class.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto bar_static = As(globals.GetItem("bar_static"));
+ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
+arginfo = bar_static.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
+EXPECT_EQ(arginfo.get().has_varargs, false);
+
+auto obj = As(globals.GetItem("obj"));
+ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
+arginfo = obj.get().GetArgInfo();
+ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -710,9 +742,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, 

[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Jim Ingham via Phabricator via lldb-commits
jingham added a comment.

IIUC, the only external change in this patch is that before if you implemented 
your Python command using a class with an `__call__` method, it would have to 
be the signature that took exe_ctx.   Since this is now switching off of the 
number of arguments (less self) you could make an `__call__` form that didn't 
take the extra argument.  I certainly want to discourage that, since the form 
without the exe_ctx will do the wrong thing in some contexts (e.g. if the 
command is used in breakpoint callbacks or stop-hooks).  It looks like that 
would be easy to prevent, you know that you've found __call__ right above where 
you check.  So I think it would be better to explicitly disallow __call__forms 
that don't take the exe_ctx.

This is different from the extra_args cases in the breakpoint callbacks and 
thread plans and so forth.  In those cases, if you don't need extra_args, 
there's no good reason why you should have to have them.  But in the case of 
Python commands, it's actually more correct to get the state you are operating 
on from the exe_ctx.  Otherwise you have to fall back on the currently selected 
process/thread/frame/etc, and there are contexts (like when you have multiple 
targets all hitting breakpoints simultaneously) where it does not make sense to 
have the currently selected state track what process/thread/frame are pertinent 
to the operation of a breakpoint command or stop hook.  So I do want to gently 
discourage this form of command.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-16 Thread Pavel Labath via Phabricator via lldb-commits
labath added a comment.

The code itself looks fine to me. Jim, is this ok from a 
scripting/compatibility/whatnot perspective?




Comment at: 
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py:25
 
+if sys.version_info[:2] >= (3, 3) or sys.version_info.major < 3:
+# Test a bunch of different kinds of python callables with

Do we have to worry about 3.0<=python<=3.3 actually? Unlike 2.7, these have 
actually been EOLed already, and I would expect/hope that anyone who is not 
stuck at 2.7 has upgraded past them..



Comment at: lldb/scripts/Python/python-wrapper.swig:701-702
+if (!argc) {
+llvm::consumeError(argc.takeError());
+return false;
+}

There is a possibility to shorten this to `return 
errorToBool(argc.takeError())` though I am undecided whether that makes things 
clearer or not, so I am mainly writing this to make you aware of that 
possibility. I'll leave that up to you to decide whether to use it...



Comment at: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h:634
+ * accept an arbitrary number */
+int max_positional_args;
 /* the number of positional arguments, including optional ones,

Make this unsigned, and add a symbolic constant (static constexpr unsigned) for 
the "varargs" value.

I've also considered making the vararg-ness more explicit via 
`Optional` but (U)INTMAX is actually a pretty good value for the 
varargs and it enables you to handle this case with a single comparison, so the 
explicitness is probably not worth it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69014



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


[Lldb-commits] [PATCH] D69014: [LLDB] bugfix: command script add -f doesn't work for some callables

2019-10-15 Thread Lawrence D'Anna via Phabricator via lldb-commits
lawrence_danna created this revision.
lawrence_danna added reviewers: JDevlieghere, clayborg, labath, jingham.
Herald added a project: LLDB.
lawrence_danna added a parent revision: D68995: clean up the implementation of 
PythonCallable::GetNumArguments.

When users define a debugger command from python, they provide a callable 
object.   Because the signature of the function has been extended, LLDB
needs to inspect the number of parameters the callable can take.

The rule it was using to decide was weird, apparently not tested, and 
giving wrong results for some kinds of python callables.

This patch replaces the weird rule with a simple one: if the callable can
take 5 arguments, it gets the 5 argument version of the signature.   
Otherwise it gets the old 4 argument version.

It also adds tests with a bunch of different kinds of python callables
with both 4 and 5 arguments.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69014

Files:
  
lldb/packages/Python/lldbsuite/test/commands/command/script/TestCommandScript.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/callables.py
  lldb/packages/Python/lldbsuite/test/commands/command/script/py_import
  lldb/scripts/Python/python-wrapper.swig
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -643,8 +643,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -655,8 +655,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -667,8 +667,8 @@
 auto arginfo = lambda.GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, INT_MAX);
 EXPECT_EQ(arginfo.get().has_varargs, true);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
   {
@@ -687,16 +687,16 @@
 auto arginfo = bar_bound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+EXPECT_EQ(arginfo.get().max_positional_args, 1); // FIXME, wrong
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, true);
 
 auto bar_unbound = As(globals.GetItem("bar_unbound"));
 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
 arginfo = bar_unbound.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 2);
+EXPECT_EQ(arginfo.get().max_positional_args, 2);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -710,9 +710,9 @@
 auto arginfo = hex.get().GetArgInfo();
 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
 EXPECT_EQ(arginfo.get().count, 1);
+EXPECT_EQ(arginfo.get().max_positional_args, 1);
 EXPECT_EQ(arginfo.get().has_varargs, false);
-EXPECT_EQ(arginfo.get().is_bound_method, false);
   }
 
 #endif
 }
\ No newline at end of file
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
===
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -628,6 +628,10 @@
   using TypedPythonObject::TypedPythonObject;
 
   struct ArgInfo {
+/* the largest number of positional arguments this callable
+ * can accept, or INT_MAX if it's a varargs function and can
+ * accept an arbitrary number */
+int max_positional_args;
 /* the number of positional arguments, including optional ones,
  * and excluding varargs.  If this is a bound method, then the
  * count will still include a +1 for self.
@@ -638,8 +642,6 @@
 int count;
 /* does the callable have positional varargs? */
 bool has_varargs : 1; // FIXME delete this
-/* is the callable a bound method written in python? */
-bool is_bound_method : 1; // FIXME delete this
   };
 
   static bool Check(PyObject *py_obj);
Index: