Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0b5768c

Browse files
committed
Improves debugging in IDE.
1 parent 4385e0b commit 0b5768c

File tree

2 files changed

+37
-36
lines changed

2 files changed

+37
-36
lines changed

‎doc/sphinx/source/debugging/debug_in_ide.rst

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Debuging Python C Extensions in an IDE
1717

1818
The basic idea is to compile/link your C extension in your IDE and get ``main()`` to call a function ``int import_call_execute(int argc, const char *argv[])`` that embeds the Python interpreter which then imports a Python module, say a unit test, that exercises your C extension code.
1919

20-
This ``import_call_execute()`` entry point is fairly generic and takes the standard arguments to ``main()``.
20+
This ``import_call_execute()`` entry point is fairly generic and takes the standard arguments to ``main()`` so it can be in its own .h/.c file.
2121

2222
------------------------------------------------
2323
Creating a Python Unit Test to Execute
@@ -39,38 +39,34 @@ Suppose you have a Python extension ``ScList`` that sub-classes a list and count
3939
Writing a C Function to call any Python Unit Test
4040
-------------------------------------------------------
4141

42-
We write the ``import_call_execute()`` function to take that same arguments as ``main()`` and ``import_call_execute()`` expects 4 arguments:
42+
We create the ``import_call_execute()`` function that takes that same arguments as ``main()`` which can forward its arguments. ``import_call_execute()`` expects 4 arguments:
4343

4444
* ``argc[0]`` - Name of the executable.
4545
* ``argc[1]`` - Path to the directory that the Python module is in.
4646
* ``argc[2]`` - Name of the Python module to be imported. This could be a unit test module for example.
4747
* ``argc[3]`` - Name of the Python function in the Python module (no arguments will be supplied, the return value is ignored). This could be a particular unit test.
4848

49-
The ``import_call_execute()`` function does this, in this particular case:
49+
The ``import_call_execute()`` function does this:
5050

5151
#. Check the arguments and initialises the Python interpreter
52-
#. Add the path to the ``test_sclist.py`` to ``sys.paths``.
53-
#. Import ``test_sclist``.
54-
#. Find the function ``test()`` in module ``test_sclist`` and call it.
52+
#. Add the path to the ``argc[1]`` to ``sys.paths``.
53+
#. Import ``argc[2]``.
54+
#. Find the function ``argc[3]`` in module ``argc[2]`` and call it.
5555
#. Clean up.
5656

5757

5858
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959
Code Walk Through
6060
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6161

62-
So ``import_call_execute()`` is quite generic, here is a walk through of the code, the whole code is below.
62+
``import_call_execute()`` is quite generic and could be implemented in, say, ``py_import_call_execute.c``.
63+
64+
Here is a walk through of the implementation code:
6365

6466
Step 1: Check the arguments and initialise the Python interpreter
6567

6668
.. code-block:: c
6769
68-
#include <Python.h>
69-
70-
/** This should be the name of your executable.
71-
* It is just used for error messages. */
72-
#define EXECUTABLE_NAME "pyxcode"
73-
7470
/** This imports a Python module and calls a specific function in it.
7571
* It's arguments are similar to main():
7672
* argc - Number of strings in argv
@@ -96,7 +92,7 @@ Step 1: Check the arguments and initialise the Python interpreter
9692
if (argc != 4) {
9793
fprintf(stderr,
9894
"Wrong arguments!"
99-
" Usage: " EXECUTABLE_NAME " package_path module function\n");
95+
" Usage: %s package_path module function\n", argv[0]);
10096
return_value = -1;
10197
goto except;
10298
}
@@ -204,28 +200,33 @@ Step 5: Clean up.
204200
return return_value;
205201
}
206202
203+
And then we need ``main()`` to call this, thus:
204+
205+
.. code-block:: c
206+
207+
#include "py_import_call_execute.h"
208+
209+
int main(int argc, const char *argv[]) {
210+
return import_call_execute(argc, argv);
211+
}
212+
213+
207214
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
208215
Complete Code
209216
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210217

211-
The complete code for the file is here:
218+
The complete code for ``py_import_call_execute.c`` is here:
212219

213220
.. code-block:: c
214221
215-
//
216-
// main.c
217-
// PythonSubclassList
218-
//
219-
// Created by Paul Ross on 01/05/2016.
220-
// Copyright (c) 2016 Paul Ross. All rights reserved.
221-
//
222+
#include "py_import_call_execute.h"
222223
223224
#include <Python.h>
224225
225-
/** This should be the name of your executable.
226-
* It is just used for error messages. */
227-
#define EXECUTABLE_NAME "pyxcode"
228-
226+
#ifdef __cplusplus
227+
extern "C" {
228+
#endif
229+
229230
/** Takes a path and adds it to sys.paths by calling PyRun_SimpleString.
230231
* This does rather laborious C string concatenation so that it will work in
231232
* a primitive C environment.
@@ -282,7 +283,7 @@ The complete code for the file is here:
282283
if (argc != 4) {
283284
fprintf(stderr,
284285
"Wrong arguments!"
285-
" Usage: " EXECUTABLE_NAME " package_path module function\n");
286+
" Usage: %s package_path module function\n", argv[0]);
286287
return_value = -1;
287288
goto except;
288289
}
@@ -295,31 +296,31 @@ The complete code for the file is here:
295296
pModule = PyImport_ImportModule(argv[2]);
296297
if (! pModule) {
297298
fprintf(stderr,
298-
EXECUTABLE_NAME ": Failed to load module \"%s\"\n", argv[2]);
299+
"%s: Failed to load module \"%s\"\n", argv[0], argv[2]);
299300
return_value = -3;
300301
goto except;
301302
}
302303
pFunc = PyObject_GetAttrString(pModule, argv[3]);
303304
if (! pFunc) {
304305
fprintf(stderr,
305-
EXECUTABLE_NAME ": Can not find function \"%s\"\n", argv[3]);
306+
"%s: Can not find function \"%s\"\n", argv[0], argv[3]);
306307
return_value = -4;
307308
goto except;
308309
}
309310
if (! PyCallable_Check(pFunc)) {
310311
fprintf(stderr,
311-
EXECUTABLE_NAME ": Function \"%s\" is not callable\n", argv[3]);
312+
"%s: Function \"%s\" is not callable\n", argv[0], argv[3]);
312313
return_value = -5;
313314
goto except;
314315
}
315316
pResult = PyObject_CallObject(pFunc, NULL);
316317
if (! pResult) {
317-
fprintf(stderr, EXECUTABLE_NAME ": Function call failed\n");
318+
fprintf(stderr, "%s: Function call failed\n", argv[0]);
318319
return_value = -6;
319320
goto except;
320321
}
321322
#ifdef DEBUG
322-
printf(EXECUTABLE_NAME ": PyObject_CallObject() succeeded\n");
323+
printf("%s: PyObject_CallObject() succeeded\n", argv[0]);
323324
#endif
324325
assert(! PyErr_Occurred());
325326
goto finally;
@@ -333,10 +334,10 @@ The complete code for the file is here:
333334
Py_Finalize();
334335
return return_value;
335336
}
336-
337-
int main(int argc, const char *argv[]) {
338-
return import_call_execute(argc, argv);
339-
}
337+
338+
#ifdef __cplusplus
339+
// extern "C" {
340+
#endif
340341
341342
342343
--------------------------------------------
4.73 KB
Binary file not shown.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /