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

2014-01-21 Thread Serhiy Storchaka

22.01.14 07:13, Nikolaus Rath написав(ла):

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?


To me too.


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-21 Thread Nikolaus Rath
Larry Hastings  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.«
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-21 Thread Larry Hastings
Yes, I meant in the definition of the convertor class.  You can fix c_default 
in converter_init.

On Jan 21, 2014 7:19 PM, Nikolaus Rath  wrote:
>
> Larry Hastings  writes:
> > A comment on your approach so far: I'm very much against giving
> > "default" a default value in the constructor.
>
> You mean in the definition of the custom converter class?
>
> > I realize that hack saves you having to say "= NULL" in a lot of
> > places.  But explicit is better than implicit, and we're going to read
> > these signatures a lot more often than we write them, and I want
> > Clinic signatures to be easy to read at first glance.
> []
> > 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}
> >
> [...]
> >
> >    /*[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.
>
> That doesn't work. If the default value is declared for the function
> rather than in the converter definition, it overwrites the C default:
>
> /*[clinic input]
> time.gmtime
>
>     seconds: clinic_time_t=None
>     /
> */
>
> gives:
>
> static PyObject *
> time_gmtime(PyModuleDef *module, PyObject *args)
> {
>     PyObject *return_value = NULL;
>     clinic_time_t seconds = Py_None;
>
>     if (!PyArg_ParseTuple(args,
>     "|O&:gmtime",
>     parse_clinic_time_t, &seconds))
>     goto exit;
>     return_value = time_gmtime_impl(module, seconds);
>
> so the default for seconds is now Py_None instead of
> DEFAULT_CLINIC_TIME_T'.
>
> 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@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: 
> https://mail.python.org/mailman/options/python-dev/larry%40hastings.org
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-21 Thread Nikolaus Rath
Larry Hastings  writes:
> A comment on your approach so far: I'm very much against giving
> "default" a default value in the constructor.

You mean in the definition of the custom converter class?

> I realize that hack saves you having to say "= NULL" in a lot of
> places.  But explicit is better than implicit, and we're going to read
> these signatures a lot more often than we write them, and I want
> Clinic signatures to be easy to read at first glance.
[]
> 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}
>
[...]
>
>/*[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.

That doesn't work. If the default value is declared for the function
rather than in the converter definition, it overwrites the C default:

/*[clinic input]
time.gmtime

seconds: clinic_time_t=None
/
*/

gives:

