8000 Add alternative to isinstance for bytes vs strings · thecodingchicken/python-future@b4bab1b · GitHub
[go: up one dir, main page]

Skip to content

Commit b4bab1b

Browse files
committed
Add alternative to isinstance for bytes vs strings
1 parent 0193ca5 commit b4bab1b

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

docs/source/isinstance.rst

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
Distinguishing bytes from unicode text
2+
--------------------------------------
3+
4+
After these imports::
5+
6+
from __future__ import unicode_literals
7+
from future.builtins import *
8+
9+
the following tests pass on Py3 but fail on Py2::
10+
11+
>>> s = 'my unicode string'
12+
>>> assert isinstance(s, str)
13+
14+
>>> b = b'my byte-string'
15+
>>> assert isinstance(b, bytes)
16+
17+
This is a corner case that results on Py2 with :func:`isinstance` because
18+
(unicode) string literals ``'...'`` and byte-string literals ``b'...'``
19+
create instances of the superclasses of the backported :class:`str` and
20+
:class:`bytes` types from :mod:`future.builtins` (i.e. the native Py2
21+
unicode and 8-bit string types).
22+
23+
If type-checking is necessary to distinguish unicode text from bytes
24+
portably across Py3 and Py2, utility functions called :func:`is_text` and
25+
:func:`is_bytes` are available in :mod:`future.utils`. You can use them
26+
as follows::
27+
28+
>>> from __future__ import unicode_literals
29+
>>> from future.builtins import *
30+
>>> from future.utils import is_text, is_bytes
31+
32+
>>> assert is_text('My (unicode) string')
33+
>>> assert is_text(str('My (unicode) string'))
34+
35+
>>> assert is_bytes(b'My byte-string')
36+
>>> assert is_bytes(bytes(b'My byte-string'))
37+
38+
``is_text(s)`` tests whether the object ``s`` is (or inherits from) a
39+
unicode string. It is equivalent to the following expression::
40+
41+
isinstance(s, type(u''))
42+
43+
which is ``True`` if ``s`` is a native Py3 string, Py2 unicode object, or
44+
:class:`future.builtins.str` object on Py2.
45+
46+
Likewise, ``is_bytes(b)`` tests whether ``b`` is (or inherits from) an
47+
8-bit byte-string. It is equivalent to::
48+
49+
isinstance(b, type(b''))
50+
51+
which is ``True`` if ``b`` is a native Py3 bytes object, Py2 8-bit str,
52+
or :class:`future.builtins.bytes` object on Py2.
53+

docs/source/what_else.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Essentials
1414

1515
.. include:: bytes_object.rst
1616
.. include:: str_object.rst
17+
.. include:: isinstance.rst
1718
.. include:: open_function.rst
1819
.. include:: dict_methods.rst
1920
.. include:: custom_str_methods.rst

future/tests/test_utils.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Tests for the various utility functions and classes in ``future.utils``
4+
"""
5+
6+
from __future__ import absolute_import, unicode_literals, print_function
7+
from future.builtins import *
8+
from future import utils
9+
10+
import unittest
11+
12+
TEST_UNICODE_STR = u'ℝεα∂@ßʟ℮ ☂ℯṧт υηḯ¢☺ḓ℮'
13+
14+
15+
class TestUtils(unittest.TestCase):
16+
def setUp(self):
17+
self.s = TEST_UNICODE_STR
18+
self.s2 = str(self.s)
19+
self.b = b'ABCDEFG'
20+
self.b2 = bytes(self.b)
21+
22+
def test_is_text(self):
23+
self.assertTrue(utils.is_text(self.s))
24+
self.assertTrue(utils.is_text(self.s2))
25+
self.assertFalse(utils.is_text(self.b))
26+
self.assertFalse(utils.is_text(self.b2))
27+
28+
def test_is_bytes(self):
29+
self.assertTrue(utils.is_bytes(self.b))
30+
self.assertTrue(utils.is_bytes(self.b2))
31+
self.assertFalse(utils.is_bytes(self.s))
32+
self.assertFalse(utils.is_bytes(self.s2))
33+
34+
35+
if __name__ == '__main__':
36+
unittest.main()

future/utils/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,13 @@ def is_new_style(cls):
376376
# ``from future.builtins import *``.
377377
native_str = str
378378

379+
def is_text(obj):
380+
return isinstance(obj, type(u''))
381+
382+
383+
def is_bytes(obj):
384+
return isinstance(obj, type(b''))
385+
379386

380387
__all__ = ['PY3', 'PY2', 'PYPY', 'python_2_unicode_compatible',
381388
'with_metaclass', 'bchr', 'bstr', 'bord',

0 commit comments

Comments
 (0)
0