Skip to content

Commit

Permalink
Second part of review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ilevkivskyi committed Apr 21, 2017
1 parent 2e25db8 commit 3a09ffd
Showing 1 changed file with 49 additions and 13 deletions.
62 changes: 49 additions & 13 deletions pep-0544.txt
Original file line number Diff line number Diff line change
Expand Up @@ -912,28 +912,51 @@ Allow only protocol methods and force use of getters and setters
One could argue that protocols typically only define methods, but not
variables. However, using getters and setters in cases where only a
simple variable is needed would be quite unpythonic. Moreover, the widespread
use of properties (that are often act as validators) in large code bases
use of properties (that often act as type validators) in large code bases
is partially due to previous absence of static type checkers for Python,
the problem that PEP 484 and this PEP are aiming to solve.
the problem that PEP 484 and this PEP are aiming to solve. For example::

# without static types

class MyClass:
@property
def my_attr(self):
return self._my_attr
@my_attr.setter
def my_attr(self, value):
if not isinstance(value, int):
raise ValidationError("An integer expected for my_attr")
self._my_attr = value

# with static types

class MyClass:
my_attr: int


Support non-protocol members
----------------------------

There was an idea to make some methods "non-protocol" (i.e. not necessary
to implement, and inherited in explicit subclassing), but it was rejected,
since this complicates things. For example, consider this function::
since this complicates things. For example, consider this situation::

def fun(m: Mapping):
m.keys()
class Proto(Protocol):
@abstractmethod
def first(self) -> int:
raise NotImplementedError
def second(self) -> int:
return self.first() + 1

def fun(arg: Proto) -> None:
arg.second()

The question is should this be an error? We think most people would expect
this to be valid. The same applies to most other methods in ``Mapping``,
people expect that they are provided by ``Mapping``. Therefore, to be on
the safe side, we need to require these methods to be implemented.
If one looks at definitions in ``collections.abc``, there are very few methods
that could be considered "non-protocol". Therefore, it was decided to not
introduce "non-protocol" methods.
this to be valid. Therefore, to be on the safe side, we need to require both
methods to be implemented in implicit subclasses. In addition, if one looks
at definitions in ``collections.abc``, there are very few methods that could
be considered "non-protocol". Therefore, it was decided to not introduce
"non-protocol" methods.

There is only one downside to this: it will require some boilerplate for
implicit subtypes of ``Mapping`` and few other "large" protocols. But, this
Expand Down Expand Up @@ -1053,7 +1076,7 @@ will be very easy to add this later if needed.
Prohibit explicit subclassing of protocols by non-protocols
-----------------------------------------------------------

This was rejected mainly for two reasons:
This was rejected for the following reasons:

* Backward compatibility: People are already using ABCs, including generic
ABCs from ``typing`` module. If we prohibit explicit subclassing of these
Expand All @@ -1066,11 +1089,24 @@ This was rejected mainly for two reasons:
``__iter__``, ``__contains__``, ``__reversed__``, ``index``, and ``count``
for free.

* Explicit subclassing makes it explicit that a class implements a particular
protocol, making subtyping relationships easier to see.

* Type checkers can warn about missing protocol members or members with

This comment has been minimized.

Copy link
@JukkaL

JukkaL Apr 21, 2017

Contributor

One additional reason: It makes it possible to force a class to be considered a subtype of a protocol (by using # type: ignore together with an explicit base class) when it's not strictly compatible, such as when it has an unsafe override.

incompatible types more easily, without having to use hacks like dummy
assignments discussed above in this section.


Backwards Compatibility
=======================

This PEP is fully backwards compatible.
This PEP is almost fully backwards compatible. Few collection classes such as
``Sequence`` and ``Mapping`` will be turned into runtime protocols, therefore
results of ``isinstance()`` checks are going to change in some edge cases.
For example, a class that implements the ``Sequence`` protocol but does not
explicitly inherit from ``Sequence`` currently returns ``False`` in
corresponding instance and class checks. With this PEP implemented, such
checks will return ``True``.


Implementation
Expand Down

0 comments on commit 3a09ffd

Please sign in to comment.