static PyObject *
time_gmtime(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
clinic_time_t seconds = Py_None;

if (!PyArg_ParseTuple(args,
"|O&:gmtime",
parse_clinic_time_t, &seconds))
goto exit;
return_value = time_gmtime_impl(module, seconds);

so the default for seconds is now Py_None instead of
DEFAULT_CLINIC_TIME_T'.


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@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-21 Thread Larry Hastings

On 01/21/2014 12:59 AM, Serhiy Storchaka wrote:

21.01.14 04:44, Nikolaus Rath написав(ла):

Serhiy Storchaka  writes:

20.01.14 06:19, Nikolaus Rath написав(ла):

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?


/*[clinic input]
time.gmtime

 [
 seconds: time_t
 ]
 /



Ahh, interesting. So this works, but now the C default is evaluated even
if the user passed an argument (so that answers my question about
decreased performance in the other subthread). The generated code is:


Don't use time(NULL) as C default. Instead check group_right_1 and 
call time(NULL) explicitly.


While this "trick" works, it abuses optional groups.  Optional groups 
are intended as a last resort, for semantics that can't be expressed any 
other way.  The semantics of time.gmtime() are very easily expressed 
using normal Python syntax.  Please don't use optional groups here.



//arry/
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-21 Thread Serhiy Storchaka

21.01.14 04:44, Nikolaus Rath написав(ла):

Serhiy Storchaka  writes:

20.01.14 06:19, Nikolaus Rath написав(ла):

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?


/*[clinic input]
time.gmtime

 [
 seconds: time_t
 ]
 /



Ahh, interesting. So this works, but now the C default is evaluated even
if the user passed an argument (so that answers my question about
decreased performance in the other subthread). The generated code is:


Don't use time(NULL) as C default. Instead check group_right_1 and call 
time(NULL) explicitly.


time_gmtime_impl(PyModuleDef *module, int group_right_1, time_t seconds)
{
if (!group_right_1)
seconds = time(NULL);
...
}


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-20 Thread Larry Hastings

On 01/20/2014 06:44 PM, Nikolaus Rath wrote:

All in all, I'm still not sure how I'm supposed to proceed. I see the
following options (and I'm fine with all of them):

1. Use the option group with a custom converter. This means a time(NULL)
call even if the caller passed a parameter.

2. Declare the _impl parameter as PyObject* instead of time_t, and
explicitly call a C conversion function.

3. Patch clinic.py to only evaluate the C default if the caller does not

pass a parameter. This seemest cleanest, but I don't know if the
design of clinic.py actually allows that.


clinic.py is not flexible enough to allow initialization code after the 
call to the converter.


A comment on your approach so far: I'm very much against giving 
"default" a default value in the constructor.  I realize that hack saves 
you having to say "= NULL" in a lot of places.  But explicit is better 
than implicit, and we're going to read these signatures a lot more often 
than we write them, and I want Clinic signatures to be easy to read at 
first glance.


Anyway, you're right, the converter function is not called if a value is 
not passed in to convert it.  I think this is more complicated than you 
suspect, because PyArg_ParseWhatnot doesn't tell you whether or not it 
processed a parameter.  You have to detect it yourself, generally 
through a clever choice of a default value in C.  But there are no 
illegal values of time_t.


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.  Also, the converter probably isn't 
quite right, you'll have to play with "impl_by_reference" and 
"parse_by_reference" and add and remove asterisks and ampersands to make 
sure the code is 100% correct.  Examine the implementation of path_t in 
Modules/posixmodule.c, as that does about the same thing.


And of course clinic_time_t is a poor name, perhaps you can come up with 
a better one.


That should work,


//arry/
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-20 Thread Nikolaus Rath
Serhiy Storchaka  writes:
> 20.01.14 06:19, Nikolaus Rath написав(ла):
>> 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?
>
> /*[clinic input]
> time.gmtime
>
> [
> seconds: time_t
> ]
> /
>

Ahh, interesting. So this works, but now the C default is evaluated even
if the user passed an argument (so that answers my question about
decreased performance in the other subthread). The generated code is:

time_gmtime(PyModuleDef *module, PyObject *args)
{
PyObject *return_value = NULL;
int group_right_1 = 0;
time_t seconds = time(NULL);

switch (PyTuple_GET_SIZE(args)) {
case 0:
break;
case 1:
if (!PyArg_ParseTuple(args, "O&:gmtime", PyObject_to_time_t, 
&seconds))
return NULL;
group_right_1 = 1;
break;
default:
PyErr_SetString(PyExc_TypeError, "time.gmtime requires 0 to 1 
arguments");
return NULL;
}
return_value = time_gmtime_impl(module, group_right_1, seconds);


All in all, I'm still not sure how I'm supposed to proceed. I see the
following options (and I'm fine with all of them):

1. Use the option group with a custom converter. This means a time(NULL)
   call even if the caller passed a parameter.

2. Declare the _impl parameter as PyObject* instead of time_t, and
   explicitly call a C conversion function.
   
3. Patch clinic.py to only evaluate the C default if the caller does not
   pass a parameter. This seemest cleanest, but I don't know if the
   design of clinic.py actually allows that.


   
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@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-20 Thread Nikolaus Rath
Ryan Smith-Roberts  writes:
> The trick you're missing is that *any time* you have an optional argument
> with a custom converter[1], PyArg_ParseTuple *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
> c_default is evaluated *every time*, as it is set *before* the call to
> PyArg_ParseTuple. 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
> parse_time_t_arg(PyObject *arg, time_t *when)
> {
> if (arg == NULL || arg == Py_None) {
> *when = time(NULL);
> return 1;
> }
> if (_PyTime_ObjectToTime_t(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]*/
> {
> time_t when;
>
> if (0 == parse_time_t_arg(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  wrote:
>
>> Larry Hastings  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 Py_None, return current time. Otherwise,
>> |convert Python object to time_t.
>> | */
>> | static int
>> | PyObject_to_time_t(PyObject *obj, time_t *stamp)
>> | {
>> | if (obj == NULL || obj == Py_None) {
>> | *stamp = time(NULL);
>> | }
>> | else {
>> | if (_PyTime_ObjectToTime_t(obj, stamp) == -1)
>> | return 0;
>> | }
>> | return 1;
>> | }
>> |
>> | /*[python input]
>> | class time_t_converter(CConverter):
>> | type = 'time_t'
>> | converter = 'PyObject_to_time_t'
>> | default = None
>> | [python start generated code]*/
>> | /*[python end generated code:
>> checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
>> |
>> |
>> | /*[clinic input]
>> | time.gmtime
>> |
>> | seconds: time_t
>> | /
>> |
>> | [clinic start generated code]*/
>> `
>>
>> but this results in the following code:
>>
>> ,
>> | static PyObject *
>> | time_gmtime(PyModuleDef *module, PyObject *args)
>> | {
>> | PyObject *return_value = NULL;
>> | time_t seconds;
>> |
>> | if (!PyArg_ParseTuple(args,
>> | "|O&:gmtime",
>> | PyObject_to_time_t, &seconds))
>> | goto exit;
>> | return_value = time_gmtime_impl(module, seconds);
>> |
>> | exit:
>> | return return_value;
>> | }
>> `
>>
>> 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@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.«
___
Python-Dev mailing list
Python-Dev@pytho

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

2014-01-20 Thread Ryan Smith-Roberts
The trick you're missing is that *any time* you have an optional argument
with a custom converter[1], PyArg_ParseTuple *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
c_default is evaluated *every time*, as it is set *before* the call to
PyArg_ParseTuple. 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. Please
do what I outlined earlier (untested, somewhat verbose code follows):

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

/*[clinic input]
time.gmtime
seconds: object = None
[clinic start generated code]*/
{
time_t when;

if (0 == parse_time_t_arg(seconds, &when))
return NULL;
...


[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  wrote:

> Larry Hastings  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 Py_None, return current time. Otherwise,
> |convert Python object to time_t.
> | */
> | static int
> | PyObject_to_time_t(PyObject *obj, time_t *stamp)
> | {
> | if (obj == NULL || obj == Py_None) {
> | *stamp = time(NULL);
> | }
> | else {
> | if (_PyTime_ObjectToTime_t(obj, stamp) == -1)
> | return 0;
> | }
> | return 1;
> | }
> |
> | /*[python input]
> | class time_t_converter(CConverter):
> | type = 'time_t'
> | converter = 'PyObject_to_time_t'
> | default = None
> | [python start generated code]*/
> | /*[python end generated code:
> checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
> |
> |
> | /*[clinic input]
> | time.gmtime
> |
> | seconds: time_t
> | /
> |
> | [clinic start generated code]*/
> `
>
> but this results in the following code:
>
> ,
> | static PyObject *
> | time_gmtime(PyModuleDef *module, PyObject *args)
> | {
> | PyObject *return_value = NULL;
> | time_t seconds;
> |
> | if (!PyArg_ParseTuple(args,
> | "|O&:gmtime",
> | PyObject_to_time_t, &seconds))
> | goto exit;
> | return_value = time_gmtime_impl(module, seconds);
> |
> | exit:
> | return return_value;
> | }
> `
>
> 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@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/rmsr%40lab.net
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-20 Thread Serhiy Storchaka

20.01.14 06:19, Nikolaus Rath написав(ла):

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?


/*[clinic input]
time.gmtime

[
seconds: time_t
]
/

[clinic start generated code]*/


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-19 Thread Nikolaus Rath
Larry Hastings  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 Py_None, return current time. Otherwise,
|convert Python object to time_t.
| */
| static int
| PyObject_to_time_t(PyObject *obj, time_t *stamp)
| {
| if (obj == NULL || obj == Py_None) {
| *stamp = time(NULL);
| }
| else {
| if (_PyTime_ObjectToTime_t(obj, stamp) == -1)
| return 0;
| }
| return 1;
| } 
| 
| /*[python input]
| class time_t_converter(CConverter):
| type = 'time_t'
| converter = 'PyObject_to_time_t'
| default = None
| [python start generated code]*/
| /*[python end generated code: 
checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
| 
| 
| /*[clinic input]
| time.gmtime
| 
| seconds: time_t
| /
| 
| [clinic start generated code]*/
`

but this results in the following code:

,
| static PyObject *
| time_gmtime(PyModuleDef *module, PyObject *args)
| {
| PyObject *return_value = NULL;
| time_t seconds;
| 
| if (!PyArg_ParseTuple(args,
| "|O&:gmtime",
| PyObject_to_time_t, &seconds))
| goto exit;
| return_value = time_gmtime_impl(module, seconds);
| 
| exit:
| return return_value;
| }
`

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@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-19 Thread Nikolaus Rath
Larry Hastings  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.

I don't see how the conversion would result in more calls to time() than
we have now. It seems to me that the expression for the C default should
be only evaluated if the caller did not specify a value. Is that not how
ac works?

> 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?

As long as you're comfortable looking over the (probably buggy) patch,
yes, I'm happy to give it a shot.

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@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-19 Thread Ryan Smith-Roberts
On Sun, Jan 19, 2014 at 2:38 AM, Larry Hastings  wrote:

>  According to the issue tracker, " rmsr" has only ever filed one issue.
> I just fixed (and closed) it.
>

The two issues were "custom converter with converter and default raises
exception" and "custom converter with py_default and c_default being
overridden by __init__".

As for the former, you said "I hope you know what you're doing!" which made
me step back and think more about the "why". I realized two things:

The default-related class attributes might be an 'attractive nuisance', in
that setting them there technically saves repetition, but could easily
confuse a later reader who expects to find the defaults declared inline as
usual.

As well, it is unclear which of 'default', 'py_default', 'c_default' one
needs to set, or which has priority. Nikolaus went ahead and set all three,
thus my bug reports. After tinkering some more with the test file for the
first bug, I noticed that a class with 'default' and 'converter' generates
a default in the signature line but not at the C level.

I'm wondering now if class-level default support shouldn't just be removed,
as the aforementioned attractive nuisance.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-19 Thread Larry Hastings


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?



As for why you're getting that exception, it definitely looks like a 
bug in Argument Clinic. I spotted another bug that would have bitten 
you while I was looking for this one, so I've opened bugs on both 
issues, and put you on the nosy list for them.




According to the issue tracker, " rmsr" has only ever filed one issue.  
I just fixed (and closed) it.



//arry/
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-18 Thread Ryan Smith-Roberts
Ah yes, my apologies, I was thrown off by the first converter declaration
in your class and didn't spot the second, so didn't realize what you were
up to.

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

As for why you're getting that exception, it definitely looks like a bug in
Argument Clinic. I spotted another bug that would have bitten you while I
was looking for this one, so I've opened bugs on both issues, and put you
on the nosy list for them.


On Sat, Jan 18, 2014 at 7:42 PM, Nikolaus Rath  wrote:

> Hi Ryan,
>
>
> Ryan Smith-Roberts  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 
> 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 Modul

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

2014-01-18 Thread Nikolaus Rath
Hi Ryan,


Ryan Smith-Roberts  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  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@python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe:
>

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

2014-01-18 Thread Ryan Smith-Roberts
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.

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  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@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/rmsr%40lab.net
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


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

2014-01-18 Thread Nikolaus Rath
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@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com