On Thu, Jun 14, 2012 at 6:50 AM, Yury Selivanov <yselivanov...@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@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/alexandre.zani%40gmail.com _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com