Skip to content

Commit 87efb24

Browse files
committed
Moves Python calling code int separate generic file py_import_call_execute.h/.c
1 parent 7ec68ce commit 87efb24

File tree

7 files changed

+184
-116
lines changed

7 files changed

+184
-116
lines changed

doc/sphinx/source/debugging/debug_python.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,12 @@ The Debug Builds
5656
---------------------------
5757

5858
The builds are controlled by the following macros:
59-
60-
59+
6160
=================== ======================================================= ==============
6261
Macro Description Must Rebuild
6362
Extensions?
6463
=================== ======================================================= ==============
65-
``Py_DEBUG`` A standard debug build. ``Py_DEBUG`` implies Yes
64+
``Py_DEBUG`` A standard debug build. ``Py_DEBUG`` sets Yes
6665
``LLTRACE``, ``Py_REF_DEBUG``, ``Py_TRACE_REFS``, and
6766
``PYMALLOC_DEBUG`` (if ``WITH_PYMALLOC`` is enabled).
6867
``Py_REF_DEBUG`` Turn on aggregate reference counting which will be No
@@ -73,7 +72,7 @@ Macro Description Must
7372
Also adds ``sys.gettotalrefcount()`` to the ``sys``
7473
module and this returns the total number of references.
7574
``Py_TRACE_REFS`` Turns on reference tracing. Yes
76-
Implies ``Py_REF_DEBUG``.
75+
Sets ``Py_REF_DEBUG``.
7776
``COUNT_ALLOCS`` Keeps track of the number of objects of each type have Yes
7877
been allocated and how many freed.
7978
See: :ref:`debug-version-of-python-COUNT_ALLOCS-label`
@@ -87,7 +86,13 @@ Macro Description Must
8786
See: :ref:`debug-version-of-python-memory_alloc-label`
8887
=================== ======================================================= ==============
8988

89+
Here is the description of other debug macros that are set by one of the macros above:
9090

91+
=================== =======================================================
92+
Macro Description
93+
=================== =======================================================
94+
``LLTRACE`` Low level tracing. See ``Python/ceval.c``.
95+
=================== =======================================================
9196

9297
In the source directory:
9398

@@ -120,7 +125,7 @@ To make a version of Python with its memory allocator suitable for use with Valg
120125
../configure --with-pydebug --without-pymalloc
121126
make
122127
123-
See :ref:`valgrind-label` for using Valgrind.
128+
See :ref:`using-valgrind-label` for using Valgrind.
124129

125130
To make a version of Python with its memory allocator using Python's malloc debugger either:
126131

src/debugging/XcodeExample/PythonSubclassList/PythonSubclassList.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
C31CD38E1CD6484100863554 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = C31CD38D1CD6484100863554 /* main.c */; };
1111
C31CD3981CD6495F00863554 /* SubclassList.c in Sources */ = {isa = PBXBuildFile; fileRef = C31CD3961CD6495F00863554 /* SubclassList.c */; };
1212
C31CD39D1CD929B700863554 /* py_call_super.c in Sources */ = {isa = PBXBuildFile; fileRef = C31CD39B1CD929B700863554 /* py_call_super.c */; };
13+
C3814CF51D0B46D100BC0384 /* py_import_call_execute.c in Sources */ = {isa = PBXBuildFile; fileRef = C3814CF31D0B46D100BC0384 /* py_import_call_execute.c */; };
1314
C3B45DD41CFE0DCA002A9D18 /* Python in Frameworks */ = {isa = PBXBuildFile; fileRef = C3B45DD31CFE0DC9002A9D18 /* Python */; };
1415
/* End PBXBuildFile section */
1516

