[Patches] [ python-Patches-1607548 ] Optional Argument Syntax

SourceForge.net noreply at sourceforge.net
Mon Feb 26 21:58:35 CET 2007


Patches item #1607548, was opened at 2006-12-02 15:53
Message generated for change (Comment added) made by gvanrossum
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1607548&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Core (C code)
Group: Python 3000
Status: Open
Resolution: Accepted
Priority: 5
Private: No
Submitted By: Tony Lownds (tonylownds)
Assigned to: Guido van Rossum (gvanrossum)
Summary: Optional Argument Syntax

Initial Comment:
This patch implements optional argument syntax for Python 3000. The patch still has issues; I am posting so that Collin Winters can add a link to the PEP.

The syntax implemented is roughly:

def f(arg:expr, (nested1:expr, nested2:expr)) -> expr:
  suite

The function object has a new attribute, func_annotations that maps from argument names to the result of the expression. The return annotation is stored with a key of 'return'.

Lambda's syntax doesn't support annotations.

This patch alters the MAKE_FUNCTION opcode. I have an implementation that built the func_annotations dictionary in bytecode as well but it was bigger and slower.


----------------------------------------------------------------------

>Comment By: Guido van Rossum (gvanrossum)
Date: 2007-02-26 15:58

Message:
Logged In: YES 
user_id=6380
Originator: NO

Tony, I am checking make_closure_fix.patch and
peepholer_and_max_annotations.patch.

Unfortunately, something happened to pydoc.py so that pydoc.patch no
longer applies and I don't want to have to think about how to fix it.  Can
you have a look at this and submit a revised patch?

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-14 15:32

Message:
Logged In: YES 
user_id=24100
Originator: YES

File Added: make_closure_fix.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-14 15:31

Message:
Logged In: YES 
user_id=24100
Originator: YES

Combines the code paths for MAKE_FUNCTION and MAKE_CLOSURE. 
Fixes a crash where functions with closures and either annotations or 
keyword-only arguments result in MAKE_CLOSURE, but only 
MAKE_FUNCTION has the code to handle annotations or keyword-only
arguments.

Includes enough tests to trigger the bug.


----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-06 16:03

Message:
Logged In: YES 
user_id=24100
Originator: YES

I tried to implement getargspec() as described, and unfortunately there 
is another wrinkle to consider. Keyword-only arguments may or may not 
have defaults. So the invariant described in getargspec()'s docstring
can't 
be maintained when simply appending keyword-only arguments.

    A tuple of four things is returned: (args, varargs, varkw, defaults).
    'args' is a list of the argument names (it may contain nested lists).
    'args' will include keyword-only argument names. 
    'varargs' and 'varkw' are the names of the * and ** arguments or
None.
    'defaults' is an n-tuple of the default values of the last n
arguments.

The attached patch adds an 'getfullargspec' API that returns complete 
information; 'getargspec' raises an error if information would be lost;
the order 
of arguments in 'formatargspec' is backwards compatible, so that
formatargspec(*getargspec(f)) == formatargspec(*getfullargspec(f)) when
getargspec(f) does not raise an error.

PEP 362 could and probably should replace the new getfullargspec()
function,
so I did not implement an API more complicated than a tuple.

File Added: pydoc.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-06 15:05

Message:
Logged In: YES 
user_id=24100
Originator: YES

Change peepholer to not bail in the presence of EXTENDED_ARG +
MAKE_FUNCTION.
Enforce the natural 16-bit limit of annotations in compile.c.

File Added: peepholer_and_max_annotations.patch

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2007-01-04 12:53

Message:
Logged In: YES 
user_id=6380
Originator: NO

I like the following approach: (1) the old API continues to work for all
functions, but provides incomplete information (not losing the kw-only args
completely, but losing the fact that they are kw-only); (2) add a new API
that provides all the relevant information.

Maybe the new API should not return a 7-tuple but rather a structure with
named attributes; that makes it more future-proof.

Sorry, I don't have any good suggestions for new names.

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-04 02:12

Message:
Logged In: YES 
user_id=24100
Originator: YES

For getargs and getargvalues, including the names in positional args is an
excellent strategy.
There are uses (in cgitb) in the stdlib for getargvalues that then
wouldn't need to be changed. 

The 2 uses of getargspec in the stdlib (one of which I missed, in
DocXMLRPCServer) are both 
closely followed by formatargspec. I think those APIs should change or
information will be lost. 

Alternatively, a new function (hopefully with a better name than
getfullargspec :) could be 
made and getargspec could retain its API, but raise an error when
keyword-only arguments are 
present.

def getargspec(func):
  args, varargs, kwonlyargs, kwdefaults, varkw, defaults, ann =
getfullargspec()
  if kwonlyargs:
     raise ValueError, "function has keyword-only arguments, use
getfullargspec!"
  return args, varargs, varkw, defaults

