Skip to content

SelfType or another way to spell "type of self" (or, How to define a copy() function) #1212

Closed
@gvanrossum

Description

@gvanrossum

A colleague and I were wondering how to define a copy() method in a base class so that when called on an instance of a subclass it is known that it returns an instance of that subclass. We found the following solution:

T = TypeVar('T')
class Copyable:
    def copy(self: T) -> T:
        return self.__class__()  # type: ignore
class X(Copyable):
    def foo(self):
        pass
x = X()
x.foo()
xx = x.copy()
xx.foo()  # OK

Note that the # type: ignore is required for two reasons: you can't call self.__class__(), and it doesn't like the return type. Try e.g. return self and you get

x.py:5: error: Incompatible return value type: expected T`-1, got x.Copyable

It works in --py2 mode too:

    def copy(self):
        # type: (T) -> T
        return self.__class__()  # type: ignore

UPDATE: This doesn't actually work. :-( See next comment.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions