Skip to content

Commit 27a1ae8

Browse files
committed
Make call_args more useful and avoid need to take the GIL twice when using it
1 parent 377a7b3 commit 27a1ae8

7 files changed

+31
-67
lines changed

Pythonwin/ddemodule.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,16 @@ class PythonDDETopicFramework : public T {
3131
virtual BOOL Exec(void *pData, DWORD dwSize)
3232
{
3333
CVirtualHelper helper("Exec", this);
34-
PyObject *args = helper.build_args("(N)", PyWinObject_FromTCHAR((TCHAR *)pData));
3534
BOOL rc = TRUE;
36-
if (helper.call_args(args))
35+
if (helper.call_args("(N)", PyWinObject_FromTCHAR((TCHAR *)pData)))
3736
helper.retval(rc);
3837
return !rc;
3938
}
4039
virtual BOOL NSRequest(const TCHAR *szItem, CDDEAllocator &allocr)
4140
{
4241
CVirtualHelper helper("Request", this);
43-
PyObject *args = helper.build_args("(N)", PyWinObject_FromTCHAR(szItem));
4442
BOOL rc = TRUE;
45-
if (helper.call_args(args)) {
43+
if (helper.call_args("(N)", PyWinObject_FromTCHAR(szItem))) {
4644
CString strret;
4745
if (helper.retval(strret)) {
4846
// seems strange we can't use DdeCreateStringHandle, but that is
@@ -56,9 +54,8 @@ class PythonDDETopicFramework : public T {
5654
virtual BOOL NSPoke(const TCHAR *szItem, void *pData, DWORD dwSize)
5755
{
5856
CVirtualHelper helper("Poke", this);
59-
PyObject *args = helper.build_args("(Nz#)", PyWinObject_FromTCHAR(szItem), pData, dwSize);
6057
BOOL rc = TRUE;
61-
if (helper.call_args(args)) {
58+
if (helper.call_args("(Nz#)", PyWinObject_FromTCHAR(szItem), pData, dwSize)) {
6259
return TRUE;
6360
}
6461
return !rc;

Pythonwin/pythonview.cpp

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,9 @@ void CPythonListViewImpl::DrawItem(LPDRAWITEMSTRUCT lpDIS)
9595
obDC = Py_None;
9696
}
9797

98-
PyObject *args = helper.build_args("iiiiiiO(iiii)O", lpDIS->CtlType, lpDIS->CtlID, lpDIS->itemID, lpDIS->itemAction,
99-
lpDIS->itemState, lpDIS->hwndItem, obDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
100-
lpDIS->rcItem.right, lpDIS->rcItem.bottom, obData);
101-
ASSERT(args);
102-
if (!args) {
103-
gui_print_error();
104-
PyErr_SetString(ui_module_error, "DrawItem could not convert args - handler not called.");
105-
return; // not too much we can do
106-
}
107-
// make the call.
108-
helper.call_args(args);
109-
// Cleanup.
110-
Py_DECREF(args);
98+
helper.call_args("iiiiiiO(iiii)O", lpDIS->CtlType, lpDIS->CtlID, lpDIS->itemID, lpDIS->itemAction,
99+
lpDIS->itemState, lpDIS->hwndItem, obDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
100+
lpDIS->rcItem.right, lpDIS->rcItem.bottom, obData);
111101
// The DC is no longer valid.
112102
Python_delete_assoc(pDC);
113103
}
@@ -141,19 +131,9 @@ void CPythonTreeViewImpl::DrawItem(LPDRAWITEMSTRUCT lpDIS)
141131
obDC = Py_None;
142132
}
143133

144-
PyObject *args = helper.build_args("iiiiiiO(iiii)O", lpDIS->CtlType, lpDIS->CtlID, lpDIS->itemID, lpDIS->itemAction,
145-
lpDIS->itemState, lpDIS->hwndItem, obDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
146-
lpDIS->rcItem.right, lpDIS->rcItem.bottom, obData);
147-
ASSERT(args);
148-
if (!args) {
149-
gui_print_error();
150-
PyErr_SetString(ui_module_error, "DrawItem could not convert args - handler not called.");
151-
return; // not too much we can do
152-
}
153-
// make the call.
154-
helper.call_args(args);
155-
// Cleanup.
156-
Py_DECREF(args);
134+
helper.call_args("iiiiiiO(iiii)O", lpDIS->CtlType, lpDIS->CtlID, lpDIS->itemID, lpDIS->itemAction,
135+
lpDIS->itemState, lpDIS->hwndItem, obDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
136+
lpDIS->rcItem.right, lpDIS->rcItem.bottom, obData);
157137
// The DC is no longer valid.
158138
Python_delete_assoc(pDC);
159139
}

Pythonwin/win32template.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,7 @@ void CPythonDocTemplate::InitialUpdateFrame(CFrameWnd *pFrame, CDocument *pDoc,
430430
// @pyparm <o PyCFrameWnd>|frame||The frame window.
431431
// @pyparm <o PyCDocument>|frame||The document attached to the frame.
432432
// @pyparm int|bMakeVisible||Indicates if the frame should be made visible.
433-
PyObject *arglst = helper.build_args("(OOi)", frame, doc, bMakeVisible);
434-
XDODECREF(frame);
435-
XDODECREF(doc);
436-
helper.call_args(arglst);
437-
return;
433+
helper.call_args("(NNi)", frame, doc, bMakeVisible);
438434
}
439435

440436
CFrameWnd *CPythonDocTemplate::CreateNewFrame(CDocument *pDoc, CFrameWnd *pOther)

Pythonwin/win32ui.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,6 @@ class PYW_EXPORT CVirtualHelper {
299299
CVirtualHelper(const char *iname, void *iassoc, EnumVirtualErrorHandling veh = VEH_PRINT_ERROR);
300300
~CVirtualHelper();
301301

302-
PyObject* build_args(const char* format, ...);
303302
BOOL HaveHandler() { return handler != NULL; }
304303
// All the "call" functions return FALSE if the call failed, or no handler exists.
305304
BOOL call();
@@ -332,7 +331,8 @@ class PYW_EXPORT CVirtualHelper {
332331
BOOL call(const MSG *);
333332
BOOL call(WPARAM, LPARAM);
334333
BOOL call(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo);
335-
BOOL call_args(PyObject *arglst);
334+
PyObject* build_args(const char* format, ...);
335+
BOOL call_args(const char* format, ...);
336336
// All the retval functions will ASSERT if the call failed!
337337
BOOL retval(int &ret);
338338
BOOL retval(long &ret);

Pythonwin/win32uiExt.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,12 @@ class CPythonWndFramework : public T {
286286
}
287287
else
288288
obPos = helper.build_args("iiiiiii", pwp->hwnd, pwp->hwndInsertAfter, pwp->x, pwp->y, pwp->cx, pwp->cy,
289-
pwp->flags);
290-
291-
PyObject *args = helper.build_args("i(OOOO)", bCalcValidRects, rc1, rc2, rc3, obPos);
292-
Py_XDECREF(rc1);
293-
Py_XDECREF(rc2);
294-
Py_XDECREF(rc3);
295-
Py_XDECREF(obPos);
296-
helper.call_args(args);
289+
pwp->flags);
290+
helper.call_args("i(NNNN)", bCalcValidRects, rc1, rc2, rc3, obPos);
297291
}
298292
else {
299293
PyObject *rc1 = PyWinObject_FromRECT((RECT *)lpncsp, false);
300-
PyObject *args = helper.build_args("i(Ozzz)", bCalcValidRects, rc1, NULL, NULL, NULL);
301-
Py_XDECREF(rc1);
302-
helper.call_args(args);
294+
helper.call_args("i(Nzzz)", bCalcValidRects, rc1, NULL, NULL, NULL);
303295
}
304296
}
305297
else
@@ -318,8 +310,7 @@ class CPythonWndFramework : public T {
318310
CVirtualHelper helper("OnNcHitTest", this);
319311
// @pyparm int, int|x,y||The point to test.
320312
if (helper.HaveHandler()) {
321-
PyObject *args = helper.build_args("((ii))", pt.x, pt.y);
322-
if (helper.call_args(args)) {
313+
if (helper.call_args("((ii))", pt.x, pt.y)) {
323314
int ret;
324315
if (helper.retval(ret))
325316
return ret;
@@ -367,11 +358,7 @@ class CPythonWndFramework : public T {
367358
obd = Py_None;
368359
Py_INCREF(Py_None);
369360
}
370-
PyObject *args = helper.build_args("(iOO)", bActivate, oba, obd);
371-
Py_XDECREF(oba);
372-
Py_XDECREF(obd);
373-
helper.call_args(args);
374-
// decref by helper.
361+
helper.call_args("(iNN)", bActivate, oba, obd);
375362
}
376363
}
377364
afx_msg int OnMouseActivate(CWnd *pDesktopWnd, UINT nHitTest, UINT message)

Pythonwin/win32uioleClientItem.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,9 @@ class PythonOleClientItem : public COleClientItem {
5454
// @pyparm (int, int, int, int)|(left, top, right, bottom)||The new position
5555
CVirtualHelper helper("OnChangeItemPosition", this);
5656
BOOL bRet;
57-
PyObject *args = helper.build_args("(iiii)", rectPos.left, rectPos.top, rectPos.right, rectPos.bottom);
58-
if (helper.HaveHandler() && helper.call_args(args)) {
59-
// Note = args decref'd by caller
57+
if (helper.call_args("(iiii)", rectPos.left, rectPos.top, rectPos.right, rectPos.bottom)) {
6058
helper.retval(bRet);
61-
}
62-
else
59+
} else
6360
bRet = COleClientItem::OnChangeItemPosition(rectPos);
6461
return bRet;
6562
}

Pythonwin/win32virt.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,21 @@ BOOL CVirtualHelper::do_call(PyObject *args)
136136
return TRUE;
137137
}
138138

139-
BOOL CVirtualHelper::call_args(PyObject *arglst)
139+
BOOL CVirtualHelper::call_args(const char* format, ...)
140140
{
141141
if (!handler)
142142
return FALSE;
143-
// NOTE no CEnterLeavePython here - the caller must do that (the entire
144-
// point of this function is to allow the consumer to build `arglst`, and
145-
// by definition that means calling into Python!
146-
return do_call(arglst);
143+
CEnterLeavePython _celp;
144+
// Duplicate build_args
145+
va_list va;
146+
PyObject* args;
147+
va_start(va, format);
148+
args = Py_VaBuildValue(format, va);
149+
va_end(va);
150+
if (!args) {
151+
return FALSE;
152+
}
153+
return do_call(args);
147154
}
148155

149156
BOOL CVirtualHelper::call()

0 commit comments

Comments
 (0)