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@@as_bytes 21@@as_text 22@@as_str_any 23@@path_to_str 24 25## Types 26The compatibility module also provides the following types: 27 28* `bytes_or_text_types` 29* `complex_types` 30* `integral_types` 31* `real_types` 32""" 33 34from __future__ import absolute_import 35from __future__ import division 36from __future__ import print_function 37 38import numbers as _numbers 39 40import numpy as _np 41import six as _six 42 43from tensorflow.python.util.all_util import remove_undocumented 44from tensorflow.python.util.tf_export import tf_export 45from tensorflow.python.util.tf_export import tf_export 46 47 48@tf_export('compat.as_bytes', 'compat.as_str') 49def as_bytes(bytes_or_text, encoding='utf-8'): 50 """Converts either bytes or unicode to `bytes`, using utf-8 encoding for text. 51 52 Args: 53 bytes_or_text: A `bytes`, `str`, or `unicode` object. 54 encoding: A string indicating the charset for encoding unicode. 55 56 Returns: 57 A `bytes` object. 58 59 Raises: 60 TypeError: If `bytes_or_text` is not a binary or unicode string. 61 """ 62 if isinstance(bytes_or_text, _six.text_type): 63 return bytes_or_text.encode(encoding) 64 elif isinstance(bytes_or_text, bytes): 65 return bytes_or_text 66 else: 67 raise TypeError('Expected binary or unicode string, got %r' % 68 (bytes_or_text,)) 69 70 71@tf_export('compat.as_text') 72def as_text(bytes_or_text, encoding='utf-8'): 73 """Returns the given argument as a unicode string. 74 75 Args: 76 bytes_or_text: A `bytes`, `str`, or `unicode` object. 77 encoding: A string indicating the charset for decoding unicode. 78 79 Returns: 80 A `unicode` (Python 2) or `str` (Python 3) object. 81 82 Raises: 83 TypeError: If `bytes_or_text` is not a binary or unicode string. 84 """ 85 if isinstance(bytes_or_text, _six.text_type): 86 return bytes_or_text 87 elif isinstance(bytes_or_text, bytes): 88 return bytes_or_text.decode(encoding) 89 else: 90 raise TypeError('Expected binary or unicode string, got %r' % bytes_or_text) 91 92 93# Convert an object to a `str` in both Python 2 and 3. 94if _six.PY2: 95 as_str = as_bytes 96else: 97 as_str = as_text 98 99 100@tf_export('compat.as_str_any') 101def as_str_any(value): 102 """Converts to `str` as `str(value)`, but use `as_str` for `bytes`. 103 104 Args: 105 value: A object that can be converted to `str`. 106 107 Returns: 108 A `str` object. 109 """ 110 if isinstance(value, bytes): 111 return as_str(value) 112 else: 113 return str(value) 114 115 116@tf_export('compat.path_to_str') 117def path_to_str(path): 118 """Returns the file system path representation of a `PathLike` object, else as it is. 119 120 Args: 121 path: An object that can be converted to path representation. 122 123 Returns: 124 A `str` object. 125 """ 126 if hasattr(path, '__fspath__'): 127 path = as_str_any(path.__fspath__()) 128 return path 129 130 131# Numpy 1.8 scalars don't inherit from numbers.Integral in Python 3, so we 132# need to check them specifically. The same goes from Real and Complex. 133integral_types = (_numbers.Integral, _np.integer) 134tf_export('compat.integral_types').export_constant(__name__, 'integral_types') 135real_types = (_numbers.Real, _np.integer, _np.floating) 136tf_export('compat.real_types').export_constant(__name__, 'real_types') 137complex_types = (_numbers.Complex, _np.number) 138tf_export('compat.complex_types').export_constant(__name__, 'complex_types') 139 140# Either bytes or text. 141bytes_or_text_types = (bytes, _six.text_type) 142tf_export('compat.bytes_or_text_types').export_constant(__name__, 143 'bytes_or_text_types') 144 145_allowed_symbols = [ 146 'as_str', 147 'bytes_or_text_types', 148 'complex_types', 149 'integral_types', 150 'real_types', 151] 152 153remove_undocumented(__name__, _allowed_symbols) 154