On 9/7/07, Jim Jewett <[EMAIL PROTECTED]> wrote: > > A Signature object has the following structure attributes: > > > * name : str > > Name of the function. This is not fully qualified because > > function objects for methods do not know the class they are > > contained within. This makes functions and methods > > indistinguishable from one another when passed to decorators, > > preventing proper creation of a fully qualified name. > > (1) Would this change with the new static __class__ attribute used > for the new super? >
I don't know enough about the super implementation to know. If you can figure out the class from the function object alone then sure, this can change. > (2) What about functions without a name? Do you want to say str or > NoneType, or is that assumed? > What functions don't have a name? Even lambdas have the name '<lambda>'. > (3) Is the Signature object live or frozen? (name is writable ... > will the Signature object reflect the new name, or the name in use at > the time it was created?) > They are currently one-time creation objects. One could change it to use properties and do the look up dynamically by caching the function object. But I currently have it implemented as all created in __init__ and then just left alone. > > * var_annotations: dict(str, object) > > Dict that contains the annotations for the variable parameters. > > The keys are of the variable parameter with values of the > > Is there a special key for the "->" returns annotation, or is that > available as a separate property? > Oops, that didn't get into the PEP for some reason. The Signature object has ``has_annotation``/``annotation`` attributes for the 'return' annotation. > > The structure of the Parameter object is: > > > * name : (str | tuple(str)) > > The name of the parameter as a string if it is not a tuple. If > > the argument is a tuple then a tuple of strings is used. > > What is used for unnamed arguments (typically provide by C)? I like > None, but I see the arguments for both "" and missing attribute. > It's open for debate. I didn't even think about functions not having __name__ set. Basically whatever people want to go with for var_args and var_kw_args. > > * position : int > > The position of the parameter within the signature of the > > function (zero-indexed). For keyword-only parameters the position > > value is arbitrary while not conflicting with positional > > parameters. > > Is this just a property/alias for signature.parameters.index(self) ? > Assuming that 'self' refers to some parameter, yes. > What should a "parameter" object not associated with a specific > signature return? -1, None, or missing attribute? > This is not an option as it must be specified by the Parameter constructor. A Parameter object should not exist without belonging to a Signature object. That's why neither Signature nor Parameter have their constructors specified; the signature() function is the only way you should cause the construction of either object. > Is there a way to get the associated Signature, or is it "compiled > out" when the Signature and its child Parameters are first > constructed? (I think the position property is the only attribute > that would use it, unless you want some of the other attributes -- > like annotations -- to be live.) There is currently no way to work backwards from a Parameter object to its parent Signature. It could be added if people wanted. > > ... > > I would also like to see a > > * value : object > > attribute; this would be missing on most functions, but might be > filled in on a Signature representing a closure, or an execution > frame. What for? How does either have bearing on the call signature of a function? > > > > When to construct the Signature object? > > --------------------------------------- > > > The Signature object can either be created in an eager or lazy > > fashion. In the eager situation, the object can be created during > > creation of the function object. > > Since most code doesn't need it, I would expect it to be optimized out > at least as often as docstrings are. > > > In the lazy situation, one would > > pass a function object to a function and that would generate the > > Signature object and store it to ``__signature__`` if > > needed, and then return the value of ``__signature__``. > > Why store it? Do you expect many use cases to need the signature more > than once (but not to save it themselves)? Because you can use these with decorators to allow introspection redirection:: def dec(fxn): def inner(*args, **kwargs): return fxn(*args, **kwargs) sig = signature(fxn) inner.__signature__ = sig return inner > > If there is a __signature__ attribute on a object, you have to specify > whether it can be replaced, It can. > which parts of it are writable, Any of it. > how that > will affect the function's own behavior, etc. It won't. > I also suspect it might > become a source of heisenbugs, like the "reference leaks" that were > really DUMMY items in a dict. > > If the Signature is just a snapshot no longer attached to the original > function, then people won't expect changes to the Signature to affect > the callable. > They are just snapshots unless people really want them to be live for some reason. > > Should ``Signature.bind`` return Parameter objects as keys? > > (see above) If a Signature is a snapshot (rather than a live part of > the function), then it might make more sense to just add a value > attribute to Parameter objects. > Why? You might make several calls to bind() and thus setting what a Parameter object would be bound to should be considered a temporary thing. > > Provide a mapping of parameter name to Parameter object? > > -------------------------------------------------------- > > > While providing access to the parameters in order is handy, it might > > also be beneficial to provide a way to retrieve Parameter objects from > > a Signature object based on the parameter's name. Which style of > > access (sequential/iteration or mapping) will influence how the > > parameters are stored internally and whether __getitem__ accepts > > strings or integers. > > I think it should accept both. > > What storage mechanism to use is an internal detail that should be > left to the implementation. I wouldn't expect Signature inspection to > be inside a tight loop anyhow, unless it were part of a Generic > Function dispatch engine ... and those authors (just PJE?) can > optimize on what they actually need. > I guess I can just try to do ``item.__index__()`` and if that triggers an AttributeError assume it is a name. > > Remove ``has_*`` attributes? > > ---------------------------- > > > If an EAFP approach to the API is taken, > > Please leave them; it is difficult to catch Exceptions in a list > comprehension. > You can also just use hasattr() if needed. > > Have ``var_args`` and ``_var_kw_args`` default to ``None``? > > Makes sense to me, particularly since it should probably be consistent > with function name, and that should probably be None. So another vote for None. Thanks for the feedback, Jim! _______________________________________________ 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