1- # Copyright (c) 2010-2018 Benjamin Peterson
1+ # Copyright (c) 2010-2020 Benjamin Peterson
22#
33# Permission is hereby granted, free of charge, to any person obtaining a copy
44# of this software and associated documentation files (the "Software"), to deal
2929import types
3030
3131__author__ = "Benjamin Peterson <[email protected] >" 32- __version__ = "1.12 .0"
32+ __version__ = "1.15 .0"
3333
3434
3535# Useful for very coarse version differentiation.
@@ -255,9 +255,11 @@ class _MovedItems(_LazyModule):
255255 MovedAttribute ("zip_longest" , "itertools" , "itertools" , "izip_longest" , "zip_longest" ),
256256 MovedModule ("builtins" , "__builtin__" ),
257257 MovedModule ("configparser" , "ConfigParser" ),
258+ MovedModule ("collections_abc" , "collections" , "collections.abc" if sys .version_info >= (3 , 3 ) else "collections" ),
258259 MovedModule ("copyreg" , "copy_reg" ),
259260 MovedModule ("dbm_gnu" , "gdbm" , "dbm.gnu" ),
260- MovedModule ("_dummy_thread" , "dummy_thread" , "_dummy_thread" ),
261+ MovedModule ("dbm_ndbm" , "dbm" , "dbm.ndbm" ),
262+ MovedModule ("_dummy_thread" , "dummy_thread" , "_dummy_thread" if sys .version_info < (3 , 9 ) else "_thread" ),
261263 MovedModule ("http_cookiejar" , "cookielib" , "http.cookiejar" ),
262264 MovedModule ("http_cookies" , "Cookie" , "http.cookies" ),
263265 MovedModule ("html_entities" , "htmlentitydefs" , "html.entities" ),
@@ -637,13 +639,16 @@ def u(s):
637639 import io
638640 StringIO = io .StringIO
639641 BytesIO = io .BytesIO
642+ del io
640643 _assertCountEqual = "assertCountEqual"
641644 if sys .version_info [1 ] <= 1 :
642645 _assertRaisesRegex = "assertRaisesRegexp"
643646 _assertRegex = "assertRegexpMatches"
647+ _assertNotRegex = "assertNotRegexpMatches"
644648 else :
645649 _assertRaisesRegex = "assertRaisesRegex"
646650 _assertRegex = "assertRegex"
651+ _assertNotRegex = "assertNotRegex"
647652else :
648653 def b (s ):
649654 return s
@@ -665,6 +670,7 @@ def indexbytes(buf, i):
665670 _assertCountEqual = "assertItemsEqual"
666671 _assertRaisesRegex = "assertRaisesRegexp"
667672 _assertRegex = "assertRegexpMatches"
673+ _assertNotRegex = "assertNotRegexpMatches"
668674_add_doc (b , """Byte literal""" )
669675_add_doc (u , """Text literal""" )
670676
@@ -681,6 +687,10 @@ def assertRegex(self, *args, **kwargs):
681687 return getattr (self , _assertRegex )(* args , ** kwargs )
682688
683689
690+ def assertNotRegex (self , * args , ** kwargs ):
691+ return getattr (self , _assertNotRegex )(* args , ** kwargs )
692+
693+
684694if PY3 :
685695 exec_ = getattr (moves .builtins , "exec" )
686696
@@ -716,16 +726,7 @@ def exec_(_code_, _globs_=None, _locs_=None):
716726""" )
717727
718728
719- if sys .version_info [:2 ] == (3 , 2 ):
720- exec_ ("""def raise_from(value, from_value):
721- try:
722- if from_value is None:
723- raise value
724- raise value from from_value
725- finally:
726- value = None
727- """ )
728- elif sys .version_info [:2 ] > (3 , 2 ):
729+ if sys .version_info [:2 ] > (3 ,):
729730 exec_ ("""def raise_from(value, from_value):
730731 try:
731732 raise value from from_value
@@ -805,13 +806,33 @@ def print_(*args, **kwargs):
805806_add_doc (reraise , """Reraise an exception.""" )
806807
807808if sys .version_info [0 :2 ] < (3 , 4 ):
809+ # This does exactly the same what the :func:`py3:functools.update_wrapper`
810+ # function does on Python versions after 3.2. It sets the ``__wrapped__``
811+ # attribute on ``wrapper`` object and it doesn't raise an error if any of
812+ # the attributes mentioned in ``assigned`` and ``updated`` are missing on
813+ # ``wrapped`` object.
814+ def _update_wrapper (wrapper , wrapped ,
815+ assigned = functools .WRAPPER_ASSIGNMENTS ,
816+ updated = functools .WRAPPER_UPDATES ):
817+ for attr in assigned :
818+ try :
819+ value = getattr (wrapped , attr )
820+ except AttributeError :
821+ continue
822+ else :
823+ setattr (wrapper , attr , value )
824+ for attr in updated :
825+ getattr (wrapper , attr ).update (getattr (wrapped , attr , {}))
826+ wrapper .__wrapped__ = wrapped
827+ return wrapper
828+ _update_wrapper .__doc__ = functools .update_wrapper .__doc__
829+
808830 def wraps (wrapped , assigned = functools .WRAPPER_ASSIGNMENTS ,
809831 updated = functools .WRAPPER_UPDATES ):
810- def wrapper (f ):
811- f = functools .wraps (wrapped , assigned , updated )(f )
812- f .__wrapped__ = wrapped
813- return f
814- return wrapper
832+ return functools .partial (_update_wrapper , wrapped = wrapped ,
833+ assigned = assigned , updated = updated )
834+ wraps .__doc__ = functools .wraps .__doc__
835+
815836else :
816837 wraps = functools .wraps
817838
@@ -824,7 +845,15 @@ def with_metaclass(meta, *bases):
824845 class metaclass (type ):
825846
826847 def __new__ (cls , name , this_bases , d ):
827- return meta (name , bases , d )
848+ if sys .version_info [:2 ] >= (3 , 7 ):
849+ # This version introduced PEP 560 that requires a bit
850+ # of extra care (we mimic what is done by __build_class__).
851+ resolved_bases = types .resolve_bases (bases )
852+ if resolved_bases is not bases :
853+ d ['__orig_bases__' ] = bases
854+ else :
855+ resolved_bases = bases
856+ return meta (name , resolved_bases , d )
828857
829858 @classmethod
830859 def __prepare__ (cls , name , this_bases ):
@@ -861,12 +890,11 @@ def ensure_binary(s, encoding='utf-8', errors='strict'):
861890 - `str` -> encoded to `bytes`
862891 - `bytes` -> `bytes`
863892 """
893+ if isinstance (s , binary_type ):
894+ return s
864895 if isinstance (s , text_type ):
865896 return s .encode (encoding , errors )
866- elif isinstance (s , binary_type ):
867- return s
868- else :
869- raise TypeError ("not expecting type '%s'" % type (s ))
897+ raise TypeError ("not expecting type '%s'" % type (s ))
870898
871899
872900def ensure_str (s , encoding = 'utf-8' , errors = 'strict' ):
@@ -880,12 +908,15 @@ def ensure_str(s, encoding='utf-8', errors='strict'):
880908 - `str` -> `str`
881909 - `bytes` -> decoded to `str`
882910 """
883- if not isinstance (s , (text_type , binary_type )):
884- raise TypeError ("not expecting type '%s'" % type (s ))
911+ # Optimization: Fast return for the common case.
912+ if type (s ) is str :
913+ return s
885914 if PY2 and isinstance (s , text_type ):
886- s = s .encode (encoding , errors )
915+ return s .encode (encoding , errors )
887916 elif PY3 and isinstance (s , binary_type ):
888- s = s .decode (encoding , errors )
917+ return s .decode (encoding , errors )
918+ elif not isinstance (s , (text_type , binary_type )):
919+ raise TypeError ("not expecting type '%s'" % type (s ))
889920 return s
890921
891922
@@ -908,10 +939,9 @@ def ensure_text(s, encoding='utf-8', errors='strict'):
908939 raise TypeError ("not expecting type '%s'" % type (s ))
909940
910941
911-
912942def python_2_unicode_compatible (klass ):
913943 """
914- A decorator that defines __unicode__ and __str__ methods under Python 2.
944+ A class decorator that defines __unicode__ and __str__ methods under Python 2.
915945 Under Python 3 it does nothing.
916946
917947 To support Python 2 and 3 with a single code base, define a __str__ method
0 commit comments