• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Functions for Python 2 vs. 3 compatibility.
16
17## Conversion routines
18In addition to the functions below, `as_str` converts an object to a `str`.
19
20
21## Types
22The compatibility module also provides the following types:
23
24* `bytes_or_text_types`
25* `complex_types`
26* `integral_types`
27* `real_types`
28"""
29
30from __future__ import absolute_import
31from __future__ import division
32from __future__ import print_function
33
34import numbers as _numbers
35
36import numpy as _np
37import six as _six
38
39from tensorflow.python.util.tf_export import tf_export
40
41
42def as_bytes(bytes_or_text, encoding='utf-8'):
43  """Converts either bytes or unicode to `bytes`, using utf-8 encoding for text.
44
45  Args:
46    bytes_or_text: A `bytes`, `str`, or `unicode` object.
47    encoding: A string indicating the charset for encoding unicode.
48
49  Returns:
50    A `bytes` object.
51
52  Raises:
53    TypeError: If `bytes_or_text` is not a binary or unicode string.
54  """
55  if isinstance(bytes_or_text, _six.text_type):
56    return bytes_or_text.encode(encoding)
57  elif isinstance(bytes_or_text, bytes):
58    return bytes_or_text
59  else:
60    raise TypeError('Expected binary or unicode string, got %r' %
61                    (bytes_or_text,))
62
63
64def as_text(bytes_or_text, encoding='utf-8'):
65  """Returns the given argument as a unicode string.
66
67  Args:
68    bytes_or_text: A `bytes`, `str`, or `unicode` object.
69    encoding: A string indicating the charset for decoding unicode.
70
71  Returns:
72    A `unicode` (Python 2) or `str` (Python 3) object.
73
74  Raises:
75    TypeError: If `bytes_or_text` is not a binary or unicode string.
76  """
77  if isinstance(bytes_or_text, _six.text_type):
78    return bytes_or_text
79  elif isinstance(bytes_or_text, bytes):
80    return bytes_or_text.decode(encoding)
81  else:
82    raise TypeError('Expected binary or unicode string, got %r' % bytes_or_text)
83
84
85# Convert an object to a `str` in both Python 2 and 3.
86if _six.PY2:
87  as_str = as_bytes
88  tf_export('compat.as_bytes', 'compat.as_str')(as_bytes)
89  tf_export('compat.as_text')(as_text)
90else:
91  as_str = as_text
92  tf_export('compat.as_bytes')(as_bytes)
93  tf_export('compat.as_text', 'compat.as_str')(as_text)
94
95
96@tf_export('compat.as_str_any')
97def as_str_any(value):
98  """Converts to `str` as `str(value)`, but use `as_str` for `bytes`.
99
100  Args:
101    value: A object that can be converted to `str`.
102
103  Returns:
104    A `str` object.
105  """
106  if isinstance(value, bytes):
107    return as_str(value)
108  else:
109    return str(value)
110
111
112@tf_export('compat.path_to_str')
113def path_to_str(path):
114  """Returns the file system path representation of a `PathLike` object, else as it is.
115
116  Args:
117    path: An object that can be converted to path representation.
118
119  Returns:
120    A `str` object.
121  """
122  if hasattr(path, '__fspath__'):
123    path = as_str_any(path.__fspath__())
124  return path
125
126
127# Numpy 1.8 scalars don't inherit from numbers.Integral in Python 3, so we
128# need to check them specifically.  The same goes from Real and Complex.
129integral_types = (_numbers.Integral, _np.integer)
130tf_export('compat.integral_types').export_constant(__name__, 'integral_types')
131real_types = (_numbers.Real, _np.integer, _np.floating)
132tf_export('compat.real_types').export_constant(__name__, 'real_types')
133complex_types = (_numbers.Complex, _np.number)
134tf_export('compat.complex_types').export_constant(__name__, 'complex_types')
135
136# Either bytes or text.
137bytes_or_text_types = (bytes, _six.text_type)
138tf_export('compat.bytes_or_text_types').export_constant(__name__,
139                                                        'bytes_or_text_types')
140