1*9c5db199SXin Li# Copyright (c) 2020 The Chromium Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li"""Miscellaneous Python 2-3 compatibility functions. 5*9c5db199SXin Li 6*9c5db199SXin LiSeven is an extension to the compatibility layer six. 7*9c5db199SXin LiIt contains utilities that ease migration from Python 2 8*9c5db199SXin Lito Python 3, but aren't present in the six library. 9*9c5db199SXin Li""" 10*9c5db199SXin Li 11*9c5db199SXin Liimport six 12*9c5db199SXin Liimport six.moves.configparser 13*9c5db199SXin Liimport socket 14*9c5db199SXin Liimport sys 15*9c5db199SXin Liimport types 16*9c5db199SXin Li 17*9c5db199SXin Liif six.PY3: 18*9c5db199SXin Li import builtins 19*9c5db199SXin Li SOCKET_ERRORS = (builtins.ConnectionError, socket.timeout, socket.gaierror, 20*9c5db199SXin Li socket.herror) 21*9c5db199SXin Li string_types = (str,) 22*9c5db199SXin Li integer_types = (int,) 23*9c5db199SXin Li class_types = (type,) 24*9c5db199SXin Li text_type = str 25*9c5db199SXin Li binary_type = bytes 26*9c5db199SXin Li 27*9c5db199SXin Li MAXSIZE = sys.maxsize 28*9c5db199SXin Lielse: 29*9c5db199SXin Li SOCKET_ERRORS = (socket.error, ) 30*9c5db199SXin Li string_types = (basestring,) 31*9c5db199SXin Li integer_types = (int, long) 32*9c5db199SXin Li class_types = (type, types.ClassType) 33*9c5db199SXin Li text_type = unicode 34*9c5db199SXin Li binary_type = str 35*9c5db199SXin Li 36*9c5db199SXin Li MAXSIZE = float("inf") 37*9c5db199SXin Li 38*9c5db199SXin Li 39*9c5db199SXin Lidef exec_file(filename, globals_, locals_): 40*9c5db199SXin Li """exec_file compiles and runs a file with globals and locals. 41*9c5db199SXin Li 42*9c5db199SXin Li exec_file does not exactly mimic all the edge cases in Python 2's 43*9c5db199SXin Li execfile function. Rather, it does only what is necessary to execute 44*9c5db199SXin Li control files in autotest and prevent compiler-wide settings like 45*9c5db199SXin Li 'from __future__ import ...' from spilling into control files that 46*9c5db199SXin Li have not yet been made Python 3-compatible. 47*9c5db199SXin Li 48*9c5db199SXin Li Arguments: 49*9c5db199SXin Li filename: path to a file 50*9c5db199SXin Li globals_: dictionary of globals 51*9c5db199SXin Li locals_: dictionary of locals 52*9c5db199SXin Li 53*9c5db199SXin Li Returns: 54*9c5db199SXin Li None (output of six.exec_) 55*9c5db199SXin Li """ 56*9c5db199SXin Li with open(filename, "rb") as fh: 57*9c5db199SXin Li code_obj = compile( 58*9c5db199SXin Li fh.read(), 59*9c5db199SXin Li filename, 60*9c5db199SXin Li mode="exec", 61*9c5db199SXin Li flags=0, 62*9c5db199SXin Li dont_inherit=1, 63*9c5db199SXin Li ) 64*9c5db199SXin Li return six.exec_(code_obj, globals_, locals_) 65*9c5db199SXin Li 66*9c5db199SXin Li 67*9c5db199SXin Lidef config_parser(args=None): 68*9c5db199SXin Li """config_parser returns a non-strict config parser. 69*9c5db199SXin Li 70*9c5db199SXin Li Unfortunately, in six configparser is not same between 2/3. For our .ini's 71*9c5db199SXin Li we do not want it to be strict (ie, error upon duplicates). 72*9c5db199SXin Li """ 73*9c5db199SXin Li if six.PY3: 74*9c5db199SXin Li return six.moves.configparser.ConfigParser(args, strict=False) 75*9c5db199SXin Li return six.moves.configparser.ConfigParser(args) 76*9c5db199SXin Li 77*9c5db199SXin Li 78*9c5db199SXin Lidef ensure_text(s, encoding='utf-8', errors='strict'): 79*9c5db199SXin Li """Coerce *s* to six.text_type. Copied from six lib. 80*9c5db199SXin Li 81*9c5db199SXin Li For Python 2: 82*9c5db199SXin Li - `unicode` -> `unicode` 83*9c5db199SXin Li - `str` -> `unicode` 84*9c5db199SXin Li For Python 3: 85*9c5db199SXin Li - `str` -> `str` 86*9c5db199SXin Li - `bytes` -> decoded to `str` 87*9c5db199SXin Li """ 88*9c5db199SXin Li if isinstance(s, binary_type): 89*9c5db199SXin Li return s.decode(encoding, errors) 90*9c5db199SXin Li elif isinstance(s, text_type): 91*9c5db199SXin Li return s 92*9c5db199SXin Li else: 93*9c5db199SXin Li raise TypeError("not expecting type '%s'" % type(s)) 94*9c5db199SXin Li 95*9c5db199SXin Li 96*9c5db199SXin Lidef ensure_long(n): 97*9c5db199SXin Li """ensure_long returns a long if py2, or int if py3.""" 98*9c5db199SXin Li if six.PY2: 99*9c5db199SXin Li return long(n) 100*9c5db199SXin Li return int(n) 101