[Python-Dev] PEP 362 Third Revision
Alexandre Zani
alexandre.zani at gmail.com
Thu Jun 14 16:50:42 CEST 2012
On Thu, Jun 14, 2012 at 6:50 AM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> On 2012-06-14, at 8:06 AM, Victor Stinner wrote:
>> Sorry if I'm asking dummy questions, I didn't follow the discussion.
>>
>>> * format(...) -> str
>>> Formats the Signature object to a string. Optional arguments allow
>>> for custom render functions for parameter names,
>>> annotations and default values, along with custom separators.
>>
>> Hum, what are these "custom render functions"? Can you give an example?
>
> That's how the function looks right now (I'm not sure we should load
> the PEP with this):
>
> def format(self, *, format_name=str,
> format_default=repr,
> format_annotation=formatannotation,
> format_args=(lambda param: '*' + str(param)),
> format_kwargs=(lambda param: '**' + str(param)),
>
> token_params_separator=', ',
> token_kwonly_separator='*',
> token_left_paren='(',
> token_right_paren=')',
> token_colon=':',
> token_eq='=',
> token_return_annotation=' -> '):
>
> '''Format signature to a string.
>
> Arguments (all optional):
>
> * format_name : A function to format names of parameters. Parameter
> won't be rendered if ``None`` is returned.
> * format_default : A function to format default values of parameters.
> Default value won't be rendered if ``None`` is returned.
> * format_annotation : A function to format parameter annotations.
> Annotation won't be rendered if ``None`` is returned.
> * format_args : A function to render ``*args`` like parameters.
> Parameter won't be rendered if ``None`` is returned.
> * format_kwargs : A function to render ``**kwargs`` like parameters.
> Parameter won't be rendered if ``None`` is returned.
> * token_params_separator : A separator for parameters. Set to
> ', ' by default.
> * token_kwonly_separator : A separator for arguments and
> keyword-only arguments. Defaults to '*'.
> * token_left_paren : Left signature parenthesis, defaults to '('.
> * token_right_paren : Left signature parenthesis, defaults to ')'.
> * token_colon : Separates parameter from its annotation,
> defaults to ':'.
> * token_eq : Separates parameter from its default value, set to
> '=' by default.
> * token_return_annotation : Function return annotation, defaults
> to ' -> '.
> '''
>
> I've designed it in such a way, that everything is configurable, so you
> can render functions to color-term, HTML, or whatever else.
>
>>> * is_keyword_only : bool
>>> True if the parameter is keyword-only, else False.
>>> * is_args : bool
>>> True if the parameter accepts variable number of arguments
>>> (``*args``-like), else False.
>>> * is_kwargs : bool
>>> True if the parameter accepts variable number of keyword
>>> arguments (``**kwargs``-like), else False.
>>
>> Hum, why not using a attribute with a string value instead of 3
>> attribute? For example:
>> * argtype: "index", "varargs", "keyword" or "keyword_only"
>>
>> It would avoid a possible inconsitency (ex: is_args=True and
>> is_kwargs=True). And it would help to implement something like a C
>> switch/case using a dict: argtype => function for functions using
>> signatures.
>
> Originally, I thought the the line:
>
> if parameters.is_args
>
> is better looking that:
>
> if parameters.kind == 'vararg'
>
> But, I like your arguments regarding inconsistency and dispatch
> through a dict (someone may find it useful). Also, Larry gave
> another one - who knows if we add another type of arguments in
> the future.
>
> I guess if nobody really wants to keep 'is_args', we can alter the
> PEP.
>
> Let's consider replacement of 'Parameter.is_*' set of attributes with
> a single 'Parameter.kind' attribute, which will have the following
> possible values: 'positional', 'vararg', 'keyword-only', 'varkwarg'.
>
> (I think 'positional' is more intuitive than 'index'?)
>
I disagree largely for readability reasons. As the PEP stands, I can
look at a Parameter object and immediately understand what the
different possible values are by just listing its attributes. The kind
attribute makes that harder.
Comparing with strings is error prone. If I do param.is_varargs
(adding an s at the end of the attribute name) I will see an attribute
error and know what is going on. If I do the same mistake with the
kind attribute param.kind == "varargs", the expression will just
always be False without any explanation.
>>> * is_implemented : bool
>>> True if the parameter is implemented for use. Some platforms
>>> implement functions but can't support specific parameters
>>> (e.g. "mode" for ``os.mkdir``). Passing in an unimplemented
>>> parameter may result in the parameter being ignored,
>>> or in NotImplementedError being raised. It is intended that
>>> all conditions where ``is_implemented`` may be False be
>>> thoroughly documented.
>>
>> I suppose that the value depends on the running platform? (For
>> example, you may get a different value on Linux and Windows.)
>
> Correct.
>
>>> Implementation
>>> ==============
>>>
>>> - If the object has a ``__signature__`` attribute and if it
>>> is not ``None`` - return a deepcopy of it
>>
>> Oh, why copying the object? It may impact performances. If fhe caller
>> knows that it will modify the signature, it can deepcopy the
>> signature.
>
> There was a discussion on this topic earlier on python-dev.
> In short - as we usually create new signatures with each 'signature()'
> call, users will expect that they can modify those freely. But if we
> have one defined in __signature__, without copying it, all its
> modifications will be persistent across 'signature()' calls. So the
> deepcopy here is required more for the consistency reasons. Besides,
> I don't think that 'signature()' will be used extensively in
> performance-critical types of code. And even if it is - you can just
> cache it manually.
>
>>> - If it is ``None`` and the object is an instance of
>>> ``BuiltinFunction``, raise a ``ValueError``
>>
>> What about builtin functions (ex: len)? Do you plan to add a
>> __signature__ attribute? If yes, something created on demand or
>> created at startup?
>
> Larry is going to add signatures to some 'os' module functions. But
> that would it for 3.3, I guess.
>
>> It would be nice to have a C API to create Signature objects, maybe
>> from the same format string than PyArg_Parse*() functions. But it can
>> be implemented later.
>
> Then parameters will lack the 'name' attribute. I think we need another
> approach here.
>
>> Is it possible to build a Signature object from a string describing
>> the prototype (ex: "def f(x, y): pass")? (I mean: do you plan to add
>> such function?)
>
>
> There are no plans to add it now (no good reasons to include such
> functionality in 3.3 at least)
>
> Thank you,
>
> -
> Yury
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/alexandre.zani%40gmail.com
More information about the Python-Dev
mailing list