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.9.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    none_type = type(None)
48    boolean_type = bool
49    float_type = float
50    int_type = int
51    long_type = int
52    list_type = list
53    tuple_type = tuple
54    dictionary_type = dict
55
56    MAXSIZE = sys.maxsize
57else:
58    string_types = basestring,
59    integer_types = (int, long)
60    class_types = (type, types.ClassType)
61    text_type = unicode
62    binary_type = str
63
64    import types
65    none_type = types.NoneType
66    boolean_type = types.BooleanType
67    int_type = types.IntType
68    long_type = types.LongType
69    float_type = types.FloatType
70    list_type = types.ListType
71    tuple_type = types.TupleType
72    dictionary_type = types.DictionaryType
73
74    if sys.platform.startswith("java"):
75        # Jython always uses 32 bits.
76        MAXSIZE = int((1 << 31) - 1)
77    else:
78        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
79        class X(object):
80
81            def __len__(self):
82                return 1 << 31
83        try:
84            len(X())
85        except OverflowError:
86            # 32-bit
87            MAXSIZE = int((1 << 31) - 1)
88        else:
89            # 64-bit
90            MAXSIZE = int((1 << 63) - 1)
91        del X
92
93
94def _add_doc(func, doc):
95    """Add documentation to a function."""
96    func.__doc__ = doc
97
98
99def _import_module(name):
100    """Import module, returning the module after the last dot."""
101    __import__(name)
102    return sys.modules[name]
103
104
105class _LazyDescr(object):
106
107    def __init__(self, name):
108        self.name = name
109
110    def __get__(self, obj, tp):
111        result = self._resolve()
112        setattr(obj, self.name, result)  # Invokes __set__.
113        try:
114            # This is a bit ugly, but it avoids running this again by
115            # removing this descriptor.
116            delattr(obj.__class__, self.name)
117        except AttributeError:
118            pass
119        return result
120
121
122class MovedModule(_LazyDescr):
123
124    def __init__(self, name, old, new=None):
125        super(MovedModule, self).__init__(name)
126        if PY3:
127            if new is None:
128                new = name
129            self.mod = new
130        else:
131            self.mod = old
132
133    def _resolve(self):
134        return _import_module(self.mod)
135
136    def __getattr__(self, attr):
137        _module = self._resolve()
138        value = getattr(_module, attr)
139        setattr(self, attr, value)
140        return value
141
142
143class _LazyModule(types.ModuleType):
144
145    def __init__(self, name):
146        super(_LazyModule, self).__init__(name)
147        self.__doc__ = self.__class__.__doc__
148
149    def __dir__(self):
150        attrs = ["__doc__", "__name__"]
151        attrs += [attr.name for attr in self._moved_attributes]
152        return attrs
153
154    # Subclasses should override this
155    _moved_attributes = []
156
157
158class MovedAttribute(_LazyDescr):
159
160    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
161        super(MovedAttribute, self).__init__(name)
162        if PY3:
163            if new_mod is None:
164                new_mod = name
165            self.mod = new_mod
166            if new_attr is None:
167                if old_attr is None:
168                    new_attr = name
169                else:
170                    new_attr = old_attr
171            self.attr = new_attr
172        else:
173            self.mod = old_mod
174            if old_attr is None:
175                old_attr = name
176            self.attr = old_attr
177
178    def _resolve(self):
179        module = _import_module(self.mod)
180        return getattr(module, self.attr)
181
182
183class _SixMetaPathImporter(object):
184
185    """
186    A meta path importer to import six.moves and its submodules.
187
188    This class implements a PEP302 finder and loader. It should be compatible
189    with Python 2.5 and all existing versions of Python3
190    """
191
192    def __init__(self, six_module_name):
193        self.name = six_module_name
194        self.known_modules = {}
195
196    def _add_module(self, mod, *fullnames):
197        for fullname in fullnames:
198            self.known_modules[self.name + "." + fullname] = mod
199
200    def _get_module(self, fullname):
201        return self.known_modules[self.name + "." + fullname]
202
203    def find_module(self, fullname, path=None):
204        if fullname in self.known_modules:
205            return self
206        return None
207
208    def __get_module(self, fullname):
209        try:
210            return self.known_modules[fullname]
211        except KeyError:
212            raise ImportError("This loader does not know module " + fullname)
213
214    def load_module(self, fullname):
215        try:
216            # in case of a reload
217            return sys.modules[fullname]
218        except KeyError:
219            pass
220        mod = self.__get_module(fullname)
221        if isinstance(mod, MovedModule):
222            mod = mod._resolve()
223        else:
224            mod.__loader__ = self
225        sys.modules[fullname] = mod
226        return mod
227
228    def is_package(self, fullname):
229        """
230        Return true, if the named module is a package.
231
232        We need this method to get correct spec objects with
233        Python 3.4 (see PEP451)
234        """
235        return hasattr(self.__get_module(fullname), "__path__")
236
237    def get_code(self, fullname):
238        """Return None
239
240        Required, if is_package is implemented"""
241        self.__get_module(fullname)  # eventually raises ImportError
242        return None
243    get_source = get_code  # same as get_code
244
245_importer = _SixMetaPathImporter(__name__)
246
247
248class _MovedItems(_LazyModule):
249
250    """Lazy loading of moved objects"""
251    __path__ = []  # mark as package
252
253
254_moved_attributes = [
255    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
256    MovedAttribute("file", "__builtin__", "io", "IOBase"),
257    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
258    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
259    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
260    MovedAttribute("intern", "__builtin__", "sys"),
261    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
262    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
263    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
264    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
265    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
266    MovedAttribute("reduce", "__builtin__", "functools"),
267    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
268    MovedAttribute("StringIO", "StringIO", "io"),
269    MovedAttribute("UserDict", "UserDict", "collections"),
270    MovedAttribute("UserList", "UserList", "collections"),
271    MovedAttribute("UserString", "UserString", "collections"),
272    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
273    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
274    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
275    MovedModule("builtins", "__builtin__"),
276    MovedModule("configparser", "ConfigParser"),
277    MovedModule("copyreg", "copy_reg"),
278    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
279    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
280    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
281    MovedModule("http_cookies", "Cookie", "http.cookies"),
282    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
283    MovedModule("html_parser", "HTMLParser", "html.parser"),
284    MovedModule("http_client", "httplib", "http.client"),
285    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
286    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
287    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
288    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
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("urlencode", "urllib", "urllib.parse"),
361    MovedAttribute("splitquery", "urllib", "urllib.parse"),
362    MovedAttribute("splittag", "urllib", "urllib.parse"),
363    MovedAttribute("splituser", "urllib", "urllib.parse"),
364    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
365    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
366    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
367    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
368    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
369]
370for attr in _urllib_parse_moved_attributes:
371    setattr(Module_six_moves_urllib_parse, attr.name, attr)
372del attr
373
374Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
375
376_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
377                      "moves.urllib_parse", "moves.urllib.parse")
378
379
380class Module_six_moves_urllib_error(_LazyModule):
381
382    """Lazy loading of moved objects in six.moves.urllib_error"""
383
384
385_urllib_error_moved_attributes = [
386    MovedAttribute("URLError", "urllib2", "urllib.error"),
387    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
388    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
389]
390for attr in _urllib_error_moved_attributes:
391    setattr(Module_six_moves_urllib_error, attr.name, attr)
392del attr
393
394Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
395
396_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
397                      "moves.urllib_error", "moves.urllib.error")
398
399
400class Module_six_moves_urllib_request(_LazyModule):
401
402    """Lazy loading of moved objects in six.moves.urllib_request"""
403
404
405_urllib_request_moved_attributes = [
406    MovedAttribute("urlopen", "urllib2", "urllib.request"),
407    MovedAttribute("install_opener", "urllib2", "urllib.request"),
408    MovedAttribute("build_opener", "urllib2", "urllib.request"),
409    MovedAttribute("pathname2url", "urllib", "urllib.request"),
410    MovedAttribute("url2pathname", "urllib", "urllib.request"),
411    MovedAttribute("getproxies", "urllib", "urllib.request"),
412    MovedAttribute("Request", "urllib2", "urllib.request"),
413    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
414    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
415    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
416    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
417    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
418    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
419    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
420    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
421    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
422    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
423    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
424    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
425    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
426    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
427    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
428    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
429    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
430    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
431    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
432    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
433    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
434    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
435    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
436    MovedAttribute("URLopener", "urllib", "urllib.request"),
437    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
438    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
439]
440for attr in _urllib_request_moved_attributes:
441    setattr(Module_six_moves_urllib_request, attr.name, attr)
442del attr
443
444Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
445
446_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
447                      "moves.urllib_request", "moves.urllib.request")
448
449
450class Module_six_moves_urllib_response(_LazyModule):
451
452    """Lazy loading of moved objects in six.moves.urllib_response"""
453
454
455_urllib_response_moved_attributes = [
456    MovedAttribute("addbase", "urllib", "urllib.response"),
457    MovedAttribute("addclosehook", "urllib", "urllib.response"),
458    MovedAttribute("addinfo", "urllib", "urllib.response"),
459    MovedAttribute("addinfourl", "urllib", "urllib.response"),
460]
461for attr in _urllib_response_moved_attributes:
462    setattr(Module_six_moves_urllib_response, attr.name, attr)
463del attr
464
465Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
466
467_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
468                      "moves.urllib_response", "moves.urllib.response")
469
470
471class Module_six_moves_urllib_robotparser(_LazyModule):
472
473    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
474
475
476_urllib_robotparser_moved_attributes = [
477    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
478]
479for attr in _urllib_robotparser_moved_attributes:
480    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
481del attr
482
483Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
484
485_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
486                      "moves.urllib_robotparser", "moves.urllib.robotparser")
487
488
489class Module_six_moves_urllib(types.ModuleType):
490
491    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
492    __path__ = []  # mark as package
493    parse = _importer._get_module("moves.urllib_parse")
494    error = _importer._get_module("moves.urllib_error")
495    request = _importer._get_module("moves.urllib_request")
496    response = _importer._get_module("moves.urllib_response")
497    robotparser = _importer._get_module("moves.urllib_robotparser")
498
499    def __dir__(self):
500        return ['parse', 'error', 'request', 'response', 'robotparser']
501
502_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
503                      "moves.urllib")
504
505
506def add_move(move):
507    """Add an item to six.moves."""
508    setattr(_MovedItems, move.name, move)
509
510
511def remove_move(name):
512    """Remove item from six.moves."""
513    try:
514        delattr(_MovedItems, name)
515    except AttributeError:
516        try:
517            del moves.__dict__[name]
518        except KeyError:
519            raise AttributeError("no such move, %r" % (name,))
520
521
522if PY3:
523    _meth_func = "__func__"
524    _meth_self = "__self__"
525
526    _func_closure = "__closure__"
527    _func_code = "__code__"
528    _func_defaults = "__defaults__"
529    _func_globals = "__globals__"
530else:
531    _meth_func = "im_func"
532    _meth_self = "im_self"
533
534    _func_closure = "func_closure"
535    _func_code = "func_code"
536    _func_defaults = "func_defaults"
537    _func_globals = "func_globals"
538
539
540try:
541    advance_iterator = next
542except NameError:
543    def advance_iterator(it):
544        return it.next()
545next = advance_iterator
546
547
548try:
549    callable = callable
550except NameError:
551    def callable(obj):
552        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
553
554
555if PY3:
556    def get_unbound_function(unbound):
557        return unbound
558
559    create_bound_method = types.MethodType
560
561    def create_unbound_method(func, cls):
562        return func
563
564    Iterator = object
565else:
566    def get_unbound_function(unbound):
567        return unbound.im_func
568
569    def create_bound_method(func, obj):
570        return types.MethodType(func, obj, obj.__class__)
571
572    def create_unbound_method(func, cls):
573        return types.MethodType(func, None, cls)
574
575    class Iterator(object):
576
577        def next(self):
578            return type(self).__next__(self)
579
580    callable = callable
581_add_doc(get_unbound_function,
582         """Get the function out of a possibly unbound function""")
583
584
585get_method_function = operator.attrgetter(_meth_func)
586get_method_self = operator.attrgetter(_meth_self)
587get_function_closure = operator.attrgetter(_func_closure)
588get_function_code = operator.attrgetter(_func_code)
589get_function_defaults = operator.attrgetter(_func_defaults)
590get_function_globals = operator.attrgetter(_func_globals)
591
592
593if PY3:
594    def iterkeys(d, **kw):
595        return iter(d.keys(**kw))
596
597    def itervalues(d, **kw):
598        return iter(d.values(**kw))
599
600    def iteritems(d, **kw):
601        return iter(d.items(**kw))
602
603    def iterlists(d, **kw):
604        return iter(d.lists(**kw))
605
606    viewkeys = operator.methodcaller("keys")
607
608    viewvalues = operator.methodcaller("values")
609
610    viewitems = operator.methodcaller("items")
611else:
612    def iterkeys(d, **kw):
613        return d.iterkeys(**kw)
614
615    def itervalues(d, **kw):
616        return d.itervalues(**kw)
617
618    def iteritems(d, **kw):
619        return d.iteritems(**kw)
620
621    def iterlists(d, **kw):
622        return d.iterlists(**kw)
623
624    viewkeys = operator.methodcaller("viewkeys")
625
626    viewvalues = operator.methodcaller("viewvalues")
627
628    viewitems = operator.methodcaller("viewitems")
629
630_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
631_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
632_add_doc(iteritems,
633         "Return an iterator over the (key, value) pairs of a dictionary.")
634_add_doc(iterlists,
635         "Return an iterator over the (key, [values]) pairs of a dictionary.")
636
637
638if PY3:
639    def b(s):
640        return s.encode("latin-1")
641
642    def u(s):
643        return s
644    unichr = chr
645    import struct
646    int2byte = struct.Struct(">B").pack
647    del struct
648    byte2int = operator.itemgetter(0)
649    indexbytes = operator.getitem
650    iterbytes = iter
651    import io
652    StringIO = io.StringIO
653    BytesIO = io.BytesIO
654    file = io.IOBase
655    _assertCountEqual = "assertCountEqual"
656    if sys.version_info[1] <= 1:
657        _assertRaisesRegex = "assertRaisesRegexp"
658        _assertRegex = "assertRegexpMatches"
659    else:
660        _assertRaisesRegex = "assertRaisesRegex"
661        _assertRegex = "assertRegex"
662else:
663    def b(s):
664        return s
665    # Workaround for standalone backslash
666
667    def u(s):
668        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
669    unichr = unichr
670    int2byte = chr
671
672    def byte2int(bs):
673        return ord(bs[0])
674
675    def indexbytes(buf, i):
676        return ord(buf[i])
677    iterbytes = functools.partial(itertools.imap, ord)
678    import StringIO
679    StringIO = BytesIO = StringIO.StringIO
680    _assertCountEqual = "assertItemsEqual"
681    _assertRaisesRegex = "assertRaisesRegexp"
682    _assertRegex = "assertRegexpMatches"
683_add_doc(b, """Byte literal""")
684_add_doc(u, """Text literal""")
685
686
687def assertCountEqual(self, *args, **kwargs):
688    return getattr(self, _assertCountEqual)(*args, **kwargs)
689
690
691def assertRaisesRegex(self, *args, **kwargs):
692    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
693
694
695def assertRegex(self, *args, **kwargs):
696    return getattr(self, _assertRegex)(*args, **kwargs)
697
698
699if PY3:
700    exec_ = getattr(moves.builtins, "exec")
701
702    def reraise(tp, value, tb=None):
703        if value is None:
704            value = tp()
705        if value.__traceback__ is not tb:
706            raise value.with_traceback(tb)
707        raise value
708
709else:
710    def exec_(_code_, _globs_=None, _locs_=None):
711        """Execute code in a namespace."""
712        if _globs_ is None:
713            frame = sys._getframe(1)
714            _globs_ = frame.f_globals
715            if _locs_ is None:
716                _locs_ = frame.f_locals
717            del frame
718        elif _locs_ is None:
719            _locs_ = _globs_
720        exec("""exec _code_ in _globs_, _locs_""")
721
722    exec_("""def reraise(tp, value, tb=None):
723    raise tp, value, tb
724""")
725
726
727if sys.version_info[:2] == (3, 2):
728    exec_("""def raise_from(value, from_value):
729    if from_value is None:
730        raise value
731    raise value from from_value
732""")
733elif sys.version_info[:2] > (3, 2):
734    exec_("""def raise_from(value, from_value):
735    raise value from from_value
736""")
737else:
738    def raise_from(value, from_value):
739        raise value
740
741
742print_ = getattr(moves.builtins, "print", None)
743if print_ is None:
744    def print_(*args, **kwargs):
745        """The new-style print function for Python 2.4 and 2.5."""
746        fp = kwargs.pop("file", sys.stdout)
747        if fp is None:
748            return
749
750        def write(data):
751            if not isinstance(data, basestring):
752                data = str(data)
753            # If the file has an encoding, encode unicode with it.
754            if (isinstance(fp, file) and
755                    isinstance(data, unicode) and
756                    fp.encoding is not None):
757                errors = getattr(fp, "errors", None)
758                if errors is None:
759                    errors = "strict"
760                data = data.encode(fp.encoding, errors)
761            fp.write(data)
762        want_unicode = False
763        sep = kwargs.pop("sep", None)
764        if sep is not None:
765            if isinstance(sep, unicode):
766                want_unicode = True
767            elif not isinstance(sep, str):
768                raise TypeError("sep must be None or a string")
769        end = kwargs.pop("end", None)
770        if end is not None:
771            if isinstance(end, unicode):
772                want_unicode = True
773            elif not isinstance(end, str):
774                raise TypeError("end must be None or a string")
775        if kwargs:
776            raise TypeError("invalid keyword arguments to print()")
777        if not want_unicode:
778            for arg in args:
779                if isinstance(arg, unicode):
780                    want_unicode = True
781                    break
782        if want_unicode:
783            newline = unicode("\n")
784            space = unicode(" ")
785        else:
786            newline = "\n"
787            space = " "
788        if sep is None:
789            sep = space
790        if end is None:
791            end = newline
792        for i, arg in enumerate(args):
793            if i:
794                write(sep)
795            write(arg)
796        write(end)
797if sys.version_info[:2] < (3, 3):
798    _print = print_
799
800    def print_(*args, **kwargs):
801        fp = kwargs.get("file", sys.stdout)
802        flush = kwargs.pop("flush", False)
803        _print(*args, **kwargs)
804        if flush and fp is not None:
805            fp.flush()
806
807_add_doc(reraise, """Reraise an exception.""")
808
809if sys.version_info[0:2] < (3, 4):
810    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
811              updated=functools.WRAPPER_UPDATES):
812        def wrapper(f):
813            f = functools.wraps(wrapped, assigned, updated)(f)
814            f.__wrapped__ = wrapped
815            return f
816        return wrapper
817else:
818    wraps = functools.wraps
819
820
821def with_metaclass(meta, *bases):
822    """Create a base class with a metaclass."""
823    # This requires a bit of explanation: the basic idea is to make a dummy
824    # metaclass for one level of class instantiation that replaces itself with
825    # the actual metaclass.
826    class metaclass(meta):
827
828        def __new__(cls, name, this_bases, d):
829            return meta(name, bases, d)
830    return type.__new__(metaclass, 'temporary_class', (), {})
831
832
833def add_metaclass(metaclass):
834    """Class decorator for creating a class with a metaclass."""
835    def wrapper(cls):
836        orig_vars = cls.__dict__.copy()
837        slots = orig_vars.get('__slots__')
838        if slots is not None:
839            if isinstance(slots, str):
840                slots = [slots]
841            for slots_var in slots:
842                orig_vars.pop(slots_var)
843        orig_vars.pop('__dict__', None)
844        orig_vars.pop('__weakref__', None)
845        return metaclass(cls.__name__, cls.__bases__, orig_vars)
846    return wrapper
847
848
849def python_2_unicode_compatible(klass):
850    """
851    A decorator that defines __unicode__ and __str__ methods under Python 2.
852    Under Python 3 it does nothing.
853
854    To support Python 2 and 3 with a single code base, define a __str__ method
855    returning text and apply this decorator to the class.
856    """
857    if PY2:
858        if '__str__' not in klass.__dict__:
859            raise ValueError("@python_2_unicode_compatible cannot be applied "
860                             "to %s because it doesn't define __str__()." %
861                             klass.__name__)
862        klass.__unicode__ = klass.__str__
863        import pyxb
864        klass.__str__ = lambda self: self.__unicode__().encode(pyxb._OutputEncoding)
865    return klass
866
867
868# Complete the moves implementation.
869# This code is at the end of this module to speed up module loading.
870# Turn this module into a package.
871__path__ = []  # required for PEP 302 and PEP 451
872__package__ = __name__  # see PEP 366 @ReservedAssignment
873if globals().get("__spec__") is not None:
874    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
875# Remove other six meta path importers, since they cause problems. This can
876# happen if six is removed from sys.modules and then reloaded. (Setuptools does
877# this for some reason.)
878if sys.meta_path:
879    for i, importer in enumerate(sys.meta_path):
880        # Here's some real nastiness: Another "instance" of the six module might
881        # be floating around. Therefore, we can't use isinstance() to check for
882        # the six meta path importer, since the other six instance will have
883        # inserted an importer with different class.
884        if (type(importer).__name__ == "_SixMetaPathImporter" and
885                importer.name == __name__):
886            del sys.meta_path[i]
887            break
888    del i, importer
889# Finally, add the importer to the meta path import hook.
890sys.meta_path.append(_importer)
891