[Python-3000] Type parameterization (was: Re: Type annotations: annotating generators)

Guido van Rossum guido at python.org
Fri May 19 07:00:20 CEST 2006


On 5/18/06, Collin Winter <collinw at gmail.com> wrote:
> On 5/19/06, Guido van Rossum <guido at python.org> wrote:
> > On 5/18/06, Collin Winter <collinw at gmail.com> wrote:
> > > I'd like to see the typechecking machinery ignore differences like
> > > "real type" v "pseudo type", looking only at whether, zB, a
> > > __parameterize__ method is present. Using __parameterize__ method (or
> > > some other name) allows maximum flexibility with respect to type
> > > parameterization.
> > >
> > > For example, the built-in list type might not allow the patterned
> > > parameterization I asked about above. A user might choose to subclass
> > > list to provide this, giving the subclass a __parameterize__ method
> > > something like:
> > >
> > > @classmethod
> > > def __parameterize__(cls, *vargs):
> > >     ....
> >
> > I'm not sure what you're up to here -- maybe it's a reference to
> > something you did in your own system? But I agree that that kind of
> > subclassing (perhaps at the metaclass level) ought to be possible.
>
> I'm just trying to flesh out how type parameterization will work under
> the covers. What I'm proposing is that list[int] would desugar to
> list.__parameterize__(int). In context:
>
> def foo(a: int, b: list[int]) -> int
>
> desugars to
>
> def foo(a: int, b: list.__parameterize__(int)) -> int
>
> The __parameterize__ methods take the parameter(s) as arguments and
> return an object that can be used to verify that an object is a list
> with int elements.
>
> I've implemented a demo of what I'm driving at, using your
> metaclass-with-__getitem__ method, taking a PatternedList class as a
> quick example [1].
>
> My goal with this is to keep user-defined annotation classes on the
> same level as the built-in types, to prevent them from becoming
> second-class citizens in this system.
>
> Collin Winter
>
> [1] - http://tinyurl.com/egabj

That's not quite how I did it. list[int] should return another type,
not a list instance. Here's a minimal example of what I'm after (truly
minimal because it only allows a single parameter named T):

class Parameterizable1(type):
    # Simplification: only one parameter allowed
    def __getitem__(self, arg):
        newcls = self.__class__(self.__name__, (self,), {})
        newcls.T = arg
        return newcls
    def __repr__(self):
        if hasattr(self, "T"):
            return "%s[%s]" % (self.__name__, self.T)
        else:
            return self.__name__

class List(list):
    __metaclass__ = Parameterizable1

print List
print List[int]

class Int(int):
    # This isn't really meant to be parameterizable, but has a nicer repr()
    __metaclass__ = Parameterizable1

print List[Int]

# Show that
a = List[int]()
a.append(0)
a.append(42)
print a

This prints

List
List[<type 'int'>]
List[Int]
[0, 42]


-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list