[Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()
Nikolaus Rath
Nikolaus at rath.org
Sun Jan 19 04:42:35 CET 2014
Hi Ryan,
Ryan Smith-Roberts <rmsr at lab.net> writes:
> Hi Nikolaus. I also started a conversion of timemodule, but dropped it when
> I saw in the issue that you had taken over that conversion. I also tried to
> turn parse_time_t_args into a converter. However, it won't work. The
> problem is that parse_time_t_args must be called whether or not the user
> supplies an argument to the function, but an Argument Clinic converter only
> gets called if the user actually supplies something, and not on the default
> value.
I don't quite follow. My approach was to drop parse_time_t_args()
completely and use _PyTime_ObjectToTime_t() as the conversion function
(which only needs to be called if the user supplied something).
In other words, I would have expected
>> ,----
>> | /*[python input]
>> | class time_t_converter(CConverter):
>> | type = 'time_t'
>> | converter = 'time_t_converter'
>> | default = None
>> | py_default = 'None'
>> | c_default = 'time(NULL)'
>> | converter = '_PyTime_ObjectToTime_t'
>> | [python start generated code]*/
>> |
>> | /*[clinic input]
>> | time.localtime
>> |
>> | seconds: time_t
>> | /
>> |
>> | bla.
>> | [clinic start generated code]*/
>> `----
to produce something like this:
static PyObject *
time_localtime(PyObject *self, PyObject *args)
{
PyObject *obj = NULL;
time_t seconds;
struct tm buf;
if (!PyArg_ParseTuple(args, "|O:localtime", &obj))
return NULL;
if (obj == NULL || obj == Py_None)
seconds = time(NULL);
else {
if (_PyTime_ObjectToTime_t(obj, &seconds) == -1)
return NULL;
}
return time_localtime_impl(self, seconds);
}
Apart from getting an error from clinic.py, it seems to me that this
should in principle be possible.
Best,
Nikolaus
>
> So, the best idea is to
>
> * Remove the PyArgs_ParseTuple code from parse_time_t_args
> * Declare seconds as a plain object in Argument Clinic
> * Call the modified parse_time_t_args on seconds first thing in the _impl
> functions
>
>
> On Sat, Jan 18, 2014 at 4:56 PM, Nikolaus Rath <Nikolaus at rath.org> wrote:
>
>> Hello,
>>
>> I'm trying to convert functions using parse_time_t_args() (from
>> timemodule.c) for argument parsing to argument clinic.
>>
>> The function is defined as:
>>
>> ,----
>> | static int
>> | parse_time_t_args(PyObject *args, char *format, time_t *pwhen)
>> | {
>> | PyObject *ot = NULL;
>> | time_t whent;
>> |
>> | if (!PyArg_ParseTuple(args, format, &ot))
>> | return 0;
>> | if (ot == NULL || ot == Py_None) {
>> | whent = time(NULL);
>> | }
>> | else {
>> | if (_PyTime_ObjectToTime_t(ot, &whent) == -1)
>> | return 0;
>> | }
>> | *pwhen = whent;
>> | return 1;
>> | }
>> `----
>>
>> and used like this:
>>
>> ,----
>> | static PyObject *
>> | time_localtime(PyObject *self, PyObject *args)
>> | {
>> | time_t when;
>> | struct tm buf;
>> |
>> | if (!parse_time_t_args(args, "|O:localtime", &when))
>> | return NULL;
>> | if (pylocaltime(&when, &buf) == -1)
>> | return NULL;
>> | return tmtotuple(&buf);
>> | }
>> `----
>>
>> In other words, if any Python object is passed to it, it calls
>> _PyTime_ObjectToTime_t on it to convert it to time_t, and otherwise uses
>> time(NULL) as the default value.
>>
>> May first attempt to implement something similar in argument clinic was:
>>
>> ,----
>> | /*[python input]
>> | class time_t_converter(CConverter):
>> | type = 'time_t'
>> | converter = 'time_t_converter'
>> | default = None
>> | py_default = 'None'
>> | c_default = 'time(NULL)'
>> | converter = '_PyTime_ObjectToTime_t'
>> | [python start generated code]*/
>> |
>> | /*[clinic input]
>> | time.localtime
>> |
>> | seconds: time_t
>> | /
>> |
>> | bla.
>> | [clinic start generated code]*/
>> `----
>>
>> However, running clinic.py on this file gives:
>>
>> ,----
>> | $ Tools/clinic/clinic.py Modules/timemodule.c
>> | Error in file "Modules/timemodule.c" on line 529:
>> | Exception raised during parsing:
>> | Traceback (most recent call last):
>> | File "Tools/clinic/clinic.py", line 1445, in parse
>> | parser.parse(block)
>> | File "Tools/clinic/clinic.py", line 2738, in parse
>> | self.state(None)
>> | File "Tools/clinic/clinic.py", line 3468, in state_terminal
>> | self.function.docstring = self.format_docstring()
>> | File "Tools/clinic/clinic.py", line 3344, in format_docstring
>> | s += "".join(a)
>> | TypeError: sequence item 2: expected str instance, NoneType found
>> `----
>>
>> What am I doing wrong?
>>
>>
>> Best,
>> 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.«
More information about the Python-Dev
mailing list