[Python-Dev] PEP 362 Third Revision

Yury Selivanov yselivanov.ml at gmail.com
Thu Jun 14 15:50:38 CEST 2012


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'?)
>> * 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


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /