[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-11 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova closed 
https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-11 Thread Med Ismail Bennani via lldb-commits

https://github.com/medismailben approved this pull request.

LGTM!

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-11 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova updated 
https://github.com/llvm/llvm-project/pull/94518

>From 4e40f07e424458be6e44cc41d333f38763a0d0fb Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova 
Date: Wed, 5 Jun 2024 11:24:01 -0700
Subject: [PATCH] [lldb][api-test] Add API test for
 SBCommandInterpreter::CommandOverrideCallback

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to
the Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing
this involves also adding a typemap for the callback used for this
function so that it matches the functionality of other callback
functions that are exposed to Python.
---
 lldb/bindings/python/python-typemaps.swig | 18 ++-
 lldb/bindings/python/python-wrapper.swig  | 22 +
 lldb/include/lldb/API/SBCommandInterpreter.h  |  2 --
 .../TestCommandOverrideCallback.py| 31 +++
 4 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 
lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py

diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..c39594c7df041 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // Don't lose the callback reference.
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..bd3de8ce5d46c 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,28 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool ret_val = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+// Create a PyList of items since we're going to pass it to the callback 
as a tuple
+// of arguments.
+PyObject *py_argv = PyList_New(0);
+for (const char **arg = argv; arg && *arg; arg++) {
+  std::string arg_string = *arg;
+  PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), 
arg_string.size());
+  PyList_Append(py_argv, py_string);
+}
+
+PyObject *result = PyObject_CallObject(
+reinterpret_cast(baton), PyList_AsTuple(py_argv));
+ret_val = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return ret_val;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new file mode 100644
index 0..a593feb0012d9
--- /dev/null
+++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
@@ -0,0 +1,31 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from 

[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova updated 
https://github.com/llvm/llvm-project/pull/94518

>From a7215585f55617a41f7c8e566088d3f50203fe55 Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova 
Date: Wed, 5 Jun 2024 11:24:01 -0700
Subject: [PATCH] [lldb][api-test] Add API test for
 SBCommandInterpreter::CommandOverrideCallback

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to
the Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing
this involves also adding a typemap for the callback used for this
function so that it matches the functionality of other callback
functions that are exposed to Python.
---
 lldb/bindings/python/python-typemaps.swig | 18 ++-
 lldb/bindings/python/python-wrapper.swig  | 22 ++
 lldb/include/lldb/API/SBCommandInterpreter.h  |  2 --
 .../TestCommandOverrideCallback.py| 30 +++
 4 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 
lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py

diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..c39594c7df041 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // Don't lose the callback reference.
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..bd3de8ce5d46c 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,28 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool ret_val = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+// Create a PyList of items since we're going to pass it to the callback 
as a tuple
+// of arguments.
+PyObject *py_argv = PyList_New(0);
+for (const char **arg = argv; arg && *arg; arg++) {
+  std::string arg_string = *arg;
+  PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), 
arg_string.size());
+  PyList_Append(py_argv, py_string);
+}
+
+PyObject *result = PyObject_CallObject(
+reinterpret_cast(baton), PyList_AsTuple(py_argv));
+ret_val = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return ret_val;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new file mode 100644
index 0..9ff16efd82859
--- /dev/null
+++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
@@ -0,0 +1,30 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from 

