Skip to content

Commit

Permalink
Fix an upcoming pytype error in absltest.
Browse files Browse the repository at this point in the history
I'm working on an improvement to pytype's type-checking of function type
comments, which exposes an annotation error in absltest.
_TempFile._open() was annotated as returning Union[TextIO, BinaryIO] but is
used as:

def open_text(...) -> ContextManager[TextIO]:
  ...
  return self._open(...)

which will cause pytype to complain about open_text returning bytes when text
is expected. The proper way to fix this issue would be to use typing.overload
and typing.Literal to define multiple signatures for _open(), but pytype
doesn't fully support Literal yet, so I've added type comments with the
right types in open_text() and open_bytes().

This change also fixes a mistake in the return annotation on _open() and
alphabetically orders all typing imports.

PiperOrigin-RevId: 283783117
Change-Id: I4d78a9eb1c98218e62a9b0662931213f7c5c1668
  • Loading branch information
Abseil Team authored and copybara-github committed Dec 4, 2019
1 parent 5a1e57e commit 2e9e5d1
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions absl/testing/absltest.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
try:
# pylint: disable=unused-import
import typing
from typing import AnyStr, Callable, Text, Optional, ContextManager, TextIO, BinaryIO, Union, Type, Tuple, Any, MutableSequence, Sequence, Mapping, MutableMapping, IO, List
from typing import Any, AnyStr, BinaryIO, Callable, ContextManager, IO, Iterator, List, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Text, TextIO, Tuple, Type, Union
# pylint: enable=unused-import
except ImportError:
pass
Expand Down Expand Up @@ -484,7 +484,8 @@ def open_text(self, mode='rt', encoding='utf8', errors='strict'):
'file in text mode'.format(mode))
if 't' not in mode:
mode += 't'
return self._open(mode, encoding, errors)
cm = self._open(mode, encoding, errors) # type: ContextManager[TextIO]
return cm

def open_bytes(self, mode='rb'):
# type: (Text) -> ContextManager[BinaryIO]
Expand All @@ -505,11 +506,15 @@ def open_bytes(self, mode='rb'):
'file in binary mode'.format(mode))
if 'b' not in mode:
mode += 'b'
return self._open(mode, encoding=None, errors=None)
cm = self._open(mode, encoding=None, errors=None) # type: ContextManager[BinaryIO]
return cm

# TODO(b/123775699): Once pytype supports typing.Literal, use overload and
# Literal to express more precise return types and remove the type comments in
# open_text and open_bytes.
@contextlib.contextmanager
def _open(self, mode, encoding='utf8', errors='strict'):
# type: (Text, Text, Text) -> Union[TextIO, BinaryIO]
# type: (Text, Text, Text) -> Iterator[Union[IO[Text], IO[bytes]]]
with io.open(
self.full_path, mode=mode, encoding=encoding, errors=errors) as fp:
yield fp
Expand Down

0 comments on commit 2e9e5d1

Please sign in to comment.