1
1
"""Utilities for writing code that runs on Python 2 and 3"""
2
2
3
- # Copyright (c) 2010-2015 Benjamin Peterson
3
+ # Copyright (c) 2010-2018 Benjamin Peterson
4
4
#
5
5
# Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
# of this software and associated documentation files (the "Software"), to deal
29
29
import types
30
30
31
31
__author__ = "Benjamin Peterson <[email protected] >"
32
- __version__ = "1.9 .0"
32
+ __version__ = "1.12 .0"
33
33
34
34
35
35
# Useful for very coarse version differentiation.
@@ -165,7 +165,6 @@ class _SixMetaPathImporter(object):
165
165
166
166
"""
167
167
A meta path importer to import six.moves and its submodules.
168
-
169
168
This class implements a PEP302 finder and loader. It should be compatible
170
169
with Python 2.5 and all existing versions of Python3
171
170
"""
@@ -209,15 +208,13 @@ def load_module(self, fullname):
209
208
def is_package (self , fullname ):
210
209
"""
211
210
Return true, if the named module is a package.
212
-
213
211
We need this method to get correct spec objects with
214
212
Python 3.4 (see PEP451)
215
213
"""
216
214
return hasattr (self .__get_module (fullname ), "__path__" )
217
215
218
216
def get_code (self , fullname ):
219
217
"""Return None
220
-
221
218
Required, if is_package is implemented"""
222
219
self .__get_module (fullname ) # eventually raises ImportError
223
220
return None
@@ -241,6 +238,7 @@ class _MovedItems(_LazyModule):
241
238
MovedAttribute ("map" , "itertools" , "builtins" , "imap" , "map" ),
242
239
MovedAttribute ("getcwd" , "os" , "os" , "getcwdu" , "getcwd" ),
243
240
MovedAttribute ("getcwdb" , "os" , "os" , "getcwd" , "getcwdb" ),
241
+ MovedAttribute ("getoutput" , "commands" , "subprocess" ),
244
242
MovedAttribute ("range" , "__builtin__" , "builtins" , "xrange" , "range" ),
245
243
MovedAttribute ("reload_module" , "__builtin__" , "importlib" if PY34 else "imp" , "reload" ),
246
244
MovedAttribute ("reduce" , "__builtin__" , "functools" ),
@@ -262,10 +260,11 @@ class _MovedItems(_LazyModule):
262
260
MovedModule ("html_entities" , "htmlentitydefs" , "html.entities" ),
263
261
MovedModule ("html_parser" , "HTMLParser" , "html.parser" ),
264
262
MovedModule ("http_client" , "httplib" , "http.client" ),
263
+ MovedModule ("email_mime_base" , "email.MIMEBase" , "email.mime.base" ),
264
+ MovedModule ("email_mime_image" , "email.MIMEImage" , "email.mime.image" ),
265
265
MovedModule ("email_mime_multipart" , "email.MIMEMultipart" , "email.mime.multipart" ),
266
266
MovedModule ("email_mime_nonmultipart" , "email.MIMENonMultipart" , "email.mime.nonmultipart" ),
267
267
MovedModule ("email_mime_text" , "email.MIMEText" , "email.mime.text" ),
268
- MovedModule ("email_mime_base" , "email.MIMEBase" , "email.mime.base" ),
269
268
MovedModule ("BaseHTTPServer" , "BaseHTTPServer" , "http.server" ),
270
269
MovedModule ("CGIHTTPServer" , "CGIHTTPServer" , "http.server" ),
271
270
MovedModule ("SimpleHTTPServer" , "SimpleHTTPServer" , "http.server" ),
@@ -337,10 +336,12 @@ class Module_six_moves_urllib_parse(_LazyModule):
337
336
MovedAttribute ("quote_plus" , "urllib" , "urllib.parse" ),
338
337
MovedAttribute ("unquote" , "urllib" , "urllib.parse" ),
339
338
MovedAttribute ("unquote_plus" , "urllib" , "urllib.parse" ),
339
+ MovedAttribute ("unquote_to_bytes" , "urllib" , "urllib.parse" , "unquote" , "unquote_to_bytes" ),
340
340
MovedAttribute ("urlencode" , "urllib" , "urllib.parse" ),
341
341
MovedAttribute ("splitquery" , "urllib" , "urllib.parse" ),
342
342
MovedAttribute ("splittag" , "urllib" , "urllib.parse" ),
343
343
MovedAttribute ("splituser" , "urllib" , "urllib.parse" ),
344
+ MovedAttribute ("splitvalue" , "urllib" , "urllib.parse" ),
344
345
MovedAttribute ("uses_fragment" , "urlparse" , "urllib.parse" ),
345
346
MovedAttribute ("uses_netloc" , "urlparse" , "urllib.parse" ),
346
347
MovedAttribute ("uses_params" , "urlparse" , "urllib.parse" ),
@@ -416,6 +417,8 @@ class Module_six_moves_urllib_request(_LazyModule):
416
417
MovedAttribute ("URLopener" , "urllib" , "urllib.request" ),
417
418
MovedAttribute ("FancyURLopener" , "urllib" , "urllib.request" ),
418
419
MovedAttribute ("proxy_bypass" , "urllib" , "urllib.request" ),
420
+ MovedAttribute ("parse_http_list" , "urllib2" , "urllib.request" ),
421
+ MovedAttribute ("parse_keqv_list" , "urllib2" , "urllib.request" ),
419
422
]
420
423
for attr in _urllib_request_moved_attributes :
421
424
setattr (Module_six_moves_urllib_request , attr .name , attr )
@@ -679,11 +682,15 @@ def assertRegex(self, *args, **kwargs):
679
682
exec_ = getattr (moves .builtins , "exec" )
680
683
681
684
def reraise (tp , value , tb = None ):
682
- if value is None :
683
- value = tp ()
684
- if value .__traceback__ is not tb :
685
- raise value .with_traceback (tb )
686
- raise value
685
+ try :
686
+ if value is None :
687
+ value = tp ()
688
+ if value .__traceback__ is not tb :
689
+ raise value .with_traceback (tb )
690
+ raise value
691
+ finally :
692
+ value = None
693
+ tb = None
687
694
688
695
else :
689
696
def exec_ (_code_ , _globs_ = None , _locs_ = None ):
@@ -699,19 +706,28 @@ def exec_(_code_, _globs_=None, _locs_=None):
699
706
exec ("""exec _code_ in _globs_, _locs_""" )
700
707
701
708
exec_ ("""def reraise(tp, value, tb=None):
702
- raise tp, value, tb
709
+ try:
710
+ raise tp, value, tb
711
+ finally:
712
+ tb = None
703
713
""" )
704
714
705
715
706
716
if sys .version_info [:2 ] == (3 , 2 ):
707
717
exec_ ("""def raise_from(value, from_value):
708
- if from_value is None:
709
- raise value
710
- raise value from from_value
718
+ try:
719
+ if from_value is None:
720
+ raise value
721
+ raise value from from_value
722
+ finally:
723
+ value = None
711
724
""" )
712
725
elif sys .version_info [:2 ] > (3 , 2 ):
713
726
exec_ ("""def raise_from(value, from_value):
714
- raise value from from_value
727
+ try:
728
+ raise value from from_value
729
+ finally:
730
+ value = None
715
731
""" )
716
732
else :
717
733
def raise_from (value , from_value ):
@@ -802,10 +818,14 @@ def with_metaclass(meta, *bases):
802
818
# This requires a bit of explanation: the basic idea is to make a dummy
803
819
# metaclass for one level of class instantiation that replaces itself with
804
820
# the actual metaclass.
805
- class metaclass (meta ):
821
+ class metaclass (type ):
806
822
807
823
def __new__ (cls , name , this_bases , d ):
808
824
return meta (name , bases , d )
825
+
826
+ @classmethod
827
+ def __prepare__ (cls , name , this_bases ):
828
+ return meta .__prepare__ (name , bases )
809
829
return type .__new__ (metaclass , 'temporary_class' , (), {})
810
830
811
831
@@ -821,15 +841,69 @@ def wrapper(cls):
821
841
orig_vars .pop (slots_var )
822
842
orig_vars .pop ('__dict__' , None )
823
843
orig_vars .pop ('__weakref__' , None )
844
+ if hasattr (cls , '__qualname__' ):
845
+ orig_vars ['__qualname__' ] = cls .__qualname__
824
846
return metaclass (cls .__name__ , cls .__bases__ , orig_vars )
825
847
return wrapper
826
848
827
849
850
+ def ensure_binary (s , encoding = 'utf-8' , errors = 'strict' ):
851
+ """Coerce **s** to six.binary_type.
852
+ For Python 2:
853
+ - `unicode` -> encoded to `str`
854
+ - `str` -> `str`
855
+ For Python 3:
856
+ - `str` -> encoded to `bytes`
857
+ - `bytes` -> `bytes`
858
+ """
859
+ if isinstance (s , text_type ):
860
+ return s .encode (encoding , errors )
861
+ elif isinstance (s , binary_type ):
862
+ return s
863
+ else :
864
+ raise TypeError ("not expecting type '%s'" % type (s ))
865
+
866
+
867
+ def ensure_str (s , encoding = 'utf-8' , errors = 'strict' ):
868
+ """Coerce *s* to `str`.
869
+ For Python 2:
870
+ - `unicode` -> encoded to `str`
871
+ - `str` -> `str`
872
+ For Python 3:
873
+ - `str` -> `str`
874
+ - `bytes` -> decoded to `str`
875
+ """
876
+ if not isinstance (s , (text_type , binary_type )):
877
+ raise TypeError ("not expecting type '%s'" % type (s ))
878
+ if PY2 and isinstance (s , text_type ):
879
+ s = s .encode (encoding , errors )
880
+ elif PY3 and isinstance (s , binary_type ):
881
+ s = s .decode (encoding , errors )
882
+ return s
883
+
884
+
885
+ def ensure_text (s , encoding = 'utf-8' , errors = 'strict' ):
886
+ """Coerce *s* to six.text_type.
887
+ For Python 2:
888
+ - `unicode` -> `unicode`
889
+ - `str` -> `unicode`
890
+ For Python 3:
891
+ - `str` -> `str`
892
+ - `bytes` -> decoded to `str`
893
+ """
894
+ if isinstance (s , binary_type ):
895
+ return s .decode (encoding , errors )
896
+ elif isinstance (s , text_type ):
897
+ return s
898
+ else :
899
+ raise TypeError ("not expecting type '%s'" % type (s ))
900
+
901
+
902
+
828
903
def python_2_unicode_compatible (klass ):
829
904
"""
830
905
A decorator that defines __unicode__ and __str__ methods under Python 2.
831
906
Under Python 3 it does nothing.
832
-
833
907
To support Python 2 and 3 with a single code base, define a __str__ method
834
908
returning text and apply this decorator to the class.
835
909
"""
@@ -865,4 +939,4 @@ def python_2_unicode_compatible(klass):
865
939
break
866
940
del i , importer
867
941
# Finally, add the importer to the meta path import hook.
868
- sys .meta_path .append (_importer )
942
+ sys .meta_path .append (_importer )
0 commit comments