I'll update the patch to fix getargvalues and DocXMLRPCServer this
weekend.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2007-01-04 00:22

Message:
Logged In: YES 
user_id=6380
Originator: NO

Well, it depends on the context whether that matters.  The kw-only args
could just be included in the positional args (which have names anyway) and
that wouldn't be so bad for some apps.

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2007-01-04 00:17

Message:
Logged In: YES 
user_id=24100
Originator: YES

I think everyone should update have to update their uses of getargspec and
friends, because otherwise they will silently mis-handle keyword-only
arguments.


----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2007-01-03 23:30

Message:
Logged In: YES 
user_id=6380
Originator: NO

I'm not sure it's right to just change the signature of the various
functions in inspect.py; that would break all existing code using that
module (and there definitely are other users besides pydoc).  It would be
better to add new methods that provide access to the additional
functionality.  Or do you think that everyone will have to change their
code anyway?

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2006-12-28 01:53

Message:
Logged In: YES 
user_id=33168
Originator: NO

I'm skipping the pydoc patch.  Didn't even look at it.  I don't have the
refleak, but I changed some calls and may have fixed it.

Committed revision 53170.

Leaving open to deal with the pydoc patch.

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-27 22:04

Message:
Logged In: YES 
user_id=24100
Originator: YES

Nothing else on the C side of things. The pydoc patch works well for me;
more tests ought to be added for function annotations and also for
keyword-only arguments, but perhaps that can be added on as a later patch
after checkin.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2006-12-27 20:38

Message:
Logged In: YES 
user_id=6380
Originator: NO

Thanks!  Is there anything else that you think needs to be done before I
check this in?  The core code looks alright to me; I can't be bothered with
reviewing the ast stuff or the compiler package since I don't know enough
about these, but given that it compiles things correctly I'm not so worried
about those.

What's the status of the pydoc patch? Are you still working on that?


----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-27 20:28

Message:
Logged In: YES 
user_id=24100
Originator: YES

Fixed in latest patch. Also added VISIT call for func_annotations.
File Added: opt_arg_ann.patch

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2006-12-27 19:40

Message:
Logged In: YES 
user_id=6380
Originator: NO

I believe I've found a leak in the code that adds annotations to a
function object. See this session:

>>> x = object()
>>> import sys
>>> sys.getrefcount(x)
2
>>> for i in range(100):
...  def f(x: x): pass
...
>>> del f
>>> sys.getrefcount(x)
102
>>>

At first I thought this could be due to the code added to the
MAKE_FUNCTION opcode, but I don't see a leak there. More likely
func_annotations is not being freed when a function object is deleted.


----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-23 14:05

Message:
Logged In: YES 
user_id=24100
Originator: YES

Initial patch to implement keyword-only arguments and annotations support
for pydoc and inspect.
Tests do not exercise these features, yet.

Output for annotations that are types is special cased so that for:

def intmin(*a: int) -> int: pass

...help(intmin) will display:

intmin(*a: int) -> int

File Added: pydoc.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-23 10:53

Message:
Logged In: YES 
user_id=24100
Originator: YES

Fixed the non-C89 style lines and the formatting (hopefully in compatible
style :)
File Added: opt_arg_ann.patch

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2006-12-22 16:41

Message:
Logged In: YES 
user_id=6380
Originator: NO

Thanks for the progress!  There are still a few lines ending in whitespace
or lines that are longer than 80 chars (and weren't before).  Mind cleaning
those up?

Also ceval.c:2305 and compile.c:1440 contain code that gcc 2.95 won't
compile (the 'int' declarations ought to be moved to the start of the
containing {...} block); I think this style is not C89 compatible.


----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-22 15:15

Message:
Logged In: YES 
user_id=24100
Originator: YES

Changes:
1. Fix crasher in Python/symtable.c -- annotations were visited inside the
function scope
2. Fix Lib/compiler issues with Lib/test/test_complex_args. 

Output from Lib/compiler does not pass all tests, same failures as in HEAD
of p3yk branch.

File Added: opt_arg_ann.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-21 15:21

Message:
Logged In: YES 
user_id=24100
Originator: YES

Changes:
1. Address Neal's comments (I hope)
2. test_scope passes
3. Added some additional tests to test_compiler

Open implementation issues:
1. Output from Lib/compiler does not pass test_complex_args, test_scope,
possibly more.

File Added: opt_arg_ann.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-20 17:13

Message:
Logged In: YES 
user_id=24100
Originator: YES

Changes:
1. Updated to apply cleanly
2. Fix to compile.c so that test_complex_args passes

Open implementation issues:
1. Neal's comments
2. test_scope fails
3. Output from Lib/compiler does not pass test_complex_args


File Added: opt_arg_ann.patch

----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-20 13:04

Message:
Logged In: YES 
user_id=24100
Originator: YES

I'll work on code formatting and the error checking and other cleanup.
Open to other names than tname and
vname, I created those non-terminals in order to use the same code for
processing "def" and "lambda". Terminals 
are caps IIUC. 

I did add a test for the multi-paren situation. 2.5 had that bug too.

Re: no changes to ceval, I tried generating the func_annotations
dictionary using 
bytecodes. That doesn't change the ceval loop but was more code and was
slower. 
So there is a way to avoid ceval changes.

Re: deciding if lambda was going to require parens around the arguments,
I don't think there was any decision, and yes annotations would be easily
supportable.
Happy to change if there is support, it's backwards incompatible.

Re: return type syntax, I have only seen the -> syntax (vs a keyword 'as')
on Guido's blog.

Thanks for the comments!

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2006-12-20 04:25

Message:
Logged In: YES 
user_id=33168
Originator: NO

Nix this comment:  I would definitely prefer the annotations baked into
the code object so
there are no changes to ceval.  I see that Guido wants it the way it
currently is which makes sense for nested functions.  There should probably
be a test with nested functions even though it really shouldn't be
different.  The test will verify that.

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2006-12-20 03:38

Message:
Logged In: YES 
user_id=33168
Originator: NO

When regenerating the patch, can you also remove non-functional changes
such as removing unneeded parens and whitespace changes.  Also, please try
to keep the same formatting in the file wrt tabs and spaces and don't move
code around.  I know this is a pain and inconsistent.  I think I changed
ast.c to be all 4 space indents with spaces only.

In compiler_simple_arg(), don't you need to check if annotation is NULL
when returned from ast_for_expr?  Otherwise an undetected error would go
through, wouldn't it?

In compiler_complex_args(), don't you need to set the ast_error (or a
SystemError) if the switch isn't a tname, vname, or LPAR?  I don't like the
names tname and vname.  Also they seem inconsistent.  Aren't all the other
names all CAPS?

In hunk, @@ -602,51 +625,75 @@ remove the commented out code.  We
shouldn't use any // style comments either.
Can you improve the error msg for kwdefaults == NULL?  (Thanks for adding
it!)
Check annotation for NULL if returned from ast_for_expr?

BTW, the AST code in this area was tricky code which had some bugs.  Did
you test with adding extra parentheses and singleton tuples?

I'm not sure if Guido preferred syntax -> vs a keyword 'as' for the return
type.

In symtable.c remove the printfs.  They should probably be SystemErrors or
something.

I would definitely prefer the annotations baked into the code object so
there are no changes to ceval.

Did we decide if lambda was going to require parens around the arguments? 
If so, it could support annotations, right?  (No comment on the usefulness
of annotations for lambdas. :-)

In compiler_visit_argannotation, you should return the result from
PyList_Append and can remove the comment about checking for errors.  Also,
I believe the INCREF is not needed, it will be done by PyList_Append.
Same deal with returning result of compiler_visit_argannotations() (the
one with an s).

Need to check for PyList_New() returning NULL in
compiler_visit_annotations().
Lots more error checking needs to be added in this area.

Dammit, I really want to use Mondrian for these comments!  (Sorry Tony,
not your fault, I'm just having some bad memories at this point cause I
have to keep providing the references.)

This patch looks very complete in that it updates things like the compiler
package and the parsermodule.c.  Good job!  This is a great start.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2006-12-19 20:22

Message:
Logged In: YES 
user_id=6380
Originator: NO

Applying the patch fails, probably due to recent merge activities in the
p3yk branch. Can I inconvenience you with a request to regenerate the patch
from the branch head?

----------------------------------------------------------------------

Comment By: Jim Jewett (jimjjewett)
Date: 2006-12-11 12:29

Message:
Logged In: YES 
user_id=764593
Originator: NO

Could you rename it to "argument annotations"?  "optional argument" makes
me think of the current keyword arguments, that can be but don't have to be
passed.

-jJ


----------------------------------------------------------------------

Comment By: Tony Lownds (tonylownds)
Date: 2006-12-03 20:24

Message:
Logged In: YES 
user_id=24100
Originator: YES

This patch implements optional argument syntax for Python 3000. The patch
still has issues:
1. test_ast and test_scope fail.
2. Running the test suite after compiling the library with the compiler
package causes failures
3. no docs
4. C-code reference counts and error checking needs a review

The syntax implemented is roughly:

def f(arg:expr, (nested1:expr, nested2:expr)) -> expr:
suite

The function object has a new attribute, func_annotations that maps from
argument names to the result of the expression. The return annotation is
stored with a key of 'return'.

Lambda's syntax doesn't support annotations.

The ast format has changed for the builtin compiler and the compiler
package. A new token was added, '->' (called RARROW in token.h). token.py
lost ERRORTOKEN after re-generating, I don't know why. I added it back
manually.



----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1607548&group_id=5470


More information about the Patches mailing list