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