[Python-Dev] Yet another type system -- request for comments on a SoC proposal
ryanf at cs.uoregon.edu
Sat May 6 08:28:43 CEST 2006
I'm currently revising a proposal for the Google Summer of Code, and it
was suggested that I start a thread here to get input. Apologies for the
length, but I wanted this to more than just a link to my proposal.
The short version of my proposal is: The module would provide a
system by which the attributes of function parameters was inferred
through the testing process, and those attributes would be used to check
the arguments to function calls at runtime. In addition to a form of
runtime type checking, this information would also be used to
automatically generate up-to-date documentation.
I've built a *very* simple proof of concept here:
My full proposal is here:
It's been suggested that this could, instead, be an extension to one of
the lint tools; while I'm open to that suggestion it seems to me like
that would seriously change the character of the modified lint tool, as
it would be running tests rather than simply analyzing source.
So why have something automatically generate signatures, rather than
explicitly declare them? Currently, the knowledge about a function's
signature may be stored in four places (other than the function's calls):
1. The function itself: the programmer expects to be passed a group of
objects which implement certain functions, and uses them as such.
2. The tests run against the function.
3. A sequence of checks on the passed objects, though the author may
trust the function user to pass the right thing.
4. The documentation for the function, though, again, the author may
leave that out.
The proposed module would use the knowledge embedded in the system by
the programmer in the first two points to generate the other
information. As the function changes over time, these generated items
will be kept up to date simply by re-running the new test cases.
A sample program using this module might look like the following:
verify = sigcheck.decorator('./verify.pickle') # note 1
@verify # note 2
def foo(file, b, c):
# ... do stuff ...
def foo(self, a, b):
return a * b
# and, the worst case:
@verify(('a', sigcheck.Int), # note 3.1
('b', ('m1', 'm2', 'm3')), # 3.2
('c', sigcheck.Int, sigcheck.String), # 3.3
returns=sigcheck.String, # 3.4
raises=(MyException, MyOtherExc)) # 3.5
def bar(self, a, b, c):
# ... do some stuff...
1. The inferred information needs to be stored somewhere. A file could
hold the pickled data structure between testing runs.
2. This line shows the most basic use of the decorator. The system
uses inference for all the parameters.
3. There may be cases where the inferences are incorrect, the user
wishes to be totally explicit about certain parameters, or wishes
to fold the inferences into their code explicitly. By passing a
data structure to the decorator they may partially or completely
bypass the inferences.
1. The system will come with some common 'types' built in.
2. The user may also require attribute sets, free-form.
3. If a parameter may have several, very different attribute sets,
they may simply be listed.
4. The return type may also be specified.
5. The function may raise exceptions which are expected; these
should be specified so the inference system doesn't treat them
More information about the Python-Dev