Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/future/utils/__init__.py: 32%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

295 statements  

1""" 

2A selection of cross-compatible functions for Python 2 and 3. 

3 

4This module exports useful functions for 2/3 compatible code: 

5 

6 * bind_method: binds functions to classes 

7 * ``native_str_to_bytes`` and ``bytes_to_native_str`` 

8 * ``native_str``: always equal to the native platform string object (because 

9 this may be shadowed by imports from future.builtins) 

10 * lists: lrange(), lmap(), lzip(), lfilter() 

11 * iterable method compatibility: 

12 - iteritems, iterkeys, itervalues 

13 - viewitems, viewkeys, viewvalues 

14 

15 These use the original method if available, otherwise they use items, 

16 keys, values. 

17 

18 * types: 

19 

20 * text_type: unicode in Python 2, str in Python 3 

21 * string_types: basestring in Python 2, str in Python 3 

22 * binary_type: str in Python 2, bytes in Python 3 

23 * integer_types: (int, long) in Python 2, int in Python 3 

24 * class_types: (type, types.ClassType) in Python 2, type in Python 3 

25 

26 * bchr(c): 

27 Take an integer and make a 1-character byte string 

28 * bord(c) 

29 Take the result of indexing on a byte string and make an integer 

30 * tobytes(s) 

31 Take a text string, a byte string, or a sequence of characters taken 

32 from a byte string, and make a byte string. 

33 

34 * raise_from() 

35 * raise_with_traceback() 

36 

37This module also defines these decorators: 

38 

39 * ``python_2_unicode_compatible`` 

40 * ``with_metaclass`` 

41 * ``implements_iterator`` 

42 

43Some of the functions in this module come from the following sources: 

44 

45 * Jinja2 (BSD licensed: see 

46 https://github.com/mitsuhiko/jinja2/blob/master/LICENSE) 

47 * Pandas compatibility module pandas.compat 

48 * six.py by Benjamin Peterson 

49 * Django 

50""" 

51 

52import types 

53import sys 

54import numbers 

55import functools 

56import copy 

57import inspect 

58 

59 

60PY3 = sys.version_info[0] >= 3 

61PY34_PLUS = sys.version_info[0:2] >= (3, 4) 

62PY35_PLUS = sys.version_info[0:2] >= (3, 5) 

63PY36_PLUS = sys.version_info[0:2] >= (3, 6) 

64PY37_PLUS = sys.version_info[0:2] >= (3, 7) 

65PY38_PLUS = sys.version_info[0:2] >= (3, 8) 

66PY39_PLUS = sys.version_info[0:2] >= (3, 9) 

67PY2 = sys.version_info[0] == 2 

68PY26 = sys.version_info[0:2] == (2, 6) 

69PY27 = sys.version_info[0:2] == (2, 7) 

70PYPY = hasattr(sys, 'pypy_translation_info') 

71 

72 

73def python_2_unicode_compatible(cls): 

74 """ 

75 A decorator that defines __unicode__ and __str__ methods under Python 

76 2. Under Python 3, this decorator is a no-op. 

77 

78 To support Python 2 and 3 with a single code base, define a __str__ 

79 method returning unicode text and apply this decorator to the class, like 

80 this:: 

81 

82 >>> from future.utils import python_2_unicode_compatible 

83 

84 >>> @python_2_unicode_compatible 

85 ... class MyClass(object): 

86 ... def __str__(self): 

87 ... return u'Unicode string: \u5b54\u5b50' 

88 

89 >>> a = MyClass() 

90 

91 Then, after this import: 

92 

93 >>> from future.builtins import str 

94 

95 the following is ``True`` on both Python 3 and 2:: 

96 

97 >>> str(a) == a.encode('utf-8').decode('utf-8') 

98 True 

99 

100 and, on a Unicode-enabled terminal with the right fonts, these both print the 

101 Chinese characters for Confucius:: 

102 

103 >>> print(a) 

104 >>> print(str(a)) 

105 

106 The implementation comes from django.utils.encoding. 

107 """ 

108 if not PY3: 

109 cls.__unicode__ = cls.__str__ 

110 cls.__str__ = lambda self: self.__unicode__().encode('utf-8') 

111 return cls 

112 

113 

114def with_metaclass(meta, *bases): 

115 """ 

116 Function from jinja2/_compat.py. License: BSD. 

117 

118 Use it like this:: 

119 

120 class BaseForm(object): 

121 pass 

122 

123 class FormType(type): 

124 pass 

125 

126 class Form(with_metaclass(FormType, BaseForm)): 

127 pass 

128 

129 This requires a bit of explanation: the basic idea is to make a 

130 dummy metaclass for one level of class instantiation that replaces 

131 itself with the actual metaclass. Because of internal type checks 

132 we also need to make sure that we downgrade the custom metaclass 

133 for one level to something closer to type (that's why __call__ and 

134 __init__ comes back from type etc.). 

135 

136 This has the advantage over six.with_metaclass of not introducing 

137 dummy classes into the final MRO. 

138 """ 

139 class metaclass(meta): 

140 __call__ = type.__call__ 

141 __init__ = type.__init__ 

142 def __new__(cls, name, this_bases, d): 

143 if this_bases is None: 

144 return type.__new__(cls, name, (), d) 

145 return meta(name, bases, d) 

146 return metaclass('temporary_class', None, {}) 

147 

148 

149# Definitions from pandas.compat and six.py follow: 

150if PY3: 

151 def bchr(s): 

152 return bytes([s]) 

153 def bstr(s): 

154 if isinstance(s, str): 

155 return bytes(s, 'latin-1') 

156 else: 

157 return bytes(s) 

158 def bord(s): 

159 return s 

160 

161 string_types = str, 

162 integer_types = int, 

163 class_types = type, 

164 text_type = str 

165 binary_type = bytes 

166 

167else: 

168 # Python 2 

169 def bchr(s): 

170 return chr(s) 

171 def bstr(s): 

172 return str(s) 

173 def bord(s): 

174 return ord(s) 

175 

176 string_types = basestring, 

177 integer_types = (int, long) 

178 class_types = (type, types.ClassType) 

179 text_type = unicode 

180 binary_type = str 

181 

182### 

183 

184if PY3: 

185 def tobytes(s): 

186 if isinstance(s, bytes): 

187 return s 

188 else: 

189 if isinstance(s, str): 

190 return s.encode('latin-1') 

191 else: 

192 return bytes(s) 

193else: 

194 # Python 2 

195 def tobytes(s): 

196 if isinstance(s, unicode): 

197 return s.encode('latin-1') 

198 else: 

199 return ''.join(s) 

200 

201tobytes.__doc__ = """ 

202 Encodes to latin-1 (where the first 256 chars are the same as 

203 ASCII.) 

204 """ 

205 

206if PY3: 

207 def native_str_to_bytes(s, encoding='utf-8'): 

208 return s.encode(encoding) 

209 

210 def bytes_to_native_str(b, encoding='utf-8'): 

211 return b.decode(encoding) 

212 

213 def text_to_native_str(t, encoding=None): 

214 return t 

215else: 

216 # Python 2 

217 def native_str_to_bytes(s, encoding=None): 

218 from future.types import newbytes # to avoid a circular import 

219 return newbytes(s) 

220 

221 def bytes_to_native_str(b, encoding=None): 

222 return native(b) 

223 

224 def text_to_native_str(t, encoding='ascii'): 

225 """ 

226 Use this to create a Py2 native string when "from __future__ import 

227 unicode_literals" is in effect. 

228 """ 

229 return unicode(t).encode(encoding) 

230 

231native_str_to_bytes.__doc__ = """ 

232 On Py3, returns an encoded string. 

233 On Py2, returns a newbytes type, ignoring the ``encoding`` argument. 

234 """ 

235 

236if PY3: 

237 # list-producing versions of the major Python iterating functions 

238 def lrange(*args, **kwargs): 

239 return list(range(*args, **kwargs)) 

240 

241 def lzip(*args, **kwargs): 

242 return list(zip(*args, **kwargs)) 

243 

244 def lmap(*args, **kwargs): 

245 return list(map(*args, **kwargs)) 

246 

247 def lfilter(*args, **kwargs): 

248 return list(filter(*args, **kwargs)) 

249else: 

250 import __builtin__ 

251 # Python 2-builtin ranges produce lists 

252 lrange = __builtin__.range 

253 lzip = __builtin__.zip 

254 lmap = __builtin__.map 

255 lfilter = __builtin__.filter 

256 

257 

258def isidentifier(s, dotted=False): 

259 ''' 

260 A function equivalent to the str.isidentifier method on Py3 

261 ''' 

262 if dotted: 

263 return all(isidentifier(a) for a in s.split('.')) 

264 if PY3: 

265 return s.isidentifier() 

266 else: 

267 import re 

268 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$") 

269 return bool(_name_re.match(s)) 

270 

271 

272def viewitems(obj, **kwargs): 

273 """ 

274 Function for iterating over dictionary items with the same set-like 

275 behaviour on Py2.7 as on Py3. 

276 

277 Passes kwargs to method.""" 

278 func = getattr(obj, "viewitems", None) 

279 if not func: 

280 func = obj.items 

281 return func(**kwargs) 

282 

283 

284def viewkeys(obj, **kwargs): 

285 """ 

286 Function for iterating over dictionary keys with the same set-like 

287 behaviour on Py2.7 as on Py3. 

288 

289 Passes kwargs to method.""" 

290 func = getattr(obj, "viewkeys", None) 

291 if not func: 

292 func = obj.keys 

293 return func(**kwargs) 

294 

295 

296def viewvalues(obj, **kwargs): 

297 """ 

298 Function for iterating over dictionary values with the same set-like 

299 behaviour on Py2.7 as on Py3. 

300 

301 Passes kwargs to method.""" 

302 func = getattr(obj, "viewvalues", None) 

303 if not func: 

304 func = obj.values 

305 return func(**kwargs) 

306 

307 

308def iteritems(obj, **kwargs): 

309 """Use this only if compatibility with Python versions before 2.7 is 

310 required. Otherwise, prefer viewitems(). 

311 """ 

312 func = getattr(obj, "iteritems", None) 

313 if not func: 

314 func = obj.items 

315 return func(**kwargs) 

316 

317 

318def iterkeys(obj, **kwargs): 

319 """Use this only if compatibility with Python versions before 2.7 is 

320 required. Otherwise, prefer viewkeys(). 

321 """ 

322 func = getattr(obj, "iterkeys", None) 

323 if not func: 

324 func = obj.keys 

325 return func(**kwargs) 

326 

327 

328def itervalues(obj, **kwargs): 

329 """Use this only if compatibility with Python versions before 2.7 is 

330 required. Otherwise, prefer viewvalues(). 

331 """ 

332 func = getattr(obj, "itervalues", None) 

333 if not func: 

334 func = obj.values 

335 return func(**kwargs) 

336 

337 

338def bind_method(cls, name, func): 

339 """Bind a method to class, python 2 and python 3 compatible. 

340 

341 Parameters 

342 ---------- 

343 

344 cls : type 

345 class to receive bound method 

346 name : basestring 

347 name of method on class instance 

348 func : function 

349 function to be bound as method 

350 

351 Returns 

352 ------- 

353 None 

354 """ 

355 # only python 2 has an issue with bound/unbound methods 

356 if not PY3: 

357 setattr(cls, name, types.MethodType(func, None, cls)) 

358 else: 

359 setattr(cls, name, func) 

360 

361 

362def getexception(): 

363 return sys.exc_info()[1] 

364 

365 

366def _get_caller_globals_and_locals(): 

367 """ 

368 Returns the globals and locals of the calling frame. 

369 

370 Is there an alternative to frame hacking here? 

371 """ 

372 caller_frame = inspect.stack()[2] 

373 myglobals = caller_frame[0].f_globals 

374 mylocals = caller_frame[0].f_locals 

375 return myglobals, mylocals 

376 

377 

378def _repr_strip(mystring): 

379 """ 

380 Returns the string without any initial or final quotes. 

381 """ 

382 r = repr(mystring) 

383 if r.startswith("'") and r.endswith("'"): 

384 return r[1:-1] 

385 else: 

386 return r 

387 

388 

389if PY3: 

390 def raise_from(exc, cause): 

391 """ 

392 Equivalent to: 

393 

394 raise EXCEPTION from CAUSE 

395 

396 on Python 3. (See PEP 3134). 

397 """ 

398 myglobals, mylocals = _get_caller_globals_and_locals() 

399 

400 # We pass the exception and cause along with other globals 

401 # when we exec(): 

402 myglobals = myglobals.copy() 

403 myglobals['__python_future_raise_from_exc'] = exc 

404 myglobals['__python_future_raise_from_cause'] = cause 

405 execstr = "raise __python_future_raise_from_exc from __python_future_raise_from_cause" 

406 exec(execstr, myglobals, mylocals) 

407 

408 def raise_(tp, value=None, tb=None): 

409 """ 

410 A function that matches the Python 2.x ``raise`` statement. This 

411 allows re-raising exceptions with the cls value and traceback on 

412 Python 2 and 3. 

413 """ 

414 if isinstance(tp, BaseException): 

415 # If the first object is an instance, the type of the exception 

416 # is the class of the instance, the instance itself is the value, 

417 # and the second object must be None. 

418 if value is not None: 

419 raise TypeError("instance exception may not have a separate value") 

420 exc = tp 

421 elif isinstance(tp, type) and not issubclass(tp, BaseException): 

422 # If the first object is a class, it becomes the type of the 

423 # exception. 

424 raise TypeError("class must derive from BaseException, not %s" % tp.__name__) 

425 else: 

426 # The second object is used to determine the exception value: If it 

427 # is an instance of the class, the instance becomes the exception 

428 # value. If the second object is a tuple, it is used as the argument 

429 # list for the class constructor; if it is None, an empty argument 

430 # list is used, and any other object is treated as a single argument 

431 # to the constructor. The instance so created by calling the 

432 # constructor is used as the exception value. 

433 if isinstance(value, tp): 

434 exc = value 

435 elif isinstance(value, tuple): 

436 exc = tp(*value) 

437 elif value is None: 

438 exc = tp() 

439 else: 

440 exc = tp(value) 

441 

442 if exc.__traceback__ is not tb: 

443 raise exc.with_traceback(tb) 

444 raise exc 

445 

446 def raise_with_traceback(exc, traceback=Ellipsis): 

447 if traceback == Ellipsis: 

448 _, _, traceback = sys.exc_info() 

449 raise exc.with_traceback(traceback) 

450 

451else: 

452 def raise_from(exc, cause): 

453 """ 

454 Equivalent to: 

455 

456 raise EXCEPTION from CAUSE 

457 

458 on Python 3. (See PEP 3134). 

459 """ 

460 # Is either arg an exception class (e.g. IndexError) rather than 

461 # instance (e.g. IndexError('my message here')? If so, pass the 

462 # name of the class undisturbed through to "raise ... from ...". 

463 if isinstance(exc, type) and issubclass(exc, Exception): 

464 e = exc() 

465 # exc = exc.__name__ 

466 # execstr = "e = " + _repr_strip(exc) + "()" 

467 # myglobals, mylocals = _get_caller_globals_and_locals() 

468 # exec(execstr, myglobals, mylocals) 

469 else: 

470 e = exc 

471 e.__suppress_context__ = False 

472 if isinstance(cause, type) and issubclass(cause, Exception): 

473 e.__cause__ = cause() 

474 e.__cause__.__traceback__ = sys.exc_info()[2] 

475 e.__suppress_context__ = True 

476 elif cause is None: 

477 e.__cause__ = None 

478 e.__suppress_context__ = True 

479 elif isinstance(cause, BaseException): 

480 e.__cause__ = cause 

481 object.__setattr__(e.__cause__, '__traceback__', sys.exc_info()[2]) 

482 e.__suppress_context__ = True 

483 else: 

484 raise TypeError("exception causes must derive from BaseException") 

485 e.__context__ = sys.exc_info()[1] 

486 raise e 

487 

488 exec(''' 

489def raise_(tp, value=None, tb=None): 

490 raise tp, value, tb 

491 

492def raise_with_traceback(exc, traceback=Ellipsis): 

493 if traceback == Ellipsis: 

494 _, _, traceback = sys.exc_info() 

495 raise exc, None, traceback 

496'''.strip()) 

497 

498 

499raise_with_traceback.__doc__ = ( 

500"""Raise exception with existing traceback. 

501If traceback is not passed, uses sys.exc_info() to get traceback.""" 

502) 

503 

504 

505# Deprecated alias for backward compatibility with ``future`` versions < 0.11: 

506reraise = raise_ 

507 

508 

509def implements_iterator(cls): 

510 ''' 

511 From jinja2/_compat.py. License: BSD. 

512 

513 Use as a decorator like this:: 

514 

515 @implements_iterator 

516 class UppercasingIterator(object): 

517 def __init__(self, iterable): 

518 self._iter = iter(iterable) 

519 def __iter__(self): 

520 return self 

521 def __next__(self): 

522 return next(self._iter).upper() 

523 

524 ''' 

525 if PY3: 

526 return cls 

527 else: 

528 cls.next = cls.__next__ 

529 del cls.__next__ 

530 return cls 

531 

532if PY3: 

533 get_next = lambda x: x.__next__ 

534else: 

535 get_next = lambda x: x.next 

536 

537 

538def encode_filename(filename): 

539 if PY3: 

540 return filename 

541 else: 

542 if isinstance(filename, unicode): 

543 return filename.encode('utf-8') 

544 return filename 

545 

546 

547def is_new_style(cls): 

548 """ 

549 Python 2.7 has both new-style and old-style classes. Old-style classes can 

550 be pesky in some circumstances, such as when using inheritance. Use this 

551 function to test for whether a class is new-style. (Python 3 only has 

552 new-style classes.) 

553 """ 

554 return hasattr(cls, '__class__') and ('__dict__' in dir(cls) 

555 or hasattr(cls, '__slots__')) 

556 

557# The native platform string and bytes types. Useful because ``str`` and 

558# ``bytes`` are redefined on Py2 by ``from future.builtins import *``. 

559native_str = str 

560native_bytes = bytes 

561 

562 

563def istext(obj): 

564 """ 

565 Deprecated. Use:: 

566 >>> isinstance(obj, str) 

567 after this import: 

568 >>> from future.builtins import str 

569 """ 

570 return isinstance(obj, type(u'')) 

571 

572 

573def isbytes(obj): 

574 """ 

575 Deprecated. Use:: 

576 >>> isinstance(obj, bytes) 

577 after this import: 

578 >>> from future.builtins import bytes 

579 """ 

580 return isinstance(obj, type(b'')) 

581 

582 

583def isnewbytes(obj): 

584 """ 

585 Equivalent to the result of ``type(obj) == type(newbytes)`` 

586 in other words, it is REALLY a newbytes instance, not a Py2 native str 

587 object? 

588 

589 Note that this does not cover subclasses of newbytes, and it is not 

590 equivalent to ininstance(obj, newbytes) 

591 """ 

592 return type(obj).__name__ == 'newbytes' 

593 

594 

595def isint(obj): 

596 """ 

597 Deprecated. Tests whether an object is a Py3 ``int`` or either a Py2 ``int`` or 

598 ``long``. 

599 

600 Instead of using this function, you can use: 

601 

602 >>> from future.builtins import int 

603 >>> isinstance(obj, int) 

604 

605 The following idiom is equivalent: 

606 

607 >>> from numbers import Integral 

608 >>> isinstance(obj, Integral) 

609 """ 

610 

611 return isinstance(obj, numbers.Integral) 

612 

613 

614def native(obj): 

615 """ 

616 On Py3, this is a no-op: native(obj) -> obj 

617 

618 On Py2, returns the corresponding native Py2 types that are 

619 superclasses for backported objects from Py3: 

620 

621 >>> from builtins import str, bytes, int 

622 

623 >>> native(str(u'ABC')) 

624 u'ABC' 

625 >>> type(native(str(u'ABC'))) 

626 unicode 

627 

628 >>> native(bytes(b'ABC')) 

629 b'ABC' 

630 >>> type(native(bytes(b'ABC'))) 

631 bytes 

632 

633 >>> native(int(10**20)) 

634 100000000000000000000L 

635 >>> type(native(int(10**20))) 

636 long 

637 

638 Existing native types on Py2 will be returned unchanged: 

639 

640 >>> type(native(u'ABC')) 

641 unicode 

642 """ 

643 if hasattr(obj, '__native__'): 

644 return obj.__native__() 

645 else: 

646 return obj 

647 

648 

649# Implementation of exec_ is from ``six``: 

650if PY3: 

651 import builtins 

652 exec_ = getattr(builtins, "exec") 

653else: 

654 def exec_(code, globs=None, locs=None): 

655 """Execute code in a namespace.""" 

656 if globs is None: 

657 frame = sys._getframe(1) 

658 globs = frame.f_globals 

659 if locs is None: 

660 locs = frame.f_locals 

661 del frame 

662 elif locs is None: 

663 locs = globs 

664 exec("""exec code in globs, locs""") 

665 

666 

667# Defined here for backward compatibility: 

668def old_div(a, b): 

669 """ 

670 DEPRECATED: import ``old_div`` from ``past.utils`` instead. 

671 

672 Equivalent to ``a / b`` on Python 2 without ``from __future__ import 

673 division``. 

674 

675 TODO: generalize this to other objects (like arrays etc.) 

676 """ 

677 if isinstance(a, numbers.Integral) and isinstance(b, numbers.Integral): 

678 return a // b 

679 else: 

680 return a / b 

681 

682 

683def as_native_str(encoding='utf-8'): 

684 ''' 

685 A decorator to turn a function or method call that returns text, i.e. 

686 unicode, into one that returns a native platform str. 

687 

688 Use it as a decorator like this:: 

689 

690 from __future__ import unicode_literals 

691 

692 class MyClass(object): 

693 @as_native_str(encoding='ascii') 

694 def __repr__(self): 

695 return next(self._iter).upper() 

696 ''' 

697 if PY3: 

698 return lambda f: f 

699 else: 

700 def encoder(f): 

701 @functools.wraps(f) 

702 def wrapper(*args, **kwargs): 

703 return f(*args, **kwargs).encode(encoding=encoding) 

704 return wrapper 

705 return encoder 

706 

707# listvalues and listitems definitions from Nick Coghlan's (withdrawn) 

708# PEP 496: 

709try: 

710 dict.iteritems 

711except AttributeError: 

712 # Python 3 

713 def listvalues(d): 

714 return list(d.values()) 

715 def listitems(d): 

716 return list(d.items()) 

717else: 

718 # Python 2 

719 def listvalues(d): 

720 return d.values() 

721 def listitems(d): 

722 return d.items() 

723 

724if PY3: 

725 def ensure_new_type(obj): 

726 return obj 

727else: 

728 def ensure_new_type(obj): 

729 from future.types.newbytes import newbytes 

730 from future.types.newstr import newstr 

731 from future.types.newint import newint 

732 from future.types.newdict import newdict 

733 

734 native_type = type(native(obj)) 

735 

736 # Upcast only if the type is already a native (non-future) type 

737 if issubclass(native_type, type(obj)): 

738 # Upcast 

739 if native_type == str: # i.e. Py2 8-bit str 

740 return newbytes(obj) 

741 elif native_type == unicode: 

742 return newstr(obj) 

743 elif native_type == int: 

744 return newint(obj) 

745 elif native_type == long: 

746 return newint(obj) 

747 elif native_type == dict: 

748 return newdict(obj) 

749 else: 

750 return obj 

751 else: 

752 # Already a new type 

753 assert type(obj) in [newbytes, newstr] 

754 return obj 

755 

756 

757__all__ = ['PY2', 'PY26', 'PY3', 'PYPY', 

758 'as_native_str', 'binary_type', 'bind_method', 'bord', 'bstr', 

759 'bytes_to_native_str', 'class_types', 'encode_filename', 

760 'ensure_new_type', 'exec_', 'get_next', 'getexception', 

761 'implements_iterator', 'integer_types', 'is_new_style', 'isbytes', 

762 'isidentifier', 'isint', 'isnewbytes', 'istext', 'iteritems', 

763 'iterkeys', 'itervalues', 'lfilter', 'listitems', 'listvalues', 

764 'lmap', 'lrange', 'lzip', 'native', 'native_bytes', 'native_str', 

765 'native_str_to_bytes', 'old_div', 

766 'python_2_unicode_compatible', 'raise_', 

767 'raise_with_traceback', 'reraise', 'string_types', 

768 'text_to_native_str', 'text_type', 'tobytes', 'viewitems', 

769 'viewkeys', 'viewvalues', 'with_metaclass' 

770 ]