@@ -33,6 +34,8 @@
3334
C31CD3991CD7A2BC00863554 /* setup.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = setup.py; sourceTree = "<group>"; };
3435
C31CD39B1CD929B700863554 /* py_call_super.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = py_call_super.c; sourceTree = "<group>"; };
3536
C31CD39C1CD929B700863554 /* py_call_super.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = py_call_super.h; sourceTree = "<group>"; };
37+
C3814CF31D0B46D100BC0384 /* py_import_call_execute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = py_import_call_execute.c; sourceTree = "<group>"; };
38+
C3814CF41D0B46D100BC0384 /* py_import_call_execute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = py_import_call_execute.h; sourceTree = "<group>"; };
3639
C3913BA41CE20386005A5E45 /* test_sclist.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = test_sclist.py; sourceTree = "<group>"; };
3740
C3B45DD31CFE0DC9002A9D18 /* Python */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = Python; path = ../../../../../../../../../../Library/Frameworks/Python.framework/Versions/3.4/Python; sourceTree = "<group>"; };
3841
/* End PBXFileReference section */
@@ -76,6 +79,8 @@
7679
C31CD3971CD6495F00863554 /* SubclassList.h */,
7780
C31CD39B1CD929B700863554 /* py_call_super.c */,
7881
C31CD39C1CD929B700863554 /* py_call_super.h */,
82+
C3814CF31D0B46D100BC0384 /* py_import_call_execute.c */,
83+
C3814CF41D0B46D100BC0384 /* py_import_call_execute.h */,
7984
);
8085
path = PythonSubclassList;
8186
sourceTree = "<group>";
@@ -137,6 +142,7 @@
137142
buildActionMask = 2147483647;
138143
files = (
139144
C31CD38E1CD6484100863554 /* main.c in Sources */,
145+
C3814CF51D0B46D100BC0384 /* py_import_call_execute.c in Sources */,
140146
C31CD39D1CD929B700863554 /* py_call_super.c in Sources */,
141147
C31CD3981CD6495F00863554 /* SubclassList.c in Sources */,
142148
);

src/debugging/XcodeExample/PythonSubclassList/PythonSubclassList.xcodeproj/xcuserdata/paulross.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
symbolName = "call_super_pyname"
7272
moduleName = "PythonSubclassList"
7373
urlString = "file:///Users/paulross/Documents/workspace/PythonExtensionPatterns/src/debugging/XcodeExample/PythonSubclassList/PythonSubclassList/py_call_super.c"
74-
timestampString = "486491056.006566"
74+
timestampString = "487278611.130096"
7575
startingColumnNumber = "9223372036854775807"
7676
endingColumnNumber = "9223372036854775807"
7777
startingLineNumber = "49"
@@ -85,7 +85,7 @@
8585
symbolName = "call_super_pyname"
8686
moduleName = "ScList.so"
8787
urlString = "file:///Users/paulross/Documents/workspace/PythonExtensionPatterns/src/debugging/XcodeExample/PythonSubclassList/PythonSubclassList/py_call_super.c"
88-
timestampString = "486491056.315771"
88+
timestampString = "487278611.358352"
8989
startingColumnNumber = "9223372036854775807"
9090
endingColumnNumber = "9223372036854775807"
9191
startingLineNumber = "49"

src/debugging/XcodeExample/PythonSubclassList/PythonSubclassList/main.c

Lines changed: 1 addition & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -6,115 +6,7 @@
66
// Copyright (c) 2016 Paul Ross. All rights reserved.
77
//
88

