[PyQt] Possible small bug in docstring generation
Shaheed Haque
srhaque at theiet.org
Thu Jun 15 19:58:12 BST 2017
Attached is a patch that converts this SIP:
===========
virtual void
openDialogIncidenceCreated(Akonadi::ITIPHandlerDialogDelegate::Recipient
recipient, const QString &question,
Akonadi::ITIPHandlerDialogDelegate::Action action =
Akonadi::ITIPHandlerDialogDelegate::ActionAsk, const KGuiItem
&buttonYes = KGuiItem(i18nc("@action:button dialog positive
answer","Send Email")), const KGuiItem &buttonNo =
KGuiItem(i18nc("@action:button dialog negative answer","Do Not
Send")));
============
into this C++ code:
============
PyDoc_STRVAR(doc_Akonadi_ITIPHandlerDialogDelegate_openDialogIncidenceCreated,
"openDialogIncidenceCreated(self,
Akonadi.ITIPHandlerDialogDelegate.Recipient, str,
Akonadi.ITIPHandlerDialogDelegate.Action =
Akonadi.ITIPHandlerDialogDelegate.ActionAsk, KGuiItem =
KGuiItem(i18nc(\"@action:button dialog positive answer\",\"Send
Email\")), KGuiItem = KGuiItem(i18nc(\"@action:button dialog negative
answer\",\"Do Not Send\")))");
.
.
.
{
::Akonadi::ITIPHandlerDialogDelegate::Recipient a0;
const ::QString* a1;
int a1State = 0;
::Akonadi::ITIPHandlerDialogDelegate::Action a2 =
Akonadi::ITIPHandlerDialogDelegate::ActionAsk;
const ::KGuiItem& a3def = KGuiItem(i18nc("@action:button
dialog positive answer","Send Email"));
const ::KGuiItem* a3 = &a3def;
const ::KGuiItem& a4def = KGuiItem(i18nc("@action:button
dialog negative answer","Do Not Send"));
============
As you can see, the PyDoc_STRVAR has the quotes escaped, but a3def and
a4def do not. Now, the patch as-is is slightly overkill in the sense
that it introduces a %q format code for prcode, which I expected would
be needed for cases like:
..., QString bar = "worst \"stri\\ng ever", ...
to generate:
..., QString bar = \"worst \\\"stri\\\\ng ever\", ...
However, it seems that SIP's lexer does not like the escapes. I did
not feel comfortable patching that here and now, so as I say, that
make the %q arguably overkill.
Please consider the patch, which is against sip-4.19.3.dev1706101519,
with or without the %q stuff.
Thanks, Shaheed
On 14 June 2017 at 19:34, Shaheed Haque <srhaque at theiet.org> wrote:
> Hi Phil,
>
> Is it possible this fell through the cracks? I don't see it in the
> changelog for the latest snapshot...or going back for a bit.
>
> If you like, I could try to create a patch (I was thinking a "q"
> format string specifier for prcode?).
>
>
>
> On 20 March 2017 at 21:45, Phil Thompson <phil at riverbankcomputing.com> wrote:
>> On 20 Mar 2017, at 7:50 pm, Shaheed Haque <srhaque at theiet.org> wrote:
>>>
>>> Hi Phil,
>>>
>>> With sip 4.18.1, I noticed this function:
>>>
>>> KMIME_EXPORT bool parseGenericQuotedString(const char *&scursor,
>>> const char *const send,
>>> QString &result, bool isCRLF,
>>> const char openChar = '"',
>>> const char closeChar = '"');
>>>
>>> ends up generating a docstring as follows, which of course is missing
>>> any escaping of the quotes...
>>>
>>> PyDoc_STRVAR(doc_KMime_HeaderParsing_parseGenericQuotedString,
>>> "parseGenericQuotedString(str, str, str, bool, str = '"', str = '"')
>>> -> bool");
>>>
>>>
>>> I'm not sure if this is fixed in a more recent release, but I thought
>>> it worth mentioning...
>>
>> I doubt it has been fixed. I'll add it to the TODO list for the next release.
>>
>> Thanks,
>> Phil
-------------- next part --------------
--- gencode.c.orig 2017-06-12 03:30:05.000000000 +0200
+++ gencode.c 2017-06-15 20:41:26.255649661 +0200
@@ -148,7 +148,7 @@
FILE *);
static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod,
classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp);
-static void generateSimpleFunctionCall(fcallDef *, FILE *);
+static void generateSimpleFunctionCall(fcallDef *, FILE *, int);
static int generateResultVar(ifaceFileDef *scope, overDef *od, argDef *res,
const char *indent, FILE *fp);
static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope,
@@ -474,9 +474,10 @@
case string_value:
{
- const char *quote = (in_str ? "\\\"" : "\"");
+ const char *quote = (in_str ? "\\\"" : "\"" );
+ const char *fmt = (in_str ? "%s%q%s" : "%s%q%s");
- prcode(fp,"%s%s%s", quote, vd->u.vstr, quote);
+ prcode(fp, fmt, quote, vd->u.vstr, quote);
}
break;
@@ -498,7 +499,7 @@
break;
case fcall_value:
- generateSimpleFunctionCall(vd->u.fcd,fp);
+ generateSimpleFunctionCall(vd->u.fcd,fp,in_str);
break;
}
@@ -9728,7 +9729,7 @@
/*
* Generate a simple function call.
*/
-static void generateSimpleFunctionCall(fcallDef *fcd,FILE *fp)
+static void generateSimpleFunctionCall(fcallDef *fcd,FILE *fp,int in_str)
{
int i;
@@ -9739,7 +9740,7 @@
if (i > 0)
prcode(fp,",");
- generateExpression(fcd->args[i], FALSE, fp);
+ generateExpression(fcd->args[i], in_str, fp);
}
prcode(fp,")");
@@ -14256,6 +14257,28 @@
break;
}
+
+ case 'q':
+ {
+ /*
+ * 'q' is the same as 's' except that the '"' is escaped with a '\'.
+ * And that then suggests that a '\' must also be escaped.
+ */
+ const char *cp = va_arg(ap,const char *);
+
+ while (*cp != '\0')
+ {
+ if (*cp == '\n')
+ ++currentLineNr;
+ else if ((*cp == '"') || (*cp == '\\'))
+ fputc('\\',fp);
+
+ fputc(*cp,fp);
+ ++cp;
+ }
+
+ break;
+ }
case 's':
{
More information about the PyQt
mailing list