Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-16 Thread Brett Cannon
On Nov 15, 2007 12:48 PM, Steven Bethard [EMAIL PROTECTED] wrote:
 On Nov 14, 2007 1:18 PM, Brett Cannon [EMAIL PROTECTED] wrote:
  On Nov 14, 2007 10:30 AM, Isaac Morland [EMAIL PROTECTED] wrote:
   So I wrote a Signature class.  Instances of the class represent all the
   information present between the parentheses of a procedure definition.
   Properties are provided to get the information out, and an expand_args 
   method
   can be called to expand arguments into a dictionary.  This expand_args 
   method
   implements (if I've done it right) the argument conversion part of section
   5.3.4 of the Python Reference Manual 
   (http://docs.python.org/ref/calls.html).
 
  As Collin already pointed out, it sounds like you want PEP 362 to get
  into the stdlib.  I have not made a big push to try to get my existing
  implementation into Python 2.6/3.0, but I plan to at some point.

 Every time I read PEP 362, I get lost in the details.  When you get
 around to working on it again, could you add a bunch of examples?
 That would make it much easier to tell why we want all those objects
 and attributes.


You might not need them in general.  It just re-packages all the
information that is found between a function object and a code object
into a single location.

 FWIW, Isaac's version of bind() that returns a regular str-object
 dict is all I've ever needed in my own code.

That's what the implementation does at the moment (if I remember correctly).

I am about to bundle up the code and submit to PyPI to get feedback
from folks and to just get it out there instead of languishing in the
sandbox while I try to decide exactly what to do about the open
issues.  I will see if i can toss in some examples into the PEP.

-Brett
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-16 Thread Brett Cannon
On Nov 15, 2007 12:48 PM, Steven Bethard [EMAIL PROTECTED] wrote:
 On Nov 14, 2007 1:18 PM, Brett Cannon [EMAIL PROTECTED] wrote:
  On Nov 14, 2007 10:30 AM, Isaac Morland [EMAIL PROTECTED] wrote:
   So I wrote a Signature class.  Instances of the class represent all the
   information present between the parentheses of a procedure definition.
   Properties are provided to get the information out, and an expand_args 
   method
   can be called to expand arguments into a dictionary.  This expand_args 
   method
   implements (if I've done it right) the argument conversion part of section
   5.3.4 of the Python Reference Manual 
   (http://docs.python.org/ref/calls.html).
 
  As Collin already pointed out, it sounds like you want PEP 362 to get
  into the stdlib.  I have not made a big push to try to get my existing
  implementation into Python 2.6/3.0, but I plan to at some point.

 Every time I read PEP 362, I get lost in the details.  When you get
 around to working on it again, could you add a bunch of examples?
 That would make it much easier to tell why we want all those objects
 and attributes.


Done.  I tossed up an annotations duck typing checker in the PEP.

 FWIW, Isaac's version of bind() that returns a regular str-object
 dict is all I've ever needed in my own code.

My implementation does that as well.  It was a typo in the PEP that
said bind() returned Parameter objects as values.

-Brett
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-15 Thread Isaac Morland
On Wed, 14 Nov 2007, Brett Cannon wrote:

 As Collin already pointed out, it sounds like you want PEP 362 to get
 into the stdlib.  I have not made a big push to try to get my existing
 implementation into Python 2.6/3.0, but I plan to at some point.

Yes, it had not occurred to me to check the existing PEPs for my PEP 
before proposing it.  Now that I've read it I have a couple of comments, 
but it is close to what I'm looking for.

 I've put the code below, but I wonder if the real solution is just to create 
 an
 interface to already-existing capability?  It occurs to me that the
 implementation is likely to be in the interpreter itself and not written in
 Python.

 I don't see why a Python implementation is bad.  If you make this
 information lazy then it is not such a big deal to have it take a
 little bit longer than if it was implemented in C.

I don't have any problem with a Python implementation.  In particular, I'm 
not concerned in this case about the performance.  Rather what I actually 
wanted was a way to just bind arguments and then get the resulting 
dictionary (what would usually become locals()).  I realized that I could 
create a Signature object with a binding method, but that I would just be 
duplicating part of the Python interpreter.

I haven't studied the Python interpreter so I don't know if it is feasible 
to re-use that (presumably highly optimized for actually calling 
procedures, not just binding arguments) code or if it makes more sense to 
simply re-implement it.

 One possible improvement (and I'm not sure it's better, so I'm just putting 
 it
 out there): perhaps expand_args should be renamed to __call__. Then 
 essentially
 a Signature object would be a procedure whose body is just return locals 
 ().

 __call__ is already used a method name for objects that can be called.

Yes, that is why I used that name.  The idea is that a Signature object be 
callable, have itself as signature, and return the dictionary of locals 
resulting from the procedure call argument binding process.

You can also think of (my idea of) Signature objects as providing a simple 
way to create lots of special-case dictionary constructors.

More (semi-)formally, if the body of a procedure p is return locals (), 
then p(...) is the same as p.__signature__(...).

A couple of comments about PEP-362:

1. For the name attribute of the Parameter object, I think it needs to 
be str | tuple(str) | tuple(tuple(str)) | :

 def a ((b,c),(d,(e,f))):
... print b,c,d,e,f
...
 a
function a at 0x7899b0
 a((1,2),(3,(4,5)))
1 2 3 4 5


2. For position of keyword-only parameters, are they allowed to conflict 
with each other, or does each parameter get a unique value?  +1 on not 
using -1 as a special value.  Python is not COBOL.

3. (My apologies if any of these have already been discussed)  Under 
Implementation, could __signature__ just be a property of callable 
objects?  Not saying anything about implementation, but just being able to 
say formataddr.__signature__ feels nicely minimal (to me).

4. Signature.bind - for what I'm doing, I definitely want what would 
become locals() in a procedure call, i.e. keys in the resulting dictionary 
are strings.  But I can see the other behaviour being useful in other 
circumstances so maybe there should be bind and bindp, or (see above) 
__call__ and bind, or something else.

5. var_args... default to None.  +10 from me on this one - this is 
*exactly* what None is, as far as I can tell.  I'm new enough that this 
should probably count for at most +0.1 though.

6. The PEP doesn't say anything about building Signature objects from 
scratch, and the code does not reassure me.  I would like to be able to 
build a Signature from a sequence of strings for positional parameter 
names, for example, and provide default values for some parameters.  My 
solution started off:

class Signature (object):
  def __init__ (self, argnames,
   excessargs=None, excesskeys=None, defaults=None):
  self.__argnames = tuple (argnames)
  self.__excessargs = excessargs
  self.__excesskeys = excesskeys
  if defaults is None:
  defaults = {}
  self.__defaults = dict (defaults)
[]

Thanks for the responses.  I hope the above is at least in part not a 
re-hash of old discussions.

Isaac Morland   CSCF Web Guru
DC 2554C, x36650WWW Software Specialist
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-15 Thread Isaac Morland
On Thu, 15 Nov 2007, Isaac Morland wrote:

 1. For the name attribute of the Parameter object, I think it needs to
 be str | tuple(str) | tuple(tuple(str)) | :

No, that's still wrong.  I think it needs to be T,
where T == str | tuple(T).

Isaac Morland   CSCF Web Guru
DC 2554C, x36650WWW Software Specialist
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-15 Thread Brett Cannon
On Nov 15, 2007 8:42 AM, Isaac Morland [EMAIL PROTECTED] wrote:
 On Wed, 14 Nov 2007, Brett Cannon wrote:

  As Collin already pointed out, it sounds like you want PEP 362 to get
  into the stdlib.  I have not made a big push to try to get my existing
  implementation into Python 2.6/3.0, but I plan to at some point.

 Yes, it had not occurred to me to check the existing PEPs for my PEP
 before proposing it.  Now that I've read it I have a couple of comments,
 but it is close to what I'm looking for.

  I've put the code below, but I wonder if the real solution is just to 
  create an
  interface to already-existing capability?  It occurs to me that the
  implementation is likely to be in the interpreter itself and not written in
  Python.
 
  I don't see why a Python implementation is bad.  If you make this
  information lazy then it is not such a big deal to have it take a
  little bit longer than if it was implemented in C.

 I don't have any problem with a Python implementation.  In particular, I'm
 not concerned in this case about the performance.  Rather what I actually
 wanted was a way to just bind arguments and then get the resulting
 dictionary (what would usually become locals()).  I realized that I could
 create a Signature object with a binding method, but that I would just be
 duplicating part of the Python interpreter.

 I haven't studied the Python interpreter so I don't know if it is feasible
 to re-use that (presumably highly optimized for actually calling
 procedures, not just binding arguments) code or if it makes more sense to
 simply re-implement it.

  One possible improvement (and I'm not sure it's better, so I'm just 
  putting it
  out there): perhaps expand_args should be renamed to __call__. Then 
  essentially
  a Signature object would be a procedure whose body is just return locals 
  ().
 
  __call__ is already used a method name for objects that can be called.

 Yes, that is why I used that name.  The idea is that a Signature object be
 callable, have itself as signature, and return the dictionary of locals
 resulting from the procedure call argument binding process.

 You can also think of (my idea of) Signature objects as providing a simple
 way to create lots of special-case dictionary constructors.

 More (semi-)formally, if the body of a procedure p is return locals (),
 then p(...) is the same as p.__signature__(...).


Fair enough, but I prefer having a method for it.

 A couple of comments about PEP-362:

 1. For the name attribute of the Parameter object, I think it needs to
 be str | tuple(str) | tuple(tuple(str)) | :

  def a ((b,c),(d,(e,f))):
 ... print b,c,d,e,f
 ...
  a
 function a at 0x7899b0
  a((1,2),(3,(4,5)))
 1 2 3 4 5
 

You are taking annotations a little too far in terms of typing.  =)
There are no type checks for the annotations; they are for
documentation purposes only.

Plus tuple parameters are gone as of Py3K thanks to my prodding to
ditch them so I am really not going to worry about them now.  =)


 2. For position of keyword-only parameters, are they allowed to conflict
 with each other, or does each parameter get a unique value?  +1 on not
 using -1 as a special value.  Python is not COBOL.


It is just he numeric order that the arguments are found, period.
Keyword-only arguments are given a index position, it just doesn't
really mean much other than giving it a numeric position.

 3. (My apologies if any of these have already been discussed)  Under
 Implementation, could __signature__ just be a property of callable
 objects?  Not saying anything about implementation, but just being able to
 say formataddr.__signature__ feels nicely minimal (to me).

The idea has been to add the code to the stdlib and let people try
them out first.  If they ended up being used often enough then
discussion of putting a signature object on every callable could be
discussed.


 4. Signature.bind - for what I'm doing, I definitely want what would
 become locals() in a procedure call, i.e. keys in the resulting dictionary
 are strings.  But I can see the other behaviour being useful in other
 circumstances so maybe there should be bind and bindp, or (see above)
 __call__ and bind, or something else.


I only want to bother supporting one or the other.  Doing the reverse
is one or two lines of code.

 5. var_args... default to None.  +10 from me on this one - this is
 *exactly* what None is, as far as I can tell.  I'm new enough that this
 should probably count for at most +0.1 though.

 6. The PEP doesn't say anything about building Signature objects from
 scratch, and the code does not reassure me.

That's because there is no way.  =)

  I would like to be able to
 build a Signature from a sequence of strings for positional parameter
 names, for example, and provide default values for some parameters.  My
 solution started off:

 class Signature (object):
   def __init__ (self, argnames,
excessargs=None, excesskeys=None, defaults=None):
  

Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-15 Thread Steven Bethard
On Nov 14, 2007 1:18 PM, Brett Cannon [EMAIL PROTECTED] wrote:
 On Nov 14, 2007 10:30 AM, Isaac Morland [EMAIL PROTECTED] wrote:
  So I wrote a Signature class.  Instances of the class represent all the
  information present between the parentheses of a procedure definition.
  Properties are provided to get the information out, and an expand_args 
  method
  can be called to expand arguments into a dictionary.  This expand_args 
  method
  implements (if I've done it right) the argument conversion part of section
  5.3.4 of the Python Reference Manual 
  (http://docs.python.org/ref/calls.html).

 As Collin already pointed out, it sounds like you want PEP 362 to get
 into the stdlib.  I have not made a big push to try to get my existing
 implementation into Python 2.6/3.0, but I plan to at some point.

Every time I read PEP 362, I get lost in the details.  When you get
around to working on it again, could you add a bunch of examples?
That would make it much easier to tell why we want all those objects
and attributes.

FWIW, Isaac's version of bind() that returns a regular str-object
dict is all I've ever needed in my own code.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
--- Bucky Katt, Get Fuzzy
___
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


[Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-14 Thread Isaac Morland
For another project (see my previous email on named tuples), I needed to 
represent procedure signatures, and use them to expand arguments into the 
dictionary of values that exists when execution of a procedure starts.  To my 
surprise, this capability didn't seem to be provided by the Python library, 
even though it clearly is present within the Python system somewhere.

So I wrote a Signature class.  Instances of the class represent all the 
information present between the parentheses of a procedure definition. 
Properties are provided to get the information out, and an expand_args method 
can be called to expand arguments into a dictionary.  This expand_args method 
implements (if I've done it right) the argument conversion part of section 
5.3.4 of the Python Reference Manual (http://docs.python.org/ref/calls.html).

I've put the code below, but I wonder if the real solution is just to create an 
interface to already-existing capability?  It occurs to me that the 
implementation is likely to be in the interpreter itself and not written in 
Python.

One possible improvement (and I'm not sure it's better, so I'm just putting it 
out there): perhaps expand_args should be renamed to __call__. Then essentially 
a Signature object would be a procedure whose body is just return locals ().

class Signature (object):
 def __init__ (self, argnames,
  excessargs=None, excesskeys=None, defaults=None):
 self.__argnames = tuple (argnames)
 self.__excessargs = excessargs
 self.__excesskeys = excesskeys
 if defaults is None:
 defaults = {}
 self.__defaults = dict (defaults)

 @property
 def argnames (self):
 return self.__argnames

 @property
 def excessargs (self):
 return self.__excessargs

 @property
 def excesskeys (self):
 return self.__excesskeys

 def defaults (self):
 return dict (self.__defaults)

 def expand_args (self, *args, **keys):
 # Start with defaults
 result = self.defaults ()

 # Assign positional arguments
 for i in range (min (len (args), len (self.argnames))):
 result[self.argnames[i]] = args[i]

 # Assign keyword arguments
 for arg in self.argnames:
 if arg in keys:
 if arg in result:
 raise TypeError
 result[arg] = keys[arg]
 del keys[arg]

 # Check for missing arguments
 for i in range (len (args), len (self.argnames)):
 if not self.argnames[i] in result:
 raise TypeError

 # Excess positional arguments (*args parameter)
 if self.excessargs is None:
 if len (args)  len (self.argnames):
 raise TypeError
 else:
 result[self.excessargs] = args[len (self.argnames):]

 # Excess keyword arguments (**keys parameter)
 if self.excesskeys is None:
 if keys:
 raise TypeError
 else:
 result[self.excesskeys] = keys

 return result


Isaac Morland   CSCF Web Guru
DC 2554C, x36650WWW Software Specialist
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-14 Thread Collin Winter
On Nov 14, 2007 10:30 AM, Isaac Morland [EMAIL PROTECTED] wrote:
 For another project (see my previous email on named tuples), I needed to
 represent procedure signatures, and use them to expand arguments into the
 dictionary of values that exists when execution of a procedure starts.  To my
 surprise, this capability didn't seem to be provided by the Python library,
 even though it clearly is present within the Python system somewhere.

 So I wrote a Signature class.  Instances of the class represent all the
 information present between the parentheses of a procedure definition.
 Properties are provided to get the information out, and an expand_args method
 can be called to expand arguments into a dictionary.  This expand_args method
 implements (if I've done it right) the argument conversion part of section
 5.3.4 of the Python Reference Manual (http://docs.python.org/ref/calls.html).

Have you seen http://www.python.org/dev/peps/pep-0362/? It sounds
awfully similar to what you're proposing here.

Collin Winter
___
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


Re: [Python-Dev] Python Library Addition: First-class Procedure Signatures

2007-11-14 Thread Brett Cannon
On Nov 14, 2007 10:30 AM, Isaac Morland [EMAIL PROTECTED] wrote:
 For another project (see my previous email on named tuples), I needed to
 represent procedure signatures, and use them to expand arguments into the
 dictionary of values that exists when execution of a procedure starts.  To my
 surprise, this capability didn't seem to be provided by the Python library,
 even though it clearly is present within the Python system somewhere.

 So I wrote a Signature class.  Instances of the class represent all the
 information present between the parentheses of a procedure definition.
 Properties are provided to get the information out, and an expand_args method
 can be called to expand arguments into a dictionary.  This expand_args method
 implements (if I've done it right) the argument conversion part of section
 5.3.4 of the Python Reference Manual (http://docs.python.org/ref/calls.html).


As Collin already pointed out, it sounds like you want PEP 362 to get
into the stdlib.  I have not made a big push to try to get my existing
implementation into Python 2.6/3.0, but I plan to at some point.

 I've put the code below, but I wonder if the real solution is just to create 
 an
 interface to already-existing capability?  It occurs to me that the
 implementation is likely to be in the interpreter itself and not written in
 Python.


I don't see why a Python implementation is bad.  If you make this
information lazy then it is not such a big deal to have it take a
little bit longer than if it was implemented in C.

 One possible improvement (and I'm not sure it's better, so I'm just putting it
 out there): perhaps expand_args should be renamed to __call__. Then 
 essentially
 a Signature object would be a procedure whose body is just return locals ().

__call__ is already used a method name for objects that can be called.

-Brett
___
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