1# Copyright (c) 2010-2020 Benjamin Peterson
2#
3# Permission is hereby granted, free of charge, to any person obtaining a copy
4# of this software and associated documentation files (the "Software"), to deal
5# in the Software without restriction, including without limitation the rights
6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7# copies of the Software, and to permit persons to whom the Software is
8# furnished to do so, subject to the following conditions:
9#
10# The above copyright notice and this permission notice shall be included in all
11# copies or substantial portions of the Software.
12#
13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19# SOFTWARE.
20
21"""Utilities for writing code that runs on Python 2 and 3"""
22
23from __future__ import absolute_import
24
25import functools
26import itertools
27import operator
28import sys
29import types
30
31__author__ = "Benjamin Peterson <benjamin@python.org>"
32__version__ = "1.16.0"
33
34
35# Useful for very coarse version differentiation.
36PY2 = sys.version_info[0] == 2
37PY3 = sys.version_info[0] == 3
38PY34 = sys.version_info[0:2] >= (3, 4)
39
40if PY3:
41    string_types = str,
42    integer_types = int,
43    class_types = type,
44    text_type = str
45    binary_type = bytes
46
47    MAXSIZE = sys.maxsize
48else:
49    string_types = basestring,
50    integer_types = (int, long)
51    class_types = (type, types.ClassType)
52    text_type = unicode
53    binary_type = str
54
55    if sys.platform.startswith("java"):
56        # Jython always uses 32 bits.
57        MAXSIZE = int((1 << 31) - 1)
58    else:
59        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
60        class X(object):
61
62            def __len__(self):
63                return 1 << 31
64        try:
65            len(X())
66        except OverflowError:
67            # 32-bit
68            MAXSIZE = int((1 << 31) - 1)
69        else:
70            # 64-bit
71            MAXSIZE = int((1 << 63) - 1)
72        del X
73
74if PY34:
75    from importlib.util import spec_from_loader
76else:
77    spec_from_loader = None
78
79
80def _add_doc(func, doc):
81    """Add documentation to a function."""
82    func.__doc__ = doc
83
84
85def _import_module(name):
86    """Import module, returning the module after the last dot."""
87    __import__(name)
88    return sys.modules[name]
89
90
91class _LazyDescr(object):
92
93    def __init__(self, name):
94        self.name = name
95
96    def __get__(self, obj, tp):
97        result = self._resolve()
98        setattr(obj, self.name, result)  # Invokes __set__.
99        try:
100            # This is a bit ugly, but it avoids running this again by
101            # removing this descriptor.
102            delattr(obj.__class__, self.name)
103        except AttributeError:
104            pass
105        return result
106
107
108class MovedModule(_LazyDescr):
109
110    def __init__(self, name, old, new=None):
111        super(MovedModule, self).__init__(name)
112        if PY3:
113            if new is None:
114                new = name
115            self.mod = new
116        else:
117            self.mod = old
118
119    def _resolve(self):
120        return _import_module(self.mod)
121
122    def __getattr__(self, attr):
123        _module = self._resolve()
124        value = getattr(_module, attr)
125        setattr(self, attr, value)
126        return value
127
128
129class _LazyModule(types.ModuleType):
130
131    def __init__(self, name):
132        super(_LazyModule, self).__init__(name)
133        self.__doc__ = self.__class__.__doc__
134
135    def __dir__(self):
136        attrs = ["__doc__", "__name__"]
137        attrs += [attr.name for attr in self._moved_attributes]
138        return attrs
139
140    # Subclasses should override this
141    _moved_attributes = []
142
143
144class MovedAttribute(_LazyDescr):
145
146    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
147        super(MovedAttribute, self).__init__(name)
148        if PY3:
149            if new_mod is None:
150                new_mod = name
151            self.mod = new_mod
152            if new_attr is None:
153                if old_attr is None:
154                    new_attr = name
155                else:
156                    new_attr = old_attr
157            self.attr = new_attr
158        else:
159            self.mod = old_mod
160            if old_attr is None:
161                old_attr = name
162            self.attr = old_attr
163
164    def _resolve(self):
165        module = _import_module(self.mod)
166        return getattr(module, self.attr)
167
168
169class _SixMetaPathImporter(object):
170
171    """
172    A meta path importer to import six.moves and its submodules.
173
174    This class implements a PEP302 finder and loader. It should be compatible
175    with Python 2.5 and all existing versions of Python3
176    """
177
178    def __init__(self, six_module_name):
179        self.name = six_module_name
180        self.known_modules = {}
181
182    def _add_module(self, mod, *fullnames):
183        for fullname in fullnames:
184            self.known_modules[self.name + "." + fullname] = mod
185
186    def _get_module(self, fullname):
187        return self.known_modules[self.name + "." + fullname]
188
189    def find_module(self, fullname, path=None):
190        if fullname in self.known_modules:
191            return self
192        return None
193
194    def find_spec(self, fullname, path, target=None):
195        if fullname in self.known_modules:
196            return spec_from_loader(fullname, self)
197        return None
198
199    def __get_module(self, fullname):
200        try:
201            return self.known_modules[fullname]
202        except KeyError:
203            raise ImportError("This loader does not know module " + fullname)
204
205    def load_module(self, fullname):
206        try:
207            # in case of a reload
208            return sys.modules[fullname]
209        except KeyError:
210            pass
211        mod = self.__get_module(fullname)
212        if isinstance(mod, MovedModule):
213            mod = mod._resolve()
214        else:
215            mod.__loader__ = self
216        sys.modules[fullname] = mod
217        return mod
218
219    def is_package(self, fullname):
220        """
221        Return true, if the named module is a package.
222
223        We need this method to get correct spec objects with
224        Python 3.4 (see PEP451)
225        """
226        return hasattr(self.__get_module(fullname), "__path__")
227
228    def get_code(self, fullname):
229        """Return None
230
231        Required, if is_package is implemented"""
232        self.__get_module(fullname)  # eventually raises ImportError
233        return None
234    get_source = get_code  # same as get_code
235
236    def create_module(self, spec):
237        return self.load_module(spec.name)
238
239    def exec_module(self, module):
240        pass
241
242_importer = _SixMetaPathImporter(__name__)
243
244
245class _MovedItems(_LazyModule):
246
247    """Lazy loading of moved objects"""
248    __path__ = []  # mark as package
249
250
251_moved_attributes = [
252    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
253    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
254    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
255    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
256    MovedAttribute("intern", "__builtin__", "sys"),
257    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
258    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
259    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
260    MovedAttribute("getoutput", "commands", "subprocess"),
261    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
262    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
263    MovedAttribute("reduce", "__builtin__", "functools"),
264    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
265    MovedAttribute("StringIO", "StringIO", "io"),
266    MovedAttribute("UserDict", "UserDict", "collections"),
267    MovedAttribute("UserList", "UserList", "collections"),
268    MovedAttribute("UserString", "UserString", "collections"),
269    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
270    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
271    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
272    MovedModule("builtins", "__builtin__"),
273    MovedModule("configparser", "ConfigParser"),
274    MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
275    MovedModule("copyreg", "copy_reg"),
276    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
277    MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
278    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
279    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
280    MovedModule("http_cookies", "Cookie", "http.cookies"),
281    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
282    MovedModule("html_parser", "HTMLParser", "html.parser"),
283    MovedModule("http_client", "httplib", "http.client"),
284    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
285    MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
286    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
287    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
288    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
289    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
290    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
291    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
292    MovedModule("cPickle", "cPickle", "pickle"),
293    MovedModule("queue", "Queue"),
294    MovedModule("reprlib", "repr"),
295    MovedModule("socketserver", "SocketServer"),
296    MovedModule("_thread", "thread", "_thread"),
297    MovedModule("tkinter", "Tkinter"),
298    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
299    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
300    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
301    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
302    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
303    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
304    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
305    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
306    MovedModule("tkinter_colorchooser", "tkColorChooser",
307                "tkinter.colorchooser"),
308    MovedModule("tkinter_commondialog", "tkCommonDialog",
309                "tkinter.commondialog"),
310    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
311    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
312    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
313    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
314                "tkinter.simpledialog"),
315    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
316    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
317    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
318    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
319    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
320    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
321]
322# Add windows specific modules.
323if sys.platform == "win32":
324    _moved_attributes += [
325        MovedModule("winreg", "_winreg"),
326    ]
327
328for attr in _moved_attributes:
329    setattr(_MovedItems, attr.name, attr)
330    if isinstance(attr, MovedModule):
331        _importer._add_module(attr, "moves." + attr.name)
332del attr
333
334_MovedItems._moved_attributes = _moved_attributes
335
336moves = _MovedItems(__name__ + ".moves")
337_importer._add_module(moves, "moves")
338
339
340class Module_six_moves_urllib_parse(_LazyModule):
341
342    """Lazy loading of moved objects in six.moves.urllib_parse"""
343
344
345_urllib_parse_moved_attributes = [
346    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
347    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
348    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
349    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
350    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
351    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
352    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
353    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
354    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
355    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
356    MovedAttribute("quote", "urllib", "urllib.parse"),
357    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
358    MovedAttribute("unquote", "urllib", "urllib.parse"),
359    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
360    MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
361    MovedAttribute("urlencode", "urllib", "urllib.parse"),
362    MovedAttribute("splitquery", "urllib", "urllib.parse"),
363    MovedAttribute("splittag", "urllib", "urllib.parse"),
364    MovedAttribute("splituser", "urllib", "urllib.parse"),
365    MovedAttribute("splitvalue", "urllib", "urllib.parse"),
366    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
367    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
368    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
369    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
370    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
371]
372for attr in _urllib_parse_moved_attributes:
373    setattr(Module_six_moves_urllib_parse, attr.name, attr)
374del attr
375
376Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
377
378_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
379                      "moves.urllib_parse", "moves.urllib.parse")
380
381
382class Module_six_moves_urllib_error(_LazyModule):
383
384    """Lazy loading of moved objects in six.moves.urllib_error"""
385
386
387_urllib_error_moved_attributes = [
388    MovedAttribute("URLError", "urllib2", "urllib.error"),
389    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
390    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
391]
392for attr in _urllib_error_moved_attributes:
393    setattr(Module_six_moves_urllib_error, attr.name, attr)
394del attr
395
396Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
397
398_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
399                      "moves.urllib_error", "moves.urllib.error")
400
401
402class Module_six_moves_urllib_request(_LazyModule):
403
404    """Lazy loading of moved objects in six.moves.urllib_request"""
405
406
407_urllib_request_moved_attributes = [
408    MovedAttribute("urlopen", "urllib2", "urllib.request"),
409    MovedAttribute("install_opener", "urllib2", "urllib.request"),
410    MovedAttribute("build_opener", "urllib2", "urllib.request"),
411    MovedAttribute("pathname2url", "urllib", "urllib.request"),
412    MovedAttribute("url2pathname", "urllib", "urllib.request"),
413    MovedAttribute("getproxies", "urllib", "urllib.request"),
414    MovedAttribute("Request", "urllib2", "urllib.request"),
415    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
416    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
417    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
418    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
419    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
420    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
421    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
422    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
423    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
424    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
425    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
426    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
427    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
428    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
429    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
430    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
431    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
432    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
433    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
434    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
435    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
436    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
437    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
438    MovedAttribute("URLopener", "urllib", "urllib.request"),
439    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
440    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
441    MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
442    MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
443]
444for attr in _urllib_request_moved_attributes:
445    setattr(Module_six_moves_urllib_request, attr.name, attr)
446del attr
447
448Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
449
450_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
451                      "moves.urllib_request", "moves.urllib.request")
452
453
454class Module_six_moves_urllib_response(_LazyModule):
455
456    """Lazy loading of moved objects in six.moves.urllib_response"""
457
458
459_urllib_response_moved_attributes = [
460    MovedAttribute("addbase", "urllib", "urllib.response"),
461    MovedAttribute("addclosehook", "urllib", "urllib.response"),
462    MovedAttribute("addinfo", "urllib", "urllib.response"),
463    MovedAttribute("addinfourl", "urllib", "urllib.response"),
464]
465for attr in _urllib_response_moved_attributes:
466    setattr(Module_six_moves_urllib_response, attr.name, attr)
467del attr
468
469Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
470
471_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
472                      "moves.urllib_response", "moves.urllib.response")
473
474
475class Module_six_moves_urllib_robotparser(_LazyModule):
476
477    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
478
479
480_urllib_robotparser_moved_attributes = [
481    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
482]
483for attr in _urllib_robotparser_moved_attributes:
484    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
485del attr
486
487Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
488
489_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
490                      "moves.urllib_robotparser", "moves.urllib.robotparser")
491
492
493class Module_six_moves_urllib(types.ModuleType):
494
495    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
496    __path__ = []  # mark as package
497    parse = _importer._get_module("moves.urllib_parse")
498    error = _importer._get_module("moves.urllib_error")
499    request = _importer._get_module("moves.urllib_request")
500    response = _importer._get_module("moves.urllib_response")
501    robotparser = _importer._get_module("moves.urllib_robotparser")
502
503    def __dir__(self):
504        return ['parse', 'error', 'request', 'response', 'robotparser']
505
506_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
507                      "moves.urllib")
508
509
510def add_move(move):
511    """Add an item to six.moves."""
512    setattr(_MovedItems, move.name, move)
513
514
515def remove_move(name):
516    """Remove item from six.moves."""
517    try:
518        delattr(_MovedItems, name)
519    except AttributeError:
520        try:
521            del moves.__dict__[name]
522        except KeyError:
523            raise AttributeError("no such move, %r" % (name,))
524
525
526if PY3:
527    _meth_func = "__func__"
528    _meth_self = "__self__"
529
530    _func_closure = "__closure__"
531    _func_code = "__code__"
532    _func_defaults = "__defaults__"
533    _func_globals = "__globals__"
534else:
535    _meth_func = "im_func"
536    _meth_self = "im_self"
537
538    _func_closure = "func_closure"
539    _func_code = "func_code"
540    _func_defaults = "func_defaults"
541    _func_globals = "func_globals"
542
543
544try:
545    advance_iterator = next
546except NameError:
547    def advance_iterator(it):
548        return it.next()
549next = advance_iterator
550
551
552try:
553    callable = callable
554except NameError:
555    def callable(obj):
556        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
557
558
559if PY3:
560    def get_unbound_function(unbound):
561        return unbound
562
563    create_bound_method = types.MethodType
564
565    def create_unbound_method(func, cls):
566        return func
567
568    Iterator = object
569else:
570    def get_unbound_function(unbound):
571        return unbound.im_func
572
573    def create_bound_method(func, obj):
574        return types.MethodType(func, obj, obj.__class__)
575
576    def create_unbound_method(func, cls):
577        return types.MethodType(func, None, cls)
578
579    class Iterator(object):
580
581        def next(self):
582            return type(self).__next__(self)
583
584    callable = callable
585_add_doc(get_unbound_function,
586         """Get the function out of a possibly unbound function""")
587
588
589get_method_function = operator.attrgetter(_meth_func)
590get_method_self = operator.attrgetter(_meth_self)
591get_function_closure = operator.attrgetter(_func_closure)
592get_function_code = operator.attrgetter(_func_code)
593get_function_defaults = operator.attrgetter(_func_defaults)
594get_function_globals = operator.attrgetter(_func_globals)
595
596
597if PY3:
598    def iterkeys(d, **kw):
599        return iter(d.keys(**kw))
600
601    def itervalues(d, **kw):
602        return iter(d.values(**kw))
603
604    def iteritems(d, **kw):
605        return iter(d.items(**kw))
606
607    def iterlists(d, **kw):
608        return iter(d.lists(**kw))
609
610    viewkeys = operator.methodcaller("keys")
611
612    viewvalues = operator.methodcaller("values")
613
614    viewitems = operator.methodcaller("items")
615else:
616    def iterkeys(d, **kw):
617        return d.iterkeys(**kw)
618
619    def itervalues(d, **kw):
620        return d.itervalues(**kw)
621
622    def iteritems(d, **kw):
623        return d.iteritems(**kw)
624
625    def iterlists(d, **kw):
626        return d.iterlists(**kw)
627
628    viewkeys = operator.methodcaller("viewkeys")
629
630    viewvalues = operator.methodcaller("viewvalues")
631
632    viewitems = operator.methodcaller("viewitems")
633
634_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
635_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
636_add_doc(iteritems,
637         "Return an iterator over the (key, value) pairs of a dictionary.")
638_add_doc(iterlists,
639         "Return an iterator over the (key, [values]) pairs of a dictionary.")
640
641
642if PY3:
643    def b(s):
644        return s.encode("latin-1")
645
646    def u(s):
647        return s
648    unichr = chr
649    import struct
650    int2byte = struct.Struct(">B").pack
651    del struct
652    byte2int = operator.itemgetter(0)
653    indexbytes = operator.getitem
654    iterbytes = iter
655    import io
656    StringIO = io.StringIO
657    BytesIO = io.BytesIO
658    del io
659    _assertCountEqual = "assertCountEqual"
660    if sys.version_info[1] <= 1:
661        _assertRaisesRegex = "assertRaisesRegexp"
662        _assertRegex = "assertRegexpMatches"
663        _assertNotRegex = "assertNotRegexpMatches"
664    else:
665        _assertRaisesRegex = "assertRaisesRegex"
666        _assertRegex = "assertRegex"
667        _assertNotRegex = "assertNotRegex"
668else:
669    def b(s):
670        return s
671    # Workaround for standalone backslash
672
673    def u(s):
674        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
675    unichr = unichr
676    int2byte = chr
677
678    def byte2int(bs):
679        return ord(bs[0])
680
681    def indexbytes(buf, i):
682        return ord(buf[i])
683    iterbytes = functools.partial(itertools.imap, ord)
684    import StringIO
685    StringIO = BytesIO = StringIO.StringIO
686    _assertCountEqual = "assertItemsEqual"
687    _assertRaisesRegex = "assertRaisesRegexp"
688    _assertRegex = "assertRegexpMatches"
689    _assertNotRegex = "assertNotRegexpMatches"
690_add_doc(b, """Byte literal""")
691_add_doc(u, """Text literal""")
692
693
694def assertCountEqual(self, *args, **kwargs):
695    return getattr(self, _assertCountEqual)(*args, **kwargs)
696
697
698def assertRaisesRegex(self, *args, **kwargs):
699    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
700
701
702def assertRegex(self, *args, **kwargs):
703    return getattr(self, _assertRegex)(*args, **kwargs)
704
705
706def assertNotRegex(self, *args, **kwargs):
707    return getattr(self, _assertNotRegex)(*args, **kwargs)
708
709
710if PY3:
711    exec_ = getattr(moves.builtins, "exec")
712
713    def reraise(tp, value, tb=None):
714        try:
715            if value is None:
716                value = tp()
717            if value.__traceback__ is not tb:
718                raise value.with_traceback(tb)
719            raise value
720        finally:
721            value = None
722            tb = None
723
724else:
725    def exec_(_code_, _globs_=None, _locs_=None):
726        """Execute code in a namespace."""
727        if _globs_ is None:
728            frame = sys._getframe(1)
729            _globs_ = frame.f_globals
730            if _locs_ is None:
731                _locs_ = frame.f_locals
732            del frame
733        elif _locs_ is None:
734            _locs_ = _globs_
735        exec("""exec _code_ in _globs_, _locs_""")
736
737    exec_("""def reraise(tp, value, tb=None):
738    try:
739        raise tp, value, tb
740    finally:
741        tb = None
742""")
743
744
745if sys.version_info[:2] > (3,):
746    exec_("""def raise_from(value, from_value):
747    try:
748        raise value from from_value
749    finally:
750        value = None
751""")
752else:
753    def raise_from(value, from_value):
754        raise value
755
756
757print_ = getattr(moves.builtins, "print", None)
758if print_ is None:
759    def print_(*args, **kwargs):
760        """The new-style print function for Python 2.4 and 2.5."""
761        fp = kwargs.pop("file", sys.stdout)
762        if fp is None:
763            return
764
765        def write(data):
766            if not isinstance(data, basestring):
767                data = str(data)
768            # If the file has an encoding, encode unicode with it.
769            if (isinstance(fp, file) and
770                    isinstance(data, unicode) and
771                    fp.encoding is not None):
772                errors = getattr(fp, "errors", None)
773                if errors is None:
774                    errors = "strict"
775                data = data.encode(fp.encoding, errors)
776            fp.write(data)
777        want_unicode = False
778        sep = kwargs.pop("sep", None)
779        if sep is not None:
780            if isinstance(sep, unicode):
781                want_unicode = True
782            elif not isinstance(sep, str):
783                raise TypeError("sep must be None or a string")
784        end = kwargs.pop("end", None)
785        if end is not None:
786            if isinstance(end, unicode):
787                want_unicode = True
788            elif not isinstance(end, str):
789                raise TypeError("end must be None or a string")
790        if kwargs:
791            raise TypeError("invalid keyword arguments to print()")
792        if not want_unicode:
793            for arg in args:
794                if isinstance(arg, unicode):
795                    want_unicode = True
796                    break
797        if want_unicode:
798            newline = unicode("\n")
799            space = unicode(" ")
800        else:
801            newline = "\n"
802            space = " "
803        if sep is None:
804            sep = space
805        if end is None:
806            end = newline
807        for i, arg in enumerate(args):
808            if i:
809                write(sep)
810            write(arg)
811        write(end)
812if sys.version_info[:2] < (3, 3):
813    _print = print_
814
815    def print_(*args, **kwargs):
816        fp = kwargs.get("file", sys.stdout)
817        flush = kwargs.pop("flush", False)
818        _print(*args, **kwargs)
819        if flush and fp is not None:
820            fp.flush()
821
822_add_doc(reraise, """Reraise an exception.""")
823
824if sys.version_info[0:2] < (3, 4):
825    # This does exactly the same what the :func:`py3:functools.update_wrapper`
826    # function does on Python versions after 3.2. It sets the ``__wrapped__``
827    # attribute on ``wrapper`` object and it doesn't raise an error if any of
828    # the attributes mentioned in ``assigned`` and ``updated`` are missing on
829    # ``wrapped`` object.
830    def _update_wrapper(wrapper, wrapped,
831                        assigned=functools.WRAPPER_ASSIGNMENTS,
832                        updated=functools.WRAPPER_UPDATES):
833        for attr in assigned:
834            try:
835                value = getattr(wrapped, attr)
836            except AttributeError:
837                continue
838            else:
839                setattr(wrapper, attr, value)
840        for attr in updated:
841            getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
842        wrapper.__wrapped__ = wrapped
843        return wrapper
844    _update_wrapper.__doc__ = functools.update_wrapper.__doc__
845
846    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
847              updated=functools.WRAPPER_UPDATES):
848        return functools.partial(_update_wrapper, wrapped=wrapped,
849                                 assigned=assigned, updated=updated)
850    wraps.__doc__ = functools.wraps.__doc__
851
852else:
853    wraps = functools.wraps
854
855
856def with_metaclass(meta, *bases):
857    """Create a base class with a metaclass."""
858    # This requires a bit of explanation: the basic idea is to make a dummy
859    # metaclass for one level of class instantiation that replaces itself with
860    # the actual metaclass.
861    class metaclass(type):
862
863        def __new__(cls, name, this_bases, d):
864            if sys.version_info[:2] >= (3, 7):
865                # This version introduced PEP 560 that requires a bit
866                # of extra care (we mimic what is done by __build_class__).
867                resolved_bases = types.resolve_bases(bases)
868                if resolved_bases is not bases:
869                    d['__orig_bases__'] = bases
870            else:
871                resolved_bases = bases
872            return meta(name, resolved_bases, d)
873
874        @classmethod
875        def __prepare__(cls, name, this_bases):
876            return meta.__prepare__(name, bases)
877    return type.__new__(metaclass, 'temporary_class', (), {})
878
879
880def add_metaclass(metaclass):
881    """Class decorator for creating a class with a metaclass."""
882    def wrapper(cls):
883        orig_vars = cls.__dict__.copy()
884        slots = orig_vars.get('__slots__')
885        if slots is not None:
886            if isinstance(slots, str):
887                slots = [slots]
888            for slots_var in slots:
889                orig_vars.pop(slots_var)
890        orig_vars.pop('__dict__', None)
891        orig_vars.pop('__weakref__', None)
892        if hasattr(cls, '__qualname__'):
893            orig_vars['__qualname__'] = cls.__qualname__
894        return metaclass(cls.__name__, cls.__bases__, orig_vars)
895    return wrapper
896
897
898def ensure_binary(s, encoding='utf-8', errors='strict'):
899    """Coerce **s** to six.binary_type.
900
901    For Python 2:
902      - `unicode` -> encoded to `str`
903      - `str` -> `str`
904
905    For Python 3:
906      - `str` -> encoded to `bytes`
907      - `bytes` -> `bytes`
908    """
909    if isinstance(s, binary_type):
910        return s
911    if isinstance(s, text_type):
912        return s.encode(encoding, errors)
913    raise TypeError("not expecting type '%s'" % type(s))
914
915
916def ensure_str(s, encoding='utf-8', errors='strict'):
917    """Coerce *s* to `str`.
918
919    For Python 2:
920      - `unicode` -> encoded to `str`
921      - `str` -> `str`
922
923    For Python 3:
924      - `str` -> `str`
925      - `bytes` -> decoded to `str`
926    """
927    # Optimization: Fast return for the common case.
928    if type(s) is str:
929        return s
930    if PY2 and isinstance(s, text_type):
931        return s.encode(encoding, errors)
932    elif PY3 and isinstance(s, binary_type):
933        return s.decode(encoding, errors)
934    elif not isinstance(s, (text_type, binary_type)):
935        raise TypeError("not expecting type '%s'" % type(s))
936    return s
937
938
939def ensure_text(s, encoding='utf-8', errors='strict'):
940    """Coerce *s* to six.text_type.
941
942    For Python 2:
943      - `unicode` -> `unicode`
944      - `str` -> `unicode`
945
946    For Python 3:
947      - `str` -> `str`
948      - `bytes` -> decoded to `str`
949    """
950    if isinstance(s, binary_type):
951        return s.decode(encoding, errors)
952    elif isinstance(s, text_type):
953        return s
954    else:
955        raise TypeError("not expecting type '%s'" % type(s))
956
957
958def python_2_unicode_compatible(klass):
959    """
960    A class decorator that defines __unicode__ and __str__ methods under Python 2.
961    Under Python 3 it does nothing.
962
963    To support Python 2 and 3 with a single code base, define a __str__ method
964    returning text and apply this decorator to the class.
965    """
966    if PY2:
967        if '__str__' not in klass.__dict__:
968            raise ValueError("@python_2_unicode_compatible cannot be applied "
969                             "to %s because it doesn't define __str__()." %
970                             klass.__name__)
971        klass.__unicode__ = klass.__str__
972        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
973    return klass
974
975
976# Complete the moves implementation.
977# This code is at the end of this module to speed up module loading.
978# Turn this module into a package.
979__path__ = []  # required for PEP 302 and PEP 451
980__package__ = __name__  # see PEP 366 @ReservedAssignment
981if globals().get("__spec__") is not None:
982    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
983# Remove other six meta path importers, since they cause problems. This can
984# happen if six is removed from sys.modules and then reloaded. (Setuptools does
985# this for some reason.)
986if sys.meta_path:
987    for i, importer in enumerate(sys.meta_path):
988        # Here's some real nastiness: Another "instance" of the six module might
989        # be floating around. Therefore, we can't use isinstance() to check for
990        # the six meta path importer, since the other six instance will have
991        # inserted an importer with different class.
992        if (type(importer).__name__ == "_SixMetaPathImporter" and
993                importer.name == __name__):
994            del sys.meta_path[i]
995            break
996    del i, importer
997# Finally, add the importer to the meta path import hook.
998sys.meta_path.append(_importer)
999