[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,27 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class CommandOverrideCallback(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.line = line_number("main.c", "Hello world.")
+
+def test_command_override_callback(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+
+target = self.dbg.CreateTarget(exe)
+self.assertTrue(target, VALID_TARGET)
+
+ci = self.dbg.GetCommandInterpreter()
+self.assertTrue(ci, VALID_COMMAND_INTERPRETER)
+
+def foo(*command_args):
+pass
+
+self.assertTrue(ci.SetCommandOverrideCallback("breakpoint set", foo))
+self.expect("breakpoint set -n main", substrs=["Breakpoint"])

JDevlieghere wrote:

This doesn't test the baton or the fact that the function was called. You 
should have the foo callback modify a variable or something and verify that the 
function has been called. 

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Jonas Devlieghere via lldb-commits


@@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // Don't lose the callback reference

JDevlieghere wrote:

Nit: missing period. 

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere edited 
https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-07 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova updated 
https://github.com/llvm/llvm-project/pull/94518

>From 44e8cab5d45a87eb1ea2076c498abe5be423eb1c Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova 
Date: Wed, 5 Jun 2024 11:24:01 -0700
Subject: [PATCH] [lldb][api-test] Add API test for
 SBCommandInterpreter::CommandOverrideCallback

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to
the Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing
this involves also adding a typemap for the callback used for this
function so that it matches the functionality of other callback
functions that are exposed to Python.
---
 lldb/bindings/python/python-typemaps.swig | 18 -
 lldb/bindings/python/python-wrapper.swig  | 22 +++
 lldb/include/lldb/API/SBCommandInterpreter.h  |  2 --
 .../TestCommandOverrideCallback.py| 27 +++
 4 files changed, 66 insertions(+), 3 deletions(-)
 create mode 100644 
lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py

diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..ff698907568c8 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..bd3de8ce5d46c 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,28 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool ret_val = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+// Create a PyList of items since we're going to pass it to the callback 
as a tuple
+// of arguments.
+PyObject *py_argv = PyList_New(0);
+for (const char **arg = argv; arg && *arg; arg++) {
+  std::string arg_string = *arg;
+  PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), 
arg_string.size());
+  PyList_Append(py_argv, py_string);
+}
+
+PyObject *result = PyObject_CallObject(
+reinterpret_cast(baton), PyList_AsTuple(py_argv));
+ret_val = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return ret_val;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new file mode 100644
index 0..e8d374987fc90
--- /dev/null
+++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
@@ -0,0 +1,27 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from 

[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Chelsea Cassanova via lldb-commits


@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already

chelcassanova wrote:

I'm not opposed to that, this same message appears for the other 2 callbacks.

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Chelsea Cassanova via lldb-commits


@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::CommandOverrideCallback callback,
+

chelcassanova wrote:

Yup, I kind of wish that SWIG had a formatter like `clang-format`.

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Alex Langford via lldb-commits


@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::CommandOverrideCallback callback,
+

bulbazord wrote:

stray line?

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Alex Langford via lldb-commits


@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already

bulbazord wrote:

I'd say remove the FIXME entirely, it shouldn't apply to this.
As a side note, I think in the LLVM project we generally discourage the pattern 
of `FIXME (name)` and `TODO (name)`. Maybe we should go clean up the original 
instance too? :p

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Alex Langford via lldb-commits


@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;

bulbazord wrote:

Can you change the name `b` to something with more meaning? Maybe something 
like `ret_val`?

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Alex Langford via lldb-commits


@@ -0,0 +1,30 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class CommandOverrideCallback(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.line = line_number("main.c", "Hello world.")
+
+def test_command_override_callback(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+
+# Create a target by the debugger.
+target = self.dbg.CreateTarget(exe)
+self.assertTrue(target, VALID_TARGET)
+
+# Retrieve the associated command interpreter from our debugger.

bulbazord wrote:

Same for this comment.

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-06 Thread Alex Langford via lldb-commits


@@ -0,0 +1,30 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class CommandOverrideCallback(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.line = line_number("main.c", "Hello world.")
+
+def test_command_override_callback(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+
+# Create a target by the debugger.

bulbazord wrote:

I don't think this comment is helpful because it's telling me what the code is 
doing, not why it's doing it. I'd suggest removing it because pretty much every 
test does this.

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Chelsea Cassanova via lldb-commits


@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+PyObject *result = PyObject_CallFunction(
+  reinterpret_cast(baton), const_cast("s"), argv); // 
WRONG!

chelcassanova wrote:

Yes, forgot to do this here when I cleaned this up and you can see the comment 
from that  

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Med Ismail Bennani via lldb-commits


@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+PyObject *result = PyObject_CallFunction(
+  reinterpret_cast(baton), const_cast("s"), argv); // 
WRONG!

medismailben wrote:

You need to convert your `char**` into a `PyList` of `PyString` before passing 
it here I think

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Med Ismail Bennani via lldb-commits


@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already

medismailben wrote:

filcab ?

https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Med Ismail Bennani via lldb-commits

https://github.com/medismailben edited 
https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Med Ismail Bennani via lldb-commits

https://github.com/medismailben requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova updated 
https://github.com/llvm/llvm-project/pull/94518

>From e4ba69ac4983e4e2882200e7efe0e850eeefae21 Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova 
Date: Wed, 5 Jun 2024 11:24:01 -0700
Subject: [PATCH] [lldb][api-test] Add API test for
 SBCommandInterpreter::CommandOverrideCallback

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to
the Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing
this involves also adding a typemap for the callback used for this
function so that it matches the functionality of other callback
functions that are exposed to Python.
---
 lldb/bindings/python/python-typemaps.swig | 27 -
 lldb/bindings/python/python-wrapper.swig  | 13 
 lldb/include/lldb/API/SBCommandInterpreter.h  |  2 --
 .../TestCommandOverrideCallback.py| 30 +++
 4 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 
lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py

diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..1bf93c59fbc7b 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::CommandOverrideCallback callback,
+
+  void *baton) {
+
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..0a332cb0a2ff4 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+PyObject *result = PyObject_CallFunction(
+  reinterpret_cast(baton), const_cast("s"), argv); // 
WRONG!
+b = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return b;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new file mode 100644
index 0..067f37f88096d
--- /dev/null
+++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
@@ -0,0 +1,30 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class 

[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread via lldb-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
c6c08eee37bada190bd1aa4593c88a5e2c8cdaac...90602ed1b2f27fecb9e1fc28419587cf6bcb04bf
 lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
``





View the diff from darker here.


``diff
--- TestCommandOverrideCallback.py  2024-06-05 18:31:49.00 +
+++ TestCommandOverrideCallback.py  2024-06-05 18:35:47.810046 +
@@ -1,10 +1,11 @@
 from typing_extensions import override
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
+
 
 class CommandOverrideCallback(TestBase):
 def setUp(self):
 TestBase.setUp(self)
 self.line = line_number("main.c", "Hello world.")
@@ -20,10 +21,11 @@
 # Retrieve the associated command interpreter from our debugger.
 ci = self.dbg.GetCommandInterpreter()
 self.assertTrue(ci, VALID_COMMAND_INTERPRETER)
 
 override_string = "what"
+
 def foo(string):
 nonlocal override_string
 override_string = string
 return False
 

``




https://github.com/llvm/llvm-project/pull/94518
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Chelsea Cassanova (chelcassanova)


Changes

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to the 
Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing this 
involves also adding a typemap for the callback used for this function so that 
it matches the functionality of other callback functions that are exposed to 
Python.

---
Full diff: https://github.com/llvm/llvm-project/pull/94518.diff


4 Files Affected:

- (modified) lldb/bindings/python/python-typemaps.swig (+26-1) 
- (modified) lldb/bindings/python/python-wrapper.swig (+13) 
- (modified) lldb/include/lldb/API/SBCommandInterpreter.h (-2) 
- (added) lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
(+30) 


``diff
diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..1bf93c59fbc7b 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::CommandOverrideCallback callback,
+
+  void *baton) {
+
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..0a332cb0a2ff4 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+PyObject *result = PyObject_CallFunction(
+  reinterpret_cast(baton), const_cast("s"), argv); // 
WRONG!
+b = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return b;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new file mode 100644
index 0..067f37f88096d
--- /dev/null
+++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
@@ -0,0 +1,30 @@
+from typing_extensions import override
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class CommandOverrideCallback(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.line = line_number("main.c", "Hello world.")
+
+def test_command_override_callback(self):
+self.build()
+exe = 

[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)

2024-06-05 Thread Chelsea Cassanova via lldb-commits

https://github.com/chelcassanova created 
https://github.com/llvm/llvm-project/pull/94518

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to the 
Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing this 
involves also adding a typemap for the callback used for this function so that 
it matches the functionality of other callback functions that are exposed to 
Python.

>From 90602ed1b2f27fecb9e1fc28419587cf6bcb04bf Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova 
Date: Wed, 5 Jun 2024 11:24:01 -0700
Subject: [PATCH] [lldb][api-test] Add API test for
 SBCommandInterpreter::CommandOverrideCallback

`SBCommandInterpreter::CommandOverrideCallback` was not being exposed to
the Python API has no coverage in the
API test suite, so this commits exposes and adds a test for it. Doing
this involves also adding a typemap for the callback used for this
function so that it matches the functionality of other callback
functions that are exposed to Python.
---
 lldb/bindings/python/python-typemaps.swig | 27 -
 lldb/bindings/python/python-wrapper.swig  | 13 
 lldb/include/lldb/API/SBCommandInterpreter.h  |  2 --
 .../TestCommandOverrideCallback.py| 30 +++
 4 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 
lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py

diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index 8d4b740e5f35c..1bf93c59fbc7b 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   free($1);
 }
 
-
 // For Log::LogOutputCallback
 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
   if (!($input == Py_None ||
@@ -476,6 +475,32 @@ template <> bool SetNumberFromPyObject(double 
, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the 
previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::CommandOverrideCallback callback,
+
+  void *baton) {
+
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) lldb::FileSP {
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 1370afc885d43..0a332cb0a2ff4 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1099,6 +1099,19 @@ static void 
LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t
   }
 }
 
+static bool 
LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void 
*baton, const char **argv) {
+  bool b = false;
+  if (baton != Py_None) {
+SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+PyObject *result = PyObject_CallFunction(
+  reinterpret_cast(baton), const_cast("s"), argv); // 
WRONG!
+b = result ? PyObject_IsTrue(result) : false;
+Py_XDECREF(result);
+SWIG_PYTHON_THREAD_END_BLOCK;
+  }
+  return b;
+}
+
 static SBError LLDBSwigPythonCallLocateModuleCallback(
 void *callback_baton, const SBModuleSpec _spec_sb,
 SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) {
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h 
b/lldb/include/lldb/API/SBCommandInterpreter.h
index 8ac36344b3a79..084b6d9adb703 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -265,11 +265,9 @@ class SBCommandInterpreter {
   // Catch commands before they execute by registering a callback that will get
   // called when the command gets executed. This allows GUI or command line
   // interfaces to intercept a command and stop it from happening
-#ifndef SWIG
   bool SetCommandOverrideCallback(const char *command_name,
   lldb::CommandOverrideCallback callback,
   void *baton);
-#endif
 
   /// Return true if the command interpreter is the active IO handler.
   ///
diff --git 
a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py 
b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py
new