9-
#include <Python.h>
10-
11-
/** Takes a path and adds it to sys.paths by calling PyRun_SimpleString.
12-
* This does rather laborious C string concatenation so that it will work in
13-
* a primitive C environment.
14-
*
15-
* Returns 0 on success, non-zero on failure.
16-
*/
17-
int add_path_to_sys_module(const char *path) {
18-
int ret = 0;
19-
const char *prefix = "import sys\nsys.path.append(\"";
20-
const char *suffix = "\")\n";
21-
char *command = (char*)malloc(strlen(prefix)
22-
+ strlen(path)
23-
+ strlen(suffix)
24-
+ 1);
25-
if (! command) {
26-
return -1;
27-
}
28-
strcpy(command, prefix);
29-
strcat(command, path);
30-
strcat(command, suffix);
31-
ret = PyRun_SimpleString(command);
32-
#ifdef DEBUG
33-
printf("Calling PyRun_SimpleString() with:\n");
34-
printf("%s", command);
35-
printf("PyRun_SimpleString() returned: %d\n", ret);
36-
fflush(stdout);
37-
#endif
38-
free(command);
39-
return ret;
40-
}
41-
42-
/** This imports a Python module and calls a specific function in it.
43-
* It's arguments are similar to main():
44-
* argc - Number of strings in argv
45-
* argv - Expected to be 4 strings:
46-
* - Name of the executable.
47-
* - Path to the directory that the Python module is in.
48-
* - Name of the Python module.
49-
* - Name of the function in the module.
50-
*
51-
* The Python interpreter will be initialised and the path to the Python module
52-
* will be added to sys.paths then the module will be imported.
53-
* The function will be called with no arguments and its return value will be
54-
* ignored.
55-
*
56-
* This returns 0 on success, non-zero on failure.
57-
*/
58-
int import_call_execute(int argc, const char *argv[]) {
59-
int return_value = 0;
60-
PyObject *pModule = NULL;
61-
PyObject *pFunc = NULL;
62-
PyObject *pResult = NULL;
63-
64-
if (argc != 4) {
65-
fprintf(stderr,
66-
"Wrong arguments!"
67-
" Usage: %s package_path module function\n", argv[0]);
68-
return_value = -1;
69-
goto except;
70-
}
71-
Py_SetProgramName((wchar_t*)argv[0]);
72-
Py_Initialize();
73-
if (add_path_to_sys_module(argv[1])) {
74-
return_value = -2;
75-
goto except;
76-
}
77-
pModule = PyImport_ImportModule(argv[2]);
78-
if (! pModule) {
79-
fprintf(stderr,
80-
"%s: Failed to load module \"%s\"\n", argv[0], argv[2]);
81-
return_value = -3;
82-
goto except;
83-
}
84-
pFunc = PyObject_GetAttrString(pModule, argv[3]);
85-
if (! pFunc) {
86-
fprintf(stderr,
87-
"%s: Can not find function \"%s\"\n", argv[0], argv[3]);
88-
return_value = -4;
89-
goto except;
90-
}
91-
if (! PyCallable_Check(pFunc)) {
92-
fprintf(stderr,
93-
"%s: Function \"%s\" is not callable\n", argv[0], argv[3]);
94-
return_value = -5;
95-
goto except;
96-
}
97-
pResult = PyObject_CallObject(pFunc, NULL);
98-
if (! pResult) {
99-
fprintf(stderr, "%s: Function call failed\n", argv[0]);
100-
return_value = -6;
101-
goto except;
102-
}
103-
#ifdef DEBUG
104-
printf("%s: PyObject_CallObject() succeeded\n", argv[0]);
105-
#endif
106-
assert(! PyErr_Occurred());
107-
goto finally;
108-
except:
109-
assert(PyErr_Occurred());
110-
PyErr_Print();
111-
finally:
112-
Py_XDECREF(pFunc);
113-
Py_XDECREF(pModule);
114-
Py_XDECREF(pResult);
115-
Py_Finalize();
116-
return return_value;
117-
}
9+
#include "py_import_call_execute.h"
11810

