1# Copyright (c) 2010-2017 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  # noqa: E501
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## This file is part of Scapy
22## See http://www.secdev.org/projects/scapy for more information
23## Copyright (C) Philippe Biondi <phil@secdev.org>
24## This program is published under a GPLv2 license
25
26"""Utilities for writing code that runs on Python 2 and 3"""
27
28from __future__ import absolute_import
29
30import functools
31import itertools
32import operator
33import sys
34import types
35
36__author__ = "Benjamin Peterson <benjamin@python.org>"
37__version__ = "1.10.0"
38
39
40# Useful for very coarse version differentiation.
41PY2 = sys.version_info[0] == 2
42PY3 = sys.version_info[0] == 3
43PY34 = sys.version_info[0:2] >= (3, 4)
44
45if PY3:
46    string_types = str,
47    integer_types = int,
48    class_types = type,
49    text_type = str
50    binary_type = bytes
51
52    MAXSIZE = sys.maxsize
53else:
54    string_types = basestring,
55    integer_types = (int, long)
56    class_types = (type, types.ClassType)
57    text_type = unicode
58    binary_type = str
59
60    if sys.platform.startswith("java"):
61        # Jython always uses 32 bits.
62        MAXSIZE = int((1 << 31) - 1)
63    else:
64        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
65        class X(object):
66
67            def __len__(self):
68                return 1 << 31
69        try:
70            len(X())
71        except OverflowError:
72            # 32-bit
73            MAXSIZE = int((1 << 31) - 1)
74        else:
75            # 64-bit
76            MAXSIZE = int((1 << 63) - 1)
77        del X
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 scapy.modules.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 __get_module(self, fullname):
195        try:
196            return self.known_modules[fullname]
197        except KeyError:
198            raise ImportError("This loader does not know module " + fullname)
199
200    def load_module(self, fullname):
201        try:
202            # in case of a reload
203            return sys.modules[fullname]
204        except KeyError:
205            pass
206        mod = self.__get_module(fullname)
207        if isinstance(mod, MovedModule):
208            mod = mod._resolve()
209        else:
210            mod.__loader__ = self
211        sys.modules[fullname] = mod
212        return mod
213
214    def is_package(self, fullname):
215        """
216        Return true, if the named module is a package.
217
218        We need this method to get correct spec objects with
219        Python 3.4 (see PEP451)
220        """
221        return hasattr(self.__get_module(fullname), "__path__")
222
223    def get_code(self, fullname):
224        """Return None
225
226        Required, if is_package is implemented"""
227        self.__get_module(fullname)  # eventually raises ImportError
228        return None
229    get_source = get_code  # same as get_code
230
231_importer = _SixMetaPathImporter(__name__)
232
233
234class _MovedItems(_LazyModule):
235
236    """Lazy loading of moved objects"""
237    __path__ = []  # mark as package
238
239
240_moved_attributes = [
241    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
242    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
243    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),  # noqa: E501
244    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
245    MovedAttribute("intern", "__builtin__", "sys"),
246    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
247    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
248    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
249    MovedAttribute("getstatusoutput", "commands", "subprocess"),
250    MovedAttribute("getoutput", "commands", "subprocess"),
251    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
252    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),  # noqa: E501
253    MovedAttribute("reduce", "__builtin__", "functools"),
254    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
255    MovedAttribute("StringIO", "StringIO", "io"),
256    MovedAttribute("UserDict", "UserDict", "collections"),
257    MovedAttribute("UserList", "UserList", "collections"),
258    MovedAttribute("UserString", "UserString", "collections"),
259    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
260    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
261    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),  # noqa: E501
262    MovedModule("builtins", "__builtin__"),
263    MovedModule("configparser", "ConfigParser"),
264    MovedModule("copyreg", "copy_reg"),
265    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
266    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
267    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
268    MovedModule("http_cookies", "Cookie", "http.cookies"),
269    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
270    MovedModule("html_parser", "HTMLParser", "html.parser"),
271    MovedModule("http_client", "httplib", "http.client"),
272    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
273    MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
274    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),  # noqa: E501
275    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),  # noqa: E501
276    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
277    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
278    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
279    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
280    MovedModule("cPickle", "cPickle", "pickle"),
281    MovedModule("queue", "Queue"),
282    MovedModule("reprlib", "repr"),
283    MovedModule("socketserver", "SocketServer"),
284    MovedModule("_thread", "thread", "_thread"),
285    MovedModule("tkinter", "Tkinter"),
286    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
287    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
288    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),  # noqa: E501
289    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),  # noqa: E501
290    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
291    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
292    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
293    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
294    MovedModule("tkinter_colorchooser", "tkColorChooser",
295                "tkinter.colorchooser"),
296    MovedModule("tkinter_commondialog", "tkCommonDialog",
297                "tkinter.commondialog"),
298    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
299    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
300    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
301    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
302                "tkinter.simpledialog"),
303    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),  # noqa: E501
304    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),  # noqa: E501
305    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),  # noqa: E501
306    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
307    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
308    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
309]
310# Add windows specific modules.
311if sys.platform == "win32":
312    _moved_attributes += [
313        MovedModule("winreg", "_winreg"),
314    ]
315
316for attr in _moved_attributes:
317    setattr(_MovedItems, attr.name, attr)
318    if isinstance(attr, MovedModule):
319        _importer._add_module(attr, "moves." + attr.name)
320del attr
321
322_MovedItems._moved_attributes = _moved_attributes
323
324moves = _MovedItems(__name__ + ".moves")
325_importer._add_module(moves, "moves")
326
327
328class Module_six_moves_urllib_parse(_LazyModule):
329
330    """Lazy loading of moved objects in scapy.modules.six.urllib_parse"""
331
332
333_urllib_parse_moved_attributes = [
334    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
335    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
336    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
337    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
338    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
339    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
340    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
341    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
342    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
343    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
344    MovedAttribute("quote", "urllib", "urllib.parse"),
345    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
346    MovedAttribute("unquote", "urllib", "urllib.parse"),
347    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
348    MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),  # noqa: E501
349    MovedAttribute("urlencode", "urllib", "urllib.parse"),
350    MovedAttribute("splitquery", "urllib", "urllib.parse"),
351    MovedAttribute("splittag", "urllib", "urllib.parse"),
352    MovedAttribute("splituser", "urllib", "urllib.parse"),
353    MovedAttribute("splitvalue", "urllib", "urllib.parse"),
354    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
355    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
356    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
357    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
358    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
359]
360for attr in _urllib_parse_moved_attributes:
361    setattr(Module_six_moves_urllib_parse, attr.name, attr)
362del attr
363
364Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes  # noqa: E501
365
366_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),  # noqa: E501
367                      "moves.urllib_parse", "moves.urllib.parse")
368
369
370class Module_six_moves_urllib_error(_LazyModule):
371
372    """Lazy loading of moved objects in scapy.modules.six.urllib_error"""
373
374
375_urllib_error_moved_attributes = [
376    MovedAttribute("URLError", "urllib2", "urllib.error"),
377    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
378    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
379]
380for attr in _urllib_error_moved_attributes:
381    setattr(Module_six_moves_urllib_error, attr.name, attr)
382del attr
383
384Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes  # noqa: E501
385
386_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),  # noqa: E501
387                      "moves.urllib_error", "moves.urllib.error")
388
389
390class Module_six_moves_urllib_request(_LazyModule):
391
392    """Lazy loading of moved objects in scapy.modules.six.urllib_request"""
393
394
395_urllib_request_moved_attributes = [
396    MovedAttribute("urlopen", "urllib2", "urllib.request"),
397    MovedAttribute("install_opener", "urllib2", "urllib.request"),
398    MovedAttribute("build_opener", "urllib2", "urllib.request"),
399    MovedAttribute("pathname2url", "urllib", "urllib.request"),
400    MovedAttribute("url2pathname", "urllib", "urllib.request"),
401    MovedAttribute("getproxies", "urllib", "urllib.request"),
402    MovedAttribute("Request", "urllib2", "urllib.request"),
403    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
404    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
405    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
406    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
407    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
408    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
409    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
410    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),  # noqa: E501
411    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
412    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
413    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
414    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
415    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
416    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
417    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
418    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
419    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
420    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
421    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
422    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
423    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
424    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
425    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
426    MovedAttribute("URLopener", "urllib", "urllib.request"),
427    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
428    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
429]
430for attr in _urllib_request_moved_attributes:
431    setattr(Module_six_moves_urllib_request, attr.name, attr)
432del attr
433
434Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes  # noqa: E501
435
436_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),  # noqa: E501
437                      "moves.urllib_request", "moves.urllib.request")
438
439
440class Module_six_moves_urllib_response(_LazyModule):
441
442    """Lazy loading of moved objects in scapy.modules.six.urllib_response"""
443
444
445_urllib_response_moved_attributes = [
446    MovedAttribute("addbase", "urllib", "urllib.response"),
447    MovedAttribute("addclosehook", "urllib", "urllib.response"),
448    MovedAttribute("addinfo", "urllib", "urllib.response"),
449    MovedAttribute("addinfourl", "urllib", "urllib.response"),
450]
451for attr in _urllib_response_moved_attributes:
452    setattr(Module_six_moves_urllib_response, attr.name, attr)
453del attr
454
455Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes  # noqa: E501
456
457_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),  # noqa: E501
458                      "moves.urllib_response", "moves.urllib.response")
459
460
461class Module_six_moves_urllib_robotparser(_LazyModule):
462
463    """Lazy loading of moved objects in scapy.modules.six.urllib_robotparser"""
464
465
466_urllib_robotparser_moved_attributes = [
467    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
468]
469for attr in _urllib_robotparser_moved_attributes:
470    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
471del attr
472
473Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes  # noqa: E501
474
475_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),  # noqa: E501
476                      "moves.urllib_robotparser", "moves.urllib.robotparser")
477
478
479class Module_six_moves_urllib(types.ModuleType):
480
481    """Create a scapy.modules.six.urllib namespace that resembles the Python 3 namespace"""  # noqa: E501
482    __path__ = []  # mark as package
483    parse = _importer._get_module("moves.urllib_parse")
484    error = _importer._get_module("moves.urllib_error")
485    request = _importer._get_module("moves.urllib_request")
486    response = _importer._get_module("moves.urllib_response")
487    robotparser = _importer._get_module("moves.urllib_robotparser")
488
489    def __dir__(self):
490        return ['parse', 'error', 'request', 'response', 'robotparser']
491
492_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
493                      "moves.urllib")
494
495
496def add_move(move):
497    """Add an item to scapy.modules.six."""
498    setattr(_MovedItems, move.name, move)
499
500
501def remove_move(name):
502    """Remove item from scapy.modules.six."""
503    try:
504        delattr(_MovedItems, name)
505    except AttributeError:
506        try:
507            del moves.__dict__[name]
508        except KeyError:
509            raise AttributeError("no such move, %r" % (name,))
510
511
512if PY3:
513    _meth_func = "__func__"
514    _meth_self = "__self__"
515
516    _func_closure = "__closure__"
517    _func_code = "__code__"
518    _func_defaults = "__defaults__"
519    _func_globals = "__globals__"
520else:
521    _meth_func = "im_func"
522    _meth_self = "im_self"
523
524    _func_closure = "func_closure"
525    _func_code = "func_code"
526    _func_defaults = "func_defaults"
527    _func_globals = "func_globals"
528
529
530try:
531    advance_iterator = next
532except NameError:
533    def advance_iterator(it):
534        return it.next()
535next = advance_iterator
536
537
538try:
539    callable = callable
540except NameError:
541    def callable(obj):
542        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
543
544
545if PY3:
546    def get_unbound_function(unbound):
547        return unbound
548
549    create_bound_method = types.MethodType
550
551    def create_unbound_method(func, cls):
552        return func
553
554    Iterator = object
555else:
556    def get_unbound_function(unbound):
557        return unbound.im_func
558
559    def create_bound_method(func, obj):
560        return types.MethodType(func, obj, obj.__class__)
561
562    def create_unbound_method(func, cls):
563        return types.MethodType(func, None, cls)
564
565    class Iterator(object):
566
567        def next(self):
568            return type(self).__next__(self)
569
570    callable = callable
571_add_doc(get_unbound_function,
572         """Get the function out of a possibly unbound function""")
573
574
575get_method_function = operator.attrgetter(_meth_func)
576get_method_self = operator.attrgetter(_meth_self)
577get_function_closure = operator.attrgetter(_func_closure)
578get_function_code = operator.attrgetter(_func_code)
579get_function_defaults = operator.attrgetter(_func_defaults)
580get_function_globals = operator.attrgetter(_func_globals)
581
582
583if PY3:
584    def iterkeys(d, **kw):
585        return iter(d.keys(**kw))
586
587    def itervalues(d, **kw):
588        return iter(d.values(**kw))
589
590    def iteritems(d, **kw):
591        return iter(d.items(**kw))
592
593    def iterlists(d, **kw):
594        return iter(d.lists(**kw))
595
596    viewkeys = operator.methodcaller("keys")
597
598    viewvalues = operator.methodcaller("values")
599
600    viewitems = operator.methodcaller("items")
601else:
602    def iterkeys(d, **kw):
603        return d.iterkeys(**kw)
604
605    def itervalues(d, **kw):
606        return d.itervalues(**kw)
607
608    def iteritems(d, **kw):
609        return d.iteritems(**kw)
610
611    def iterlists(d, **kw):
612        return d.iterlists(**kw)
613
614    viewkeys = operator.methodcaller("viewkeys")
615
616    viewvalues = operator.methodcaller("viewvalues")
617
618    viewitems = operator.methodcaller("viewitems")
619
620_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
621_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
622_add_doc(iteritems,
623         "Return an iterator over the (key, value) pairs of a dictionary.")
624_add_doc(iterlists,
625         "Return an iterator over the (key, [values]) pairs of a dictionary.")
626
627
628if PY3:
629    def b(s):
630        return s.encode("latin-1")
631
632    def u(s):
633        return s
634    unichr = chr
635    import struct
636    int2byte = struct.Struct(">B").pack
637    del struct
638    byte2int = operator.itemgetter(0)
639    indexbytes = operator.getitem
640    iterbytes = iter
641    import io
642    StringIO = io.StringIO
643    BytesIO = io.BytesIO
644    _assertCountEqual = "assertCountEqual"
645    if sys.version_info[1] <= 1:
646        _assertRaisesRegex = "assertRaisesRegexp"
647        _assertRegex = "assertRegexpMatches"
648    else:
649        _assertRaisesRegex = "assertRaisesRegex"
650        _assertRegex = "assertRegex"
651else:
652    def b(s):
653        return s
654    # Workaround for standalone backslash
655
656    def u(s):
657        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
658    unichr = unichr
659    int2byte = chr
660
661    def byte2int(bs):
662        return ord(bs[0])
663
664    def indexbytes(buf, i):
665        return ord(buf[i])
666    iterbytes = functools.partial(itertools.imap, ord)
667    import StringIO
668    StringIO = BytesIO = StringIO.StringIO
669    _assertCountEqual = "assertItemsEqual"
670    _assertRaisesRegex = "assertRaisesRegexp"
671    _assertRegex = "assertRegexpMatches"
672_add_doc(b, """Byte literal""")
673_add_doc(u, """Text literal""")
674
675
676def assertCountEqual(self, *args, **kwargs):
677    return getattr(self, _assertCountEqual)(*args, **kwargs)
678
679
680def assertRaisesRegex(self, *args, **kwargs):
681    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
682
683
684def assertRegex(self, *args, **kwargs):
685    return getattr(self, _assertRegex)(*args, **kwargs)
686
687
688if PY3:
689    exec_ = getattr(moves.builtins, "exec")
690
691    def reraise(tp, value, tb=None):
692        try:
693            if value is None:
694                value = tp()
695            if value.__traceback__ is not tb:
696                raise value.with_traceback(tb)
697            raise value
698        finally:
699            value = None
700            tb = None
701
702else:
703    def exec_(_code_, _globs_=None, _locs_=None):
704        """Execute code in a namespace."""
705        if _globs_ is None:
706            frame = sys._getframe(1)
707            _globs_ = frame.f_globals
708            if _locs_ is None:
709                _locs_ = frame.f_locals
710            del frame
711        elif _locs_ is None:
712            _locs_ = _globs_
713        exec("""exec _code_ in _globs_, _locs_""")
714
715    exec_("""def reraise(tp, value, tb=None):
716    try:
717        raise tp, value, tb
718    finally:
719        tb = None
720""")
721
722
723if sys.version_info[:2] == (3, 2):
724    exec_("""def raise_from(value, from_value):
725    try:
726        if from_value is None:
727            raise value
728        raise value from from_value
729    finally:
730        value = None
731""")
732elif sys.version_info[:2] > (3, 2):
733    exec_("""def raise_from(value, from_value):
734    try:
735        raise value from from_value
736    finally:
737        value = None
738""")
739else:
740    def raise_from(value, from_value):
741        raise value
742
743
744print_ = getattr(moves.builtins, "print", None)
745if print_ is None:
746    def print_(*args, **kwargs):
747        """The new-style print function for Python 2.4 and 2.5."""
748        fp = kwargs.pop("file", sys.stdout)
749        if fp is None:
750            return
751
752        def write(data):
753            if not isinstance(data, basestring):
754                data = str(data)
755            # If the file has an encoding, encode unicode with it.
756            if (isinstance(fp, file) and
757                    isinstance(data, unicode) and
758                    fp.encoding is not None):
759                errors = getattr(fp, "errors", None)
760                if errors is None:
761                    errors = "strict"
762                data = data.encode(fp.encoding, errors)
763            fp.write(data)
764        want_unicode = False
765        sep = kwargs.pop("sep", None)
766        if sep is not None:
767            if isinstance(sep, unicode):
768                want_unicode = True
769            elif not isinstance(sep, str):
770                raise TypeError("sep must be None or a string")
771        end = kwargs.pop("end", None)
772        if end is not None:
773            if isinstance(end, unicode):
774                want_unicode = True
775            elif not isinstance(end, str):
776                raise TypeError("end must be None or a string")
777        if kwargs:
778            raise TypeError("invalid keyword arguments to print()")
779        if not want_unicode:
780            for arg in args:
781                if isinstance(arg, unicode):
782                    want_unicode = True
783                    break
784        if want_unicode:
785            newline = unicode("\n")
786            space = unicode(" ")
787        else:
788            newline = "\n"
789            space = " "
790        if sep is None:
791            sep = space
792        if end is None:
793            end = newline
794        for i, arg in enumerate(args):
795            if i:
796                write(sep)
797            write(arg)
798        write(end)
799if sys.version_info[:2] < (3, 3):
800    _print = print_
801
802    def print_(*args, **kwargs):
803        fp = kwargs.get("file", sys.stdout)
804        flush = kwargs.pop("flush", False)
805        _print(*args, **kwargs)
806        if flush and fp is not None:
807            fp.flush()
808
809_add_doc(reraise, """Reraise an exception.""")
810
811if sys.version_info[0:2] < (3, 4):
812    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
813              updated=functools.WRAPPER_UPDATES):
814        def wrapper(f):
815            f = functools.wraps(wrapped, assigned, updated)(f)
816            f.__wrapped__ = wrapped
817            return f
818        return wrapper
819else:
820    wraps = functools.wraps
821
822
823def with_metaclass(meta, *bases):
824    """Create a base class with a metaclass."""
825    # This requires a bit of explanation: the basic idea is to make a dummy
826    # metaclass for one level of class instantiation that replaces itself with
827    # the actual metaclass.
828    class metaclass(meta):
829
830        def __new__(cls, name, this_bases, d):
831            return meta(name, bases, d)
832    return type.__new__(metaclass, 'temporary_class', (), {})
833
834
835def add_metaclass(metaclass):
836    """Class decorator for creating a class with a metaclass."""
837    def wrapper(cls):
838        orig_vars = cls.__dict__.copy()
839        slots = orig_vars.get('__slots__')
840        if slots is not None:
841            if isinstance(slots, str):
842                slots = [slots]
843            for slots_var in slots:
844                orig_vars.pop(slots_var)
845        orig_vars.pop('__dict__', None)
846        orig_vars.pop('__weakref__', None)
847        return metaclass(cls.__name__, cls.__bases__, orig_vars)
848    return wrapper
849
850
851def python_2_unicode_compatible(klass):
852    """
853    A decorator that defines __unicode__ and __str__ methods under Python 2.
854    Under Python 3 it does nothing.
855
856    To support Python 2 and 3 with a single code base, define a __str__ method
857    returning text and apply this decorator to the class.
858    """
859    if PY2:
860        if '__str__' not in klass.__dict__:
861            raise ValueError("@python_2_unicode_compatible cannot be applied "
862                             "to %s because it doesn't define __str__()." %
863                             klass.__name__)
864        klass.__unicode__ = klass.__str__
865        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
866    return klass
867
868
869# Complete the moves implementation.
870# This code is at the end of this module to speed up module loading.
871# Turn this module into a package.
872__path__ = []  # required for PEP 302 and PEP 451
873__package__ = __name__  # see PEP 366 @ReservedAssignment
874if globals().get("__spec__") is not None:
875    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
876# Remove other six meta path importers, since they cause problems. This can
877# happen if six is removed from sys.modules and then reloaded. (Setuptools does
878# this for some reason.)
879if sys.meta_path:
880    for i, importer in enumerate(sys.meta_path):
881        # Here's some real nastiness: Another "instance" of the six module might  # noqa: E501
882        # be floating around. Therefore, we can't use isinstance() to check for
883        # the six meta path importer, since the other six instance will have
884        # inserted an importer with different class.
885        if (type(importer).__name__ == "_SixMetaPathImporter" and
886                importer.name == __name__):
887            del sys.meta_path[i]
888            break
889    del i, importer
890# Finally, add the importer to the meta path import hook.
891sys.meta_path.append(_importer)
892