[Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args() (original) (raw)
Nikolaus Rath Nikolaus at rath.org
Tue Jan 21 03:35:40 CET 2014
- Previous message: [Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()
- Next message: [Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Ryan Smith-Roberts <rmsr at lab.net> writes:
The trick you're missing is that any time you have an optional argument with a custom converter[1], PyArgParseTuple only calls the converter function in the case that the user actually supplies some value. This is a basic property of an optional argument. Another property is that the cdefault is evaluated every time, as it is set before the call to PyArgParseTuple. Are these the best ways to do things? Maybe not, but it's how they are.
Please do not use a custom converter for this case. It can't work.
Well, I thought I was following Larry's recommendation:
A better choice would be to write a converter function in C, then use a custom converter that called it. Nikolaus: Is that something you're comfortable doing?
..and I assumed he'd know best. Did I misunderstand that quote?
Please do what I outlined earlier (untested, somewhat verbose code follows):
static int parsetimetarg(PyObject *arg, timet *when) { if (arg == NULL || arg == PyNone) { *when = time(NULL); return 1; } if (PyTimeObjectToTimet(arg, when) == -1) return 0; return 1; }
Ahm, this is exactly the code that I wrote (and you even quoted it below), only with the identifiers renamed.
/*[clinic input] time.gmtime seconds: object = None [clinic start generated code]*/ { timet when; if (0 == parsetimetarg(seconds, &when)) return NULL;
That's fine with me too. I'd just like Larry to sign off on it, because as far as I know, he'll be the one to review my patch.
Best, -Nikolaus
[1] If you set a default value, or put it in brackets as Serhiy later recommends, it works the same.
On Sun, Jan 19, 2014 at 8:19 PM, Nikolaus Rath <Nikolaus at rath.org> wrote: Larry Hastings <larry at hastings.org> writes: > On 01/18/2014 09:52 PM, Ryan Smith-Roberts wrote: >> >> I still advise you not to use this solution. time() is a system call >> on many operating systems, and so it can be a heavier operation than >> you'd think. Best to avoid it unless it's needed (on FreeBSD it >> seems to add about 15% overhead to localtime(), for instance). >> > > I agree. Converting to Argument Clinic should not cause a performance > regression. Please don't add new calls to time() for the sake of > making code more generic. > > A better choice would be to write a converter function in C, then use > a custom converter that called it. Nikolaus: Is that something you're > comfortable doing?
I think I'll need some help. I don't know how to handle the case where the user is not passing anything. Here's my attempt: ,---- | /* C Converter for argument clinic | If obj is NULL or PyNone, return current time. Otherwise, | convert Python object to timet. | */ | static int | PyObjecttotimet(PyObject *obj, timet *stamp) | { | if (obj == NULL || obj == PyNone) { | *stamp = time(NULL); | } | else { | if (PyTimeObjectToTimet(obj, stamp) == -1) | return 0; | } | return 1; | } | | /*[python input] | class timetconverter(CConverter): | type = 'timet' | converter = 'PyObjecttotimet' | default = None | [python start generated code]*/ | /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ | | | /*[clinic input] | time.gmtime | | seconds: timet | / | | [clinic start generated code]*/
----_ _but this results in the following code:_ _,----_ _| static PyObject *_ _| timegmtime(PyModuleDef *module, PyObject *args)_ _| {_ _| PyObject *returnvalue = NULL;_ _| timet seconds;_ _|_ _| if (!PyArgParseTuple(args,_ _| "|O&:gmtime",_ _| PyObjecttotimet, &seconds))_ _| goto exit;_ _| returnvalue = timegmtimeimpl(module, seconds);_ _|_ _| exit:_ _| return returnvalue;_ _| }_ _
---- This works if the user calls time.gmtime(None), but it fails for time.gmtime(). It seems that in that case my C converter function is never called. What's the trick that I'm missing?Thanks! -Nikolaus -- Encrypted emails preferred. PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C »Time flies like an arrow, fruit flies like a Banana.«
Python-Dev mailing list Python-Dev at python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/rmsr%40lab.net
-- Encrypted emails preferred. PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
»Time flies like an arrow, fruit flies like a Banana.«
- Previous message: [Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()
- Next message: [Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]