I'm overall very supportive of seeing something like this make it into Python to further strengthen duck typing in the language. I know I've wanted something something like this since ABCs were introduced.
I personally only have one issue/clarification for the PEP. On Mon, 20 Mar 2017 at 05:02 Ivan Levkivskyi <levkivs...@gmail.com> wrote: > [SNIP] > Protocol members > ---------------- > > All methods defined in the protocol class body are protocol members, both > normal and decorated with ``@abstractmethod``. If some or all parameters of > protocol method are not annotated, then their types are assumed to be > ``Any`` > (see PEP 484). Bodies of protocol methods are type checked, except for > methods > decorated with ``@abstractmethod`` with trivial bodies. A trivial body can > contain a docstring. > What is a "trivial body"? I don't know of any such definition anywhere in Python so this is too loosely defined. You also don't say what happens if the body isn't trivial. Are tools expected to raise an error? > Example:: > > from typing import Protocol > from abc import abstractmethod > > class Example(Protocol): > def first(self) -> int: # This is a protocol member > return 42 > > @abstractmethod > def second(self) -> int: # Method without a default implementation > """Some method.""" > > Note that although formally the implicit return type of a method with > a trivial body is ``None``, > This seems to suggest a trivial body is anything lacking a return statement. > type checker will not warn about above example, > such convention is similar to how methods are defined in stub files. > Static methods, class methods, and properties are equally allowed > in protocols. > Personally, I think even an abstract method should be properly typed. So in the example above, second() should either return a reasonable default value or raise NotImplementedError. My argument is "explicit is better than implicit" and you make errors when people call super() on an abstract method that doesn't return None when it doesn't make sense. I would also argue that you can't expect an abstract method to always be simple. For instance, I might define an abstract method that has horrible complexity characteristics (e.g. O(n**2)), but which might be acceptable in select cases. By making the method abstract you force subclasses to explicitly opt-in to using the potentially horrible implementation. -Brett > > To define a protocol variable, one must use PEP 526 variable > annotations in the class body. Additional attributes *only* defined in > the body of a method by assignment via ``self`` are not allowed. The > rationale > for this is that the protocol class implementation is often not shared by > subtypes, so the interface should not depend on the default implementation. > Examples:: > > from typing import Protocol, List > > class Template(Protocol): > name: str # This is a protocol member > value: int = 0 # This one too (with default) > > def method(self) -> None: > self.temp: List[int] = [] # Error in type checker > > To distinguish between protocol class variables and protocol instance > variables, the special ``ClassVar`` annotation should be used as specified > by PEP 526. > > >
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com