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