11911
int main(int argc, const char *argv[]) {
12012
return import_call_execute(argc, argv);
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//
2+
// py_import_call_execute.c
3+
// PythonSubclassList
4+
//
5+
// Created by Paul Ross on 10/06/2016.
6+
// Copyright (c) 2016 Paul Ross. All rights reserved.
7+
//
8+
9+
#include "py_import_call_execute.h"
10+
11+
#include <Python.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
/** Takes a path and adds it to sys.paths by calling PyRun_SimpleString.
18+
* This does rather laborious C string concatenation so that it will work in
19+
* a primitive C environment.
20+
*
21+
* Returns 0 on success, non-zero on failure.
22+
*/
23+
int add_path_to_sys_module(const char *path) {
24+
int ret = 0;
25+
const char *prefix = "import sys\nsys.path.append(\"";
26+
const char *suffix = "\")\n";
27+
char *command = (char*)malloc(strlen(prefix)
28+
+ strlen(path)
29+
+ strlen(suffix)
30+
+ 1);
31+
if (! command) {
32+
return -1;
33+
}
34+
strcpy(command, prefix);
35+
strcat(command, path);
36+
strcat(command, suffix);
37+
ret = PyRun_SimpleString(command);
38+
#ifdef DEBUG
39+
printf("Calling PyRun_SimpleString() with:\n");
40+
printf("%s", command);
41+
printf("PyRun_SimpleString() returned: %d\n", ret);
42+
fflush(stdout);
43+
#endif
44+
free(command);
45+
return ret;
46+
}
47+
48+
/** This imports a Python module and calls a specific function in it.
49+
* It's arguments are similar to main():
50+
* argc - Number of strings in argv
51+
* argv - Expected to be 4 strings:
52+
* - Name of the executable.
53+
* - Path to the directory that the Python module is in.
54+
* - Name of the Python module.
55+
* - Name of the function in the module.
56+
*
57+
* The Python interpreter will be initialised and the path to the Python module
58+
* will be added to sys.paths then the module will be imported.
59+
* The function will be called with no arguments and its return value will be
60+
* ignored.
61+
*
62+
* This returns 0 on success, non-zero on failure.
63+
*/
64+
int import_call_execute(int argc, const char *argv[]) {
65+
int return_value = 0;
66+
PyObject *pModule = NULL;
67+
PyObject *pFunc = NULL;
68+
PyObject *pResult = NULL;
69+
70+
if (argc != 4) {
71+
fprintf(stderr,
72+
"Wrong arguments!"
73+
" Usage: %s package_path module function\n", argv[0]);
74+
return_value = -1;
75+
goto except;
76+
}
77+
Py_SetProgramName((wchar_t*)argv[0]);
78+
Py_Initialize();
79+
if (add_path_to_sys_module(argv[1])) {
80+
return_value = -2;
81+
goto except;
82+
}
83+
pModule = PyImport_ImportModule(argv[2]);
84+
if (! pModule) {
85+
fprintf(stderr,
86+
"%s: Failed to load module \"%s\"\n", argv[0], argv[2]);
87+
return_value = -3;
88+
goto except;
89+
}
90+
pFunc = PyObject_GetAttrString(pModule, argv[3]);
91+
if (! pFunc) {
92+
fprintf(stderr,
93+
"%s: Can not find function \"%s\"\n", argv[0], argv[3]);
94+
return_value = -4;
95+
goto except;
96+
}
97+
if (! PyCallable_Check(pFunc)) {
98+
fprintf(stderr,
99+
"%s: Function \"%s\" is not callable\n", argv[0], argv[3]);
100+
return_value = -5;
101+
goto except;
102+
}
103+
pResult = PyObject_CallObject(pFunc, NULL);
104+
if (! pResult) {
105+
fprintf(stderr, "%s: Function call failed\n", argv[0]);
106+
return_value = -6;
107+
goto except;
108+
}
109+
#ifdef DEBUG
110+
printf("%s: PyObject_CallObject() succeeded\n", argv[0]);
111+
#endif
112+
assert(! PyErr_Occurred());
113+
goto finally;
114+
except:
115+
assert(PyErr_Occurred());
116+
PyErr_Print();
117+
finally:
118+
Py_XDECREF(pFunc);
119+
Py_XDECREF(pModule);
120+
Py_XDECREF(pResult);
121+
Py_Finalize();
122+
return return_value;
123+
}
124+
125+
#ifdef __cplusplus
126+
// extern "C" {
127+
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// py_import_call_execute.h
3+
// PythonSubclassList
4+
//
5+
// Created by Paul Ross on 10/06/2016.
6+
// Copyright (c) 2016 Paul Ross. All rights reserved.
7+
//
8+
9+
#ifndef __PythonSubclassList__py_import_call_execute__
10+
#define __PythonSubclassList__py_import_call_execute__
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
/** This imports a Python module and calls a specific function in it.
17+
* It's arguments are similar to main():
18+
* argc - Number of strings in argv
19+
* argv - Expected to be 4 strings:
20+
* - Name of the executable.
21+
* - Path to the directory that the Python module is in.
22+
* - Name of the Python module.
23+
* - Name of the function in the module.
24+
*
25+
* The Python interpreter will be initialised and the path to the Python module
26+
* will be added to sys.paths then the module will be imported.
27+
* The function will be called with no arguments and its return value will be
28+
* ignored.
29+
*
30+
* This returns 0 on success, non-zero on failure.
31+
*/
32+
int import_call_execute(int argc, const char *argv[]);
33+
34+
#ifdef __cplusplus
35+
} // extern "C"
36+
#endif
37+
38+
#endif /* defined(__PythonSubclassList__py_import_call_execute__) */

0 commit comments

Comments
 (0)