[Python-Dev] Using argument clinic to replace timemodule.c:parse_time_t_args()

Nikolaus Rath Nikolaus at rath.org
Wed Jan 22 06:13:22 CET 2014


Larry Hastings <larry at hastings.org> writes:
> All is not lost!  What follows is rough pseudo-C code, hopefully you
> can take it from here.
>
>    typedef struct {
>       int set;
>       time_t when;
>    } clinic_time_t;
>
>    #define DEFAULT_CLINIC_TIME_T {0, 0}
>
>    static int
>    parse_clinic_time_t_arg(PyObject *arg, clinic_time_t *ct)
>    {
>         if (arg == NULL)
>             return 1;
>         if (arg == Py_None)
>             return 0;
>         if (_PyTime_ObjectToTime_t(arg, &ct->when) == -1) {
>             set = 1;
>             return 0;
>         }
>         return 1;
>    }
>
>    static int post_parse_clinic_time_t(clinic_time_t *ct) {
>         if (ct->set)
>             return 0;
>         ct->when = time(NULL);
>         return 0;
>    }
>
>    /*[python input]
>    class clinic_time_t_converter(CConverter):
>         type = 'clinic_time_t'
>         converter = 'parse_clinic_time_t'
>         c_default = 'DEFAULT_CLINIC_TIME_T'
>    [python start generated code]*/
>    /*[python end generated code: checksum=...]*/
>
> Now you can use clinic_time_t.  Parameters declared clinic_time_t can
> be required, or they can be optional; if they're optional give them a
> default value of None.  You'll have to call post_parse_clinic_time_t()
> by hand in your impl function; I'll see if I can extend Clinic so
> converters can emit code after a successful call to the parse function
> but before the call to the impl.


Okay, I attached a patch along these lines to the bugtracker.


However, I have to say that I lost track of what we're actually gaining
with all this. If all we need is a type that can distinguish between a
valid time_t value and a default value, why don't we simply use
PyObject?

In other words, what's the advantage of all the code above over:

static int
PyObject_to_time_t(PyObject *obj, time_t *when)
{
     if (obj == NULL || obj == Py_None) 
         *when = time(NULL);
     else if (_PyTime_ObjectToTime_t(obj, when) == -1)
         return 0;
     return 1;
}


/*[clinic input]
time.gmtime

    seconds: object=NULL
    /
[...]

static PyObject *
time_gmtime_impl(PyModuleDef *module, PyObject *seconds)
{
    PyObject *return_value = NULL;
    time_t when;
    if(!PyObj_to_time_t(seconds, &when))
       return NULL;

[...]


To me this version looks shorter and clearer. Is there really an
advantage in defining the clinic argument as a custom struct rather than
object?

    
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.«


More information about the Python-Dev mailing list