Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1ebd3f5
Adapt Protocol and runtime from PR #417
ilevkivskyi Aug 19, 2017
37b6a7b
An attempt to fix missing failure on some versions
ilevkivskyi Aug 19, 2017
bb3a8a9
Fix missing import
ilevkivskyi Aug 19, 2017
d8ae30e
Fix another missing import
ilevkivskyi Aug 19, 2017
a4e68ff
And another missing import
ilevkivskyi Aug 19, 2017
c8076ee
Abandon attempts to support protocols in 3.5.0 and 3.5.1, see #195
ilevkivskyi Aug 19, 2017
80e8014
Attempt to keep support of 3.5.2
ilevkivskyi Aug 19, 2017
a6a631a
Hopefully last backward compatibility nit
ilevkivskyi Aug 19, 2017
5913fe6
Skip some irrelevant tests
ilevkivskyi Aug 19, 2017
faf4ff0
Conditionally add Protocol and runtime to __all__
ilevkivskyi Aug 19, 2017
c7f6b68
Tweaks following Jelle's comments
ilevkivskyi Aug 20, 2017
8151355
Allow Protocol tests on 3.5.1
ilevkivskyi Sep 2, 2017
76a7ecd
Fix constannt NO_PROTOCOL definition
ilevkivskyi Sep 2, 2017
95faebe
Add super() argument
ilevkivskyi Sep 2, 2017
04f1c51
Fix typo
ilevkivskyi Sep 2, 2017
ce4e04f
Fix super()
ilevkivskyi Sep 2, 2017
a7cf2fb
Fix super() second attemt
ilevkivskyi Sep 2, 2017
8b50c60
Attempt an alternative solution
ilevkivskyi Sep 2, 2017
1dc1971
Fix _gorg in typing 3.5.1
ilevkivskyi Sep 2, 2017
e25077f
Disable some tests for old-style generics and add one new instead
ilevkivskyi Sep 2, 2017
1c1d9fe
Add some tests as proposed by Michael
ilevkivskyi Sep 2, 2017
9b22594
More tests per Michael's CR; remove redundant extra; drop old-style c…
ilevkivskyi Sep 2, 2017
458b232
Fix _gorg on Python 2; add 3.6.2 to Travis
ilevkivskyi Sep 2, 2017
dbc6def
First part of Jukka's CR
ilevkivskyi Sep 2, 2017
31cbe0d
Second part of Jukka's CR: docstrings and comments
ilevkivskyi Sep 2, 2017
171b1e5
Update one comment in test
ilevkivskyi Sep 3, 2017
fc0ec94
Don't support issubclass() for protocols with non-method members
ilevkivskyi Sep 9, 2017
f1f478a
Add more tests
ilevkivskyi Sep 9, 2017
8652ced
Only apply the None rule to callable attributes on class
ilevkivskyi Sep 9, 2017
8f0a778
Add more tests
ilevkivskyi Sep 9, 2017
23e80da
Backport latest changes and tests on Python 2
ilevkivskyi Sep 9, 2017
dc01948
Fix lint
ilevkivskyi Sep 9, 2017
733016d
Fix Python 3.6+ tests
ilevkivskyi Sep 9, 2017
8f12689
One more Python 3.6+ fix
ilevkivskyi Sep 9, 2017
a4d397e
Address CR
ilevkivskyi Sep 14, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Attempt to keep support of 3.5.2
  • Loading branch information
ilevkivskyi committed Aug 19, 2017
commit 80e8014411e1d66a30a5b5684868d4fc270032a4
67 changes: 40 additions & 27 deletions typing_extensions/src_py3/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from typing import GenericMeta, TypingMeta, Generic, Callable, TypeVar, Tuple
NO_PROTOCOL = False
try:
from typing import _type_vars, _next_in_mro, _type_check, _check_generic
from typing import _type_vars, _next_in_mro, _type_check
except ImportError:
NO_PROTOCOL = True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment discussing when this happens and what it means.

try:
Expand All @@ -36,6 +36,17 @@ class _TypingEmpty: pass
from typing import _make_subclasshook
except ImportError:
_make_subclasshook = None
try:
from typing import _check_generic
except ImportError:
def _check_generic(cls, parameters):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just always define this locally? What do you get by importing it from typing (apart from the risk that a future version of typing changes this internal function in a way that breaks us)? Same for _no_slots_copy (though not for the other conditional imports -- I see their value).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be just an artefact from initial attempts to allow this on 3.5.1 with minimal changes, I will check now.

if not cls.__parameters__:
raise TypeError("%s is not a generic class" % repr(cls))
alen = len(parameters)
elen = len(cls.__parameters__)
if alen != elen:
raise TypeError("Too %s parameters for %s; actual %s, expected %s" %
("many" if alen > elen else "few", repr(cls), alen, elen))

if hasattr(typing, '_generic_new'):
_generic_new = typing._generic_new
Expand Down Expand Up @@ -865,39 +876,41 @@ def __getitem__(self, params):
extra=self.__extra__,
orig_bases=self.__orig_bases__)

if NO_PROTOCOL:
del ProtocolMeta
else:
class Protocol(metaclass=ProtocolMeta):
"""Base class for protocol classes. Protocol classes are defined as::

class Protocol(metaclass=ProtocolMeta):
"""Base class for protocol classes. Protocol classes are defined as::

class Proto(Protocol[T]):
def meth(self) -> T:
...
class Proto(Protocol[T]):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments about the corresponding docstring in the Python 2 implementation. They are also relevant here.

def meth(self) -> T:
...

Such classes are primarily used with static type checkers that recognize
structural subtyping (static duck-typing), for example::
Such classes are primarily used with static type checkers that recognize
structural subtyping (static duck-typing), for example::

class C:
def meth(self) -> int:
return 0
class C:
def meth(self) -> int:
return 0

def func(x: Proto[int]) -> int:
return x.meth()
def func(x: Proto[int]) -> int:
return x.meth()

func(C()) # Passes static type check
func(C()) # Passes static type check

See PEP 544 for details. Protocol classes decorated with @typing_extensions.runtime
act as simple-minded runtime protocols that checks only the presence of
given attributes, ignoring their type signatures.
"""
See PEP 544 for details. Protocol classes decorated with @typing_extensions.runtime
act as simple-minded runtime protocols that checks only the presence of
given attributes, ignoring their type signatures.
"""

__slots__ = ()
_is_protocol = True
__slots__ = ()
_is_protocol = True

def __new__(cls, *args, **kwds):
if cls._gorg is Protocol:
raise TypeError("Type Protocol cannot be instantiated; "
"it can be used only as a base class")
return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
def __new__(cls, *args, **kwds):
if cls._gorg is Protocol:
raise TypeError("Type Protocol cannot be instantiated; "
"it can be used only as a base class")
return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)


def runtime(cls):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't like the @runtime name. Maybe @runtime_checkable? The longer this is the better, to discourage people from using it without understanding the consequences.

Expand All @@ -916,4 +929,4 @@ def runtime(cls):


if NO_PROTOCOL:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again it seems weird to define it and then delete it. (Also maybe the flag could be reverted and be named HAVE_PROTOCOLS?)

del Protocol, runtime
del runtime