[Python-checkins] peps: Update from Yury.
brett.cannon
python-checkins at python.org
Fri Jun 15 19:56:27 CEST 2012
http://hg.python.org/peps/rev/c1f693b39292
changeset: 4461:c1f693b39292
user: Brett Cannon <brett at python.org>
date: Fri Jun 15 13:56:20 2012 -0400
summary:
Update from Yury.
files:
pep-0362.txt | 164 +++++++++++++++++++++++++++++---------
1 files changed, 126 insertions(+), 38 deletions(-)
diff --git a/pep-0362.txt b/pep-0362.txt
--- a/pep-0362.txt
+++ b/pep-0362.txt
@@ -51,12 +51,13 @@
as listed in ``code.co_varnames``).
* bind(\*args, \*\*kwargs) -> BoundArguments
Creates a mapping from positional and keyword arguments to
- parameters. Raises a ``BindError`` (subclass of ``TypeError``)
- if the passed arguments do not match the signature.
+ parameters. Raises a ``TypeError`` if the passed arguments do
+ not match the signature.
* bind_partial(\*args, \*\*kwargs) -> BoundArguments
Works the same way as ``bind()``, but allows the omission
of some required arguments (mimics ``functools.partial``
- behavior.)
+ behavior.) Raises a ``TypeError`` if the passed arguments do
+ not match the signature.
* format(...) -> str
Formats the Signature object to a string. Optional arguments allow
for custom render functions for parameter names,
@@ -84,27 +85,53 @@
* name : str
The name of the parameter as a string.
+
* default : object
The default value for the parameter, if specified. If the
parameter has no default value, this attribute is not set.
+
* annotation : object
The annotation for the parameter if specified. If the
parameter has no annotation, this attribute is not set.
-* 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.
-* is_implemented : bool
+
+* kind : str
+ Describes how argument values are bound to the parameter.
+ Possible values:
+
+ * ``Parameter.POSITIONAL_ONLY`` - value must be supplied
+ as a positional argument.
+
+ Python has no explicit syntax for defining positional-only
+ parameters, but many builtin and extension module functions
+ (especially those that accept only one or two parameters)
+ accept them.
+
+ * ``Parameter.POSITIONAL_OR_KEYWORD`` - value may be
+ supplied as either a keyword or positional argument
+ (this is the standard binding behaviour for functions
+ implemented in Python.)
+
+ * ``Parameter.KEYWORD_ONLY`` - value must be supplied
+ as a keyword argument. Keyword only parameters are those
+ which appear after a "*" or "\*args" entry in a Python
+ function definition.
+
+ * ``Parameter.VAR_POSITIONAL`` - a tuple of positional
+ arguments that aren't bound to any other parameter.
+ This corresponds to a "\*args" parameter in a Python
+ function definition.
+
+ * ``Parameter.VAR_KEYWORD`` - a dict of keyword arguments
+ that aren't bound to any other parameter. This corresponds
+ to a "\*\*kwds" parameter in a Python function definition.
+
+* 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
+ all conditions where ``implemented`` may be False be
thoroughly documented.
Two parameters are equal when all their attributes are equal.
@@ -159,12 +186,11 @@
- If it is ``None`` and the object is an instance of
``BuiltinFunction``, raise a ``ValueError``
- - If the object is a an instance of ``FunctionType``:
+ - If it has a ``__wrapped__`` attribute, return
+ ``signature(object.__wrapped__)``
- - If it has a ``__wrapped__`` attribute, return
- ``signature(object.__wrapped__)``
-
- - Or else construct a new ``Signature`` object and return it
+ - If the object is a an instance of ``FunctionType`` construct
+ and return a new ``Signature`` for it
- If the object is a method or a classmethod, construct and return
a new ``Signature`` object, with its first parameter (usually
@@ -223,6 +249,9 @@
Visualizing Callable Objects' Signature
---------------------------------------
+
+Let's define some classes and functions:
+
::
from inspect import signature
@@ -245,25 +274,62 @@
return a, b, c
- print('FooMeta >', str(signature(FooMeta)))
- print('Foo >', str(signature(Foo)))
- print('Foo.__call__ >', str(signature(Foo.__call__)))
- print('Foo().__call__ >', str(signature(Foo().__call__)))
- print('partial(Foo().__call__, 1, c=3) >',
- str(signature(partial(Foo().__call__, 1, c=3))))
- print('partial(partial(Foo().__call__, 1, c=3), 2, c=20) >',
- str(signature(partial(partial(Foo().__call__, 1, c=3), 2, c=20))))
+ def shared_vars(*shared_args):
+ """Decorator factory that defines shared variables that are
+ passed to every invocation of the function"""
+ def decorator(f):
+ @wraps(f)
+ def wrapper(*args, **kwds):
+ full_args = shared_args + args
+ return f(*full_args, **kwds)
+ # Override signature
+ sig = wrapper.__signature__ = signature(f)
+ for __ in shared_args:
+ sig.parameters.popitem(last=False)
+ return wrapper
+ return decorator
-The script will output:
+
+ @shared_vars({})
+ def example(_state, a, b, c):
+ return _state, a, b, c
+
+
+ def format_signature(obj):
+ return str(signature(obj))
+
+
+Now, in the python REPL:
+
::
- FooMeta > (name, bases, dct, *, bar:bool=False)
- Foo > (spam:int=42)
- Foo.__call__ > (self, a, b, *, c) -> tuple
- Foo().__call__ > (a, b, *, c) -> tuple
- partial(Foo().__call__, 1, c=3) > (b, *, c=3) -> tuple
- partial(partial(Foo().__call__, 1, c=3), 2, c=20) > (*, c=20) -> tuple
+ >>> format_signature(FooMeta)
+ '(name, bases, dct, *, bar:bool=False)'
+
+ >>> format_signature(Foo)
+ '(spam:int=42)'
+
+ >>> format_signature(Foo.__call__)
+ '(self, a, b, *, c) -> tuple'
+
+ >>> format_signature(Foo().__call__)
+ '(a, b, *, c) -> tuple'
+
+ >>> format_signature(partial(Foo().__call__, 1, c=3))
+ '(b, *, c=3) -> tuple'
+
+ >>> format_signature(partial(partial(Foo().__call__, 1, c=3), 2, c=20))
+ '(*, c=20) -> tuple'
+
+ >>> format_signature(example)
+ '(a, b, c)'
+
+ >>> format_signature(partial(example, 1, 2))
+ '(c)'
+
+ >>> format_signature(partial(partial(example, 1, b=2), c=3))
+ '(b=2, c=3)'
Annotation Checker
@@ -317,14 +383,14 @@
else:
if not isinstance(default, type_):
raise ValueError("{func}: wrong type of a default value for {arg!r}". \
- format(func=sig.qualname, arg=param.name))
+ format(func=func.__qualname__, arg=param.name))
def check_type(sig, arg_name, arg_type, arg_value):
# Internal function that encapsulates arguments type checking
if not isinstance(arg_value, arg_type):
raise ValueError("{func}: wrong type of {arg!r} argument, " \
"{exp!r} expected, got {got!r}". \
- format(func=sig.qualname, arg=arg_name,
+ format(func=func.__qualname__, arg=arg_name,
exp=arg_type.__name__, got=type(arg_value).__name__))
@functools.wraps(func)
@@ -341,12 +407,12 @@
# OK, we have a type for the argument, lets get the corresponding
# parameter description from the signature object
param = sig.parameters[arg_name]
- if param.is_args:
+ if param.kind == param.VAR_POSITIONAL:
# If this parameter is a variable-argument parameter,
# then we need to check each of its values
for value in arg:
check_type(sig, arg_name, type_, value)
- elif param.is_kwargs:
+ elif param.kind == param.VAR_KEYWORD:
# If this parameter is a variable-keyword-argument parameter:
for subname, value in arg.items():
check_type(sig, arg_name + ':' + subname, type_, value)
@@ -364,13 +430,35 @@
else:
if isinstance(return_type, type) and not isinstance(result, return_type):
raise ValueError('{func}: wrong return type, {exp} expected, got {got}'. \
- format(func=sig.qualname, exp=return_type.__name__,
+ format(func=func.__qualname__, exp=return_type.__name__,
got=type(result).__name__))
return result
return wrapper
+Render Function Signature to HTML
+---------------------------------
+
+::
+
+ import inspect
+
+ def format_to_html(func):
+ sig = inspect.signature(func)
+
+ html = sig.format(token_params_separator='<span class="t-comma">,</span>',
+ token_colon='<span class="t-colon">:</span>',
+ token_eq='<span class="t-eq">=</span>',
+ token_return_annotation='<span class="t-ra">-></span>',
+ token_left_paren='<span class="t-lp">(</span>',
+ token_right_paren='<span class="t-lp">)</span>',
+ token_kwonly_separator='<span class="t-ast">*</span>',
+ format_name=lambda name: '<span class="name">'+name+'</span>')
+
+ return '<span class="py-func">{}</span>'.format(html)
+
+
References
==========
--
Repository URL: http://hg.python.org/peps
More information about the Python-checkins
mailing list