[Python-Dev] PEP 318 restrictions on elements (original) (raw)

[Python-Dev] PEP 318 - generality of list; restrictions on elements

Greg Ewing greg at cosc.canterbury.ac.nz
Mon Mar 8 18:52:39 EST 2004


"Jewett, Jim J" <jim.jewett at eds.com>:

Right now, the variable portion of the syntax is:

'[' wrapper (, wrapper)* ']' What else should be accepted, to avoid surprises?

Whatever else happens, I think the square brackets should always be present. They do not denote list construction; they are the syntactic elements which say "here is a parenthetical note concerning qualities which this function is to have".

What are the restrictions on list items?

Only a function? Only a code object? (I assume so)

Any callable object should be acceptable as a wrapper. I don't see any need to restrict them to functions.

To allow for dynamic insertion of a sequence of wrappers, I can think of two possibilities:

(A) Allow a list or tuple of further items to be used as an item.

(B) Allow a '*' before an item to mean that the item is to be treated as a sequence of items to be iterated over.

I think I prefer (B) because it eliminates any need for type testing, and allows any iterable to be used as the items sequence rather than being restricted to certain sequence types.

Must the code return the original function? Must the code return a code object?

The wrapper can return any object it likes, as long as it makes sense to insert it into the class dict as the result of the def, or pass it on to further wrappers. (In most cases it probably won't return the original function -- that's the whole point of wrapping!)

1. # fail, integer not a callable? (Don't try to slice the args!) def name(args)[0]:

Yes, fail.

2. # fail, as w[0] is itself a (non-callable) list? w = [wrapper] def name(args) [w]:

Under suggestion (A) above, recurse into the list. Under (B), fail (item non-callable).

3. # fail, not a list? def name(args) classmethod:

Syntax error.

4. # ??? lambda would be OK, except for the second ":" def name(args)[lambda x: x]:

Accepted. I can't see any reason why the second ':' should be an issue, any more than the multiple ':' in nested lambdas causes any problem.

5. # should succeed? def name(args)[x for x in decorators if x in active]:

On the understanding that there is a generator expression between the [...]:

Under (A): Fail, item is not callable and is not a list or tuple (it's a generator-iterator).

Under (B): Fail, item is not callable. This would succeed, however:

 def name(args)[*x for x in decorators if x in active]:

6. # ??? wrapper does not return a callable. y = lambda x: None def name(args) [y]:

Succeeds, but leaves 'name' defined as 'None' in the target namespace, which probably isn't very useful.

7. # a list, but no '[]'. either surprises. def name(args) list((wrap1, wrap2)):

Syntax error.

8. # a list, but no '[]'. either surprises. w = [wrapper] def name(args) w:

Syntax error.

9. # a list, but no '[]'. either surprises. def w(): return [y,y,y] def name(args) w():

Syntax error.

Do the wrappers have to be defined when the definition starts?

The wrapper expressions are evaluated when the def is executed (same as with default argument values).

def outer(): # w not defined at module load, but defined before any call def inner(x)[w]: print x return inner

Okay.

But if that is OK, then which w would be used in the next example?

def w(fn): print "outside w" return fn

def outer(): # w not defined yet, but defined in this def inner(x)[w]: print x def w(fn): return fn inner(5)

The w in def inner(x)[w]: refers to the local w, which is not bound when the inner def is executed, so a NameError results when outer() is called.

How about this? There is no guarantee that othermod will finish loading first, though I suppose that already causes problems today.

import othermod def fn()[othermod.wrap]: pass

You take your chances. Okay if othermod gets as far as binding othermod.wrap by the time def fn() is executed (which presumably it will as long as nothing goes wrong).

Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg at cosc.canterbury.ac.nz +--------------------------------------+



More information about the Python-Dev mailing list