1"""Utilities for writing code that runs on Python 2 and 3"""
2
3# Copyright (c) 2010-2014 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 operator
27import sys
28import types
29
30__author__ = "Benjamin Peterson <benjamin@python.org>"
31__version__ = "1.8.0"
32
33
34# Useful for very coarse version differentiation.
35PY2 = sys.version_info[0] == 2
36PY3 = sys.version_info[0] == 3
37
38if PY3:
39    string_types = str,
40    integer_types = int,
41    class_types = type,
42    text_type = str
43    binary_type = bytes
44
45    MAXSIZE = sys.maxsize
46else:
47    string_types = basestring,
48    integer_types = (int, long)
49    class_types = (type, types.ClassType)
50    text_type = unicode
51    binary_type = str
52
53    if sys.platform.startswith("java"):
54        # Jython always uses 32 bits.
55        MAXSIZE = int((1 << 31) - 1)
56    else:
57        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
58        class X(object):
59            def __len__(self):
60                return 1 << 31
61        try:
62            len(X())
63        except OverflowError:
64            # 32-bit
65            MAXSIZE = int((1 << 31) - 1)
66        else:
67            # 64-bit
68            MAXSIZE = int((1 << 63) - 1)
69        del X
70
71
72def _add_doc(func, doc):
73    """Add documentation to a function."""
74    func.__doc__ = doc
75
76
77def _import_module(name):
78    """Import module, returning the module after the last dot."""
79    __import__(name)
80    return sys.modules[name]
81
82
83class _LazyDescr(object):
84
85    def __init__(self, name):
86        self.name = name
87
88    def __get__(self, obj, tp):
89        result = self._resolve()
90        setattr(obj, self.name, result) # Invokes __set__.
91        # This is a bit ugly, but it avoids running this again.
92        delattr(obj.__class__, self.name)
93        return result
94
95
96class MovedModule(_LazyDescr):
97
98    def __init__(self, name, old, new=None):
99        super(MovedModule, self).__init__(name)
100        if PY3:
101            if new is None:
102                new = name
103            self.mod = new
104        else:
105            self.mod = old
106
107    def _resolve(self):
108        return _import_module(self.mod)
109
110    def __getattr__(self, attr):
111        _module = self._resolve()
112        value = getattr(_module, attr)
113        setattr(self, attr, value)
114        return value
115
116
117class _LazyModule(types.ModuleType):
118
119    def __init__(self, name):
120        super(_LazyModule, self).__init__(name)
121        self.__doc__ = self.__class__.__doc__
122
123    def __dir__(self):
124        attrs = ["__doc__", "__name__"]
125        attrs += [attr.name for attr in self._moved_attributes]
126        return attrs
127
128    # Subclasses should override this
129    _moved_attributes = []
130
131
132class MovedAttribute(_LazyDescr):
133
134    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
135        super(MovedAttribute, self).__init__(name)
136        if PY3:
137            if new_mod is None:
138                new_mod = name
139            self.mod = new_mod
140            if new_attr is None:
141                if old_attr is None:
142                    new_attr = name
143                else:
144                    new_attr = old_attr
145            self.attr = new_attr
146        else:
147            self.mod = old_mod
148            if old_attr is None:
149                old_attr = name
150            self.attr = old_attr
151
152    def _resolve(self):
153        module = _import_module(self.mod)
154        return getattr(module, self.attr)
155
156
157class _SixMetaPathImporter(object):
158    """
159    A meta path importer to import six.moves and its submodules.
160
161    This class implements a PEP302 finder and loader. It should be compatible
162    with Python 2.5 and all existing versions of Python3
163    """
164    def __init__(self, six_module_name):
165        self.name = six_module_name
166        self.known_modules = {}
167
168    def _add_module(self, mod, *fullnames):
169        for fullname in fullnames:
170            self.known_modules[self.name + "." + fullname] = mod
171
172    def _get_module(self, fullname):
173        return self.known_modules[self.name + "." + fullname]
174
175    def find_module(self, fullname, path=None):
176        if fullname in self.known_modules:
177            return self
178        return None
179
180    def __get_module(self, fullname):
181        try:
182            return self.known_modules[fullname]
183        except KeyError:
184            raise ImportError("This loader does not know module " + fullname)
185
186    def load_module(self, fullname):
187        try:
188            # in case of a reload
189            return sys.modules[fullname]
190        except KeyError:
191            pass
192        mod = self.__get_module(fullname)
193        if isinstance(mod, MovedModule):
194            mod = mod._resolve()
195        else:
196            mod.__loader__ = self
197        sys.modules[fullname] = mod
198        return mod
199
200    def is_package(self, fullname):
201        """
202        Return true, if the named module is a package.
203
204        We need this method to get correct spec objects with
205        Python 3.4 (see PEP451)
206        """
207        return hasattr(self.__get_module(fullname), "__path__")
208
209    def get_code(self, fullname):
210        """Return None
211
212        Required, if is_package is implemented"""
213        self.__get_module(fullname)  # eventually raises ImportError
214        return None
215    get_source = get_code  # same as get_code
216
217_importer = _SixMetaPathImporter(__name__)
218
219
220class _MovedItems(_LazyModule):
221    """Lazy loading of moved objects"""
222    __path__ = []  # mark as package
223
224
225_moved_attributes = [
226    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
227    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
228    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
229    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
230    MovedAttribute("intern", "__builtin__", "sys"),
231    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
232    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
233    MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
234    MovedAttribute("reduce", "__builtin__", "functools"),
235    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
236    MovedAttribute("StringIO", "StringIO", "io"),
237    MovedAttribute("UserDict", "UserDict", "collections"),
238    MovedAttribute("UserList", "UserList", "collections"),
239    MovedAttribute("UserString", "UserString", "collections"),
240    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
241    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
242    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
243
244    MovedModule("builtins", "__builtin__"),
245    MovedModule("configparser", "ConfigParser"),
246    MovedModule("copyreg", "copy_reg"),
247    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
248    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
249    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
250    MovedModule("http_cookies", "Cookie", "http.cookies"),
251    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
252    MovedModule("html_parser", "HTMLParser", "html.parser"),
253    MovedModule("http_client", "httplib", "http.client"),
254    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
255    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
256    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
257    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
258    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
259    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
260    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
261    MovedModule("cPickle", "cPickle", "pickle"),
262    MovedModule("queue", "Queue"),
263    MovedModule("reprlib", "repr"),
264    MovedModule("socketserver", "SocketServer"),
265    MovedModule("_thread", "thread", "_thread"),
266    MovedModule("tkinter", "Tkinter"),
267    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
268    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
269    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
270    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
271    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
272    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
273    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
274    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
275    MovedModule("tkinter_colorchooser", "tkColorChooser",
276                "tkinter.colorchooser"),
277    MovedModule("tkinter_commondialog", "tkCommonDialog",
278                "tkinter.commondialog"),
279    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
280    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
281    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
282    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
283                "tkinter.simpledialog"),
284    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
285    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
286    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
287    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
288    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
289    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
290    MovedModule("winreg", "_winreg"),
291]
292for attr in _moved_attributes:
293    setattr(_MovedItems, attr.name, attr)
294    if isinstance(attr, MovedModule):
295        _importer._add_module(attr, "moves." + attr.name)
296del attr
297
298_MovedItems._moved_attributes = _moved_attributes
299
300moves = _MovedItems(__name__ + ".moves")
301_importer._add_module(moves, "moves")
302
303
304class Module_six_moves_urllib_parse(_LazyModule):
305    """Lazy loading of moved objects in six.moves.urllib_parse"""
306
307
308_urllib_parse_moved_attributes = [
309    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
310    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
311    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
312    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
313    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
314    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
315    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
316    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
317    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
318    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
319    MovedAttribute("quote", "urllib", "urllib.parse"),
320    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
321    MovedAttribute("unquote", "urllib", "urllib.parse"),
322    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
323    MovedAttribute("urlencode", "urllib", "urllib.parse"),
324    MovedAttribute("splitquery", "urllib", "urllib.parse"),
325    MovedAttribute("splittag", "urllib", "urllib.parse"),
326    MovedAttribute("splituser", "urllib", "urllib.parse"),
327    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
328    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
329    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
330    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
331    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
332]
333for attr in _urllib_parse_moved_attributes:
334    setattr(Module_six_moves_urllib_parse, attr.name, attr)
335del attr
336
337Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
338
339_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
340                      "moves.urllib_parse", "moves.urllib.parse")
341
342
343class Module_six_moves_urllib_error(_LazyModule):
344    """Lazy loading of moved objects in six.moves.urllib_error"""
345
346
347_urllib_error_moved_attributes = [
348    MovedAttribute("URLError", "urllib2", "urllib.error"),
349    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
350    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
351]
352for attr in _urllib_error_moved_attributes:
353    setattr(Module_six_moves_urllib_error, attr.name, attr)
354del attr
355
356Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
357
358_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
359                      "moves.urllib_error", "moves.urllib.error")
360
361
362class Module_six_moves_urllib_request(_LazyModule):
363    """Lazy loading of moved objects in six.moves.urllib_request"""
364
365
366_urllib_request_moved_attributes = [
367    MovedAttribute("urlopen", "urllib2", "urllib.request"),
368    MovedAttribute("install_opener", "urllib2", "urllib.request"),
369    MovedAttribute("build_opener", "urllib2", "urllib.request"),
370    MovedAttribute("pathname2url", "urllib", "urllib.request"),
371    MovedAttribute("url2pathname", "urllib", "urllib.request"),
372    MovedAttribute("getproxies", "urllib", "urllib.request"),
373    MovedAttribute("Request", "urllib2", "urllib.request"),
374    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
375    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
376    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
377    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
378    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
379    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
380    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
381    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
382    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
383    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
384    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
385    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
386    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
387    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
388    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
389    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
390    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
391    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
392    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
393    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
394    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
395    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
396    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
397    MovedAttribute("URLopener", "urllib", "urllib.request"),
398    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
399    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
400]
401for attr in _urllib_request_moved_attributes:
402    setattr(Module_six_moves_urllib_request, attr.name, attr)
403del attr
404
405Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
406
407_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
408                      "moves.urllib_request", "moves.urllib.request")
409
410
411class Module_six_moves_urllib_response(_LazyModule):
412    """Lazy loading of moved objects in six.moves.urllib_response"""
413
414
415_urllib_response_moved_attributes = [
416    MovedAttribute("addbase", "urllib", "urllib.response"),
417    MovedAttribute("addclosehook", "urllib", "urllib.response"),
418    MovedAttribute("addinfo", "urllib", "urllib.response"),
419    MovedAttribute("addinfourl", "urllib", "urllib.response"),
420]
421for attr in _urllib_response_moved_attributes:
422    setattr(Module_six_moves_urllib_response, attr.name, attr)
423del attr
424
425Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
426
427_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
428                      "moves.urllib_response", "moves.urllib.response")
429
430
431class Module_six_moves_urllib_robotparser(_LazyModule):
432    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
433
434
435_urllib_robotparser_moved_attributes = [
436    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
437]
438for attr in _urllib_robotparser_moved_attributes:
439    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
440del attr
441
442Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
443
444_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
445                      "moves.urllib_robotparser", "moves.urllib.robotparser")
446
447
448class Module_six_moves_urllib(types.ModuleType):
449    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
450    __path__ = []  # mark as package
451    parse = _importer._get_module("moves.urllib_parse")
452    error = _importer._get_module("moves.urllib_error")
453    request = _importer._get_module("moves.urllib_request")
454    response = _importer._get_module("moves.urllib_response")
455    robotparser = _importer._get_module("moves.urllib_robotparser")
456
457    def __dir__(self):
458        return ['parse', 'error', 'request', 'response', 'robotparser']
459
460_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
461                      "moves.urllib")
462
463
464def add_move(move):
465    """Add an item to six.moves."""
466    setattr(_MovedItems, move.name, move)
467
468
469def remove_move(name):
470    """Remove item from six.moves."""
471    try:
472        delattr(_MovedItems, name)
473    except AttributeError:
474        try:
475            del moves.__dict__[name]
476        except KeyError:
477            raise AttributeError("no such move, %r" % (name,))
478
479
480if PY3:
481    _meth_func = "__func__"
482    _meth_self = "__self__"
483
484    _func_closure = "__closure__"
485    _func_code = "__code__"
486    _func_defaults = "__defaults__"
487    _func_globals = "__globals__"
488else:
489    _meth_func = "im_func"
490    _meth_self = "im_self"
491
492    _func_closure = "func_closure"
493    _func_code = "func_code"
494    _func_defaults = "func_defaults"
495    _func_globals = "func_globals"
496
497
498try:
499    advance_iterator = next
500except NameError:
501    def advance_iterator(it):
502        return it.next()
503next = advance_iterator
504
505
506try:
507    callable = callable
508except NameError:
509    def callable(obj):
510        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
511
512
513if PY3:
514    def get_unbound_function(unbound):
515        return unbound
516
517    create_bound_method = types.MethodType
518
519    Iterator = object
520else:
521    def get_unbound_function(unbound):
522        return unbound.im_func
523
524    def create_bound_method(func, obj):
525        return types.MethodType(func, obj, obj.__class__)
526
527    class Iterator(object):
528
529        def next(self):
530            return type(self).__next__(self)
531
532    callable = callable
533_add_doc(get_unbound_function,
534         """Get the function out of a possibly unbound function""")
535
536
537get_method_function = operator.attrgetter(_meth_func)
538get_method_self = operator.attrgetter(_meth_self)
539get_function_closure = operator.attrgetter(_func_closure)
540get_function_code = operator.attrgetter(_func_code)
541get_function_defaults = operator.attrgetter(_func_defaults)
542get_function_globals = operator.attrgetter(_func_globals)
543
544
545if PY3:
546    def iterkeys(d, **kw):
547        return iter(d.keys(**kw))
548
549    def itervalues(d, **kw):
550        return iter(d.values(**kw))
551
552    def iteritems(d, **kw):
553        return iter(d.items(**kw))
554
555    def iterlists(d, **kw):
556        return iter(d.lists(**kw))
557else:
558    def iterkeys(d, **kw):
559        return iter(d.iterkeys(**kw))
560
561    def itervalues(d, **kw):
562        return iter(d.itervalues(**kw))
563
564    def iteritems(d, **kw):
565        return iter(d.iteritems(**kw))
566
567    def iterlists(d, **kw):
568        return iter(d.iterlists(**kw))
569
570_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
571_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
572_add_doc(iteritems,
573         "Return an iterator over the (key, value) pairs of a dictionary.")
574_add_doc(iterlists,
575         "Return an iterator over the (key, [values]) pairs of a dictionary.")
576
577
578if PY3:
579    def b(s):
580        return s.encode("latin-1")
581    def u(s):
582        return s
583    unichr = chr
584    if sys.version_info[1] <= 1:
585        def int2byte(i):
586            return bytes((i,))
587    else:
588        # This is about 2x faster than the implementation above on 3.2+
589        int2byte = operator.methodcaller("to_bytes", 1, "big")
590    byte2int = operator.itemgetter(0)
591    indexbytes = operator.getitem
592    iterbytes = iter
593    import io
594    StringIO = io.StringIO
595    BytesIO = io.BytesIO
596else:
597    def b(s):
598        return s
599    # Workaround for standalone backslash
600    def u(s):
601        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
602    unichr = unichr
603    int2byte = chr
604    def byte2int(bs):
605        return ord(bs[0])
606    def indexbytes(buf, i):
607        return ord(buf[i])
608    def iterbytes(buf):
609        return (ord(byte) for byte in buf)
610    import StringIO
611    StringIO = BytesIO = StringIO.StringIO
612_add_doc(b, """Byte literal""")
613_add_doc(u, """Text literal""")
614
615
616if PY3:
617    exec_ = getattr(moves.builtins, "exec")
618
619
620    def reraise(tp, value, tb=None):
621        if value is None:
622            value = tp()
623        if value.__traceback__ is not tb:
624            raise value.with_traceback(tb)
625        raise value
626
627else:
628    def exec_(_code_, _globs_=None, _locs_=None):
629        """Execute code in a namespace."""
630        if _globs_ is None:
631            frame = sys._getframe(1)
632            _globs_ = frame.f_globals
633            if _locs_ is None:
634                _locs_ = frame.f_locals
635            del frame
636        elif _locs_ is None:
637            _locs_ = _globs_
638        exec("""exec _code_ in _globs_, _locs_""")
639
640
641    exec_("""def reraise(tp, value, tb=None):
642    raise tp, value, tb
643""")
644
645
646print_ = getattr(moves.builtins, "print", None)
647if print_ is None:
648    def print_(*args, **kwargs):
649        """The new-style print function for Python 2.4 and 2.5."""
650        fp = kwargs.pop("file", sys.stdout)
651        if fp is None:
652            return
653        def write(data):
654            if not isinstance(data, basestring):
655                data = str(data)
656            # If the file has an encoding, encode unicode with it.
657            if (isinstance(fp, file) and
658                isinstance(data, unicode) and
659                fp.encoding is not None):
660                errors = getattr(fp, "errors", None)
661                if errors is None:
662                    errors = "strict"
663                data = data.encode(fp.encoding, errors)
664            fp.write(data)
665        want_unicode = False
666        sep = kwargs.pop("sep", None)
667        if sep is not None:
668            if isinstance(sep, unicode):
669                want_unicode = True
670            elif not isinstance(sep, str):
671                raise TypeError("sep must be None or a string")
672        end = kwargs.pop("end", None)
673        if end is not None:
674            if isinstance(end, unicode):
675                want_unicode = True
676            elif not isinstance(end, str):
677                raise TypeError("end must be None or a string")
678        if kwargs:
679            raise TypeError("invalid keyword arguments to print()")
680        if not want_unicode:
681            for arg in args:
682                if isinstance(arg, unicode):
683                    want_unicode = True
684                    break
685        if want_unicode:
686            newline = unicode("\n")
687            space = unicode(" ")
688        else:
689            newline = "\n"
690            space = " "
691        if sep is None:
692            sep = space
693        if end is None:
694            end = newline
695        for i, arg in enumerate(args):
696            if i:
697                write(sep)
698            write(arg)
699        write(end)
700
701_add_doc(reraise, """Reraise an exception.""")
702
703if sys.version_info[0:2] < (3, 4):
704    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
705              updated=functools.WRAPPER_UPDATES):
706        def wrapper(f):
707            f = functools.wraps(wrapped)(f)
708            f.__wrapped__ = wrapped
709            return f
710        return wrapper
711else:
712    wraps = functools.wraps
713
714def with_metaclass(meta, *bases):
715    """Create a base class with a metaclass."""
716    # This requires a bit of explanation: the basic idea is to make a dummy
717    # metaclass for one level of class instantiation that replaces itself with
718    # the actual metaclass.
719    class metaclass(meta):
720        def __new__(cls, name, this_bases, d):
721            return meta(name, bases, d)
722    return type.__new__(metaclass, 'temporary_class', (), {})
723
724
725def add_metaclass(metaclass):
726    """Class decorator for creating a class with a metaclass."""
727    def wrapper(cls):
728        orig_vars = cls.__dict__.copy()
729        slots = orig_vars.get('__slots__')
730        if slots is not None:
731            if isinstance(slots, str):
732                slots = [slots]
733            for slots_var in slots:
734                orig_vars.pop(slots_var)
735        orig_vars.pop('__dict__', None)
736        orig_vars.pop('__weakref__', None)
737        return metaclass(cls.__name__, cls.__bases__, orig_vars)
738    return wrapper
739
740# Complete the moves implementation.
741# This code is at the end of this module to speed up module loading.
742# Turn this module into a package.
743__path__ = []  # required for PEP 302 and PEP 451
744__package__ = __name__  # see PEP 366 @ReservedAssignment
745if globals().get("__spec__") is not None:
746    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
747# Remove other six meta path importers, since they cause problems. This can
748# happen if six is removed from sys.modules and then reloaded. (Setuptools does
749# this for some reason.)
750if sys.meta_path:
751    for i, importer in enumerate(sys.meta_path):
752        # Here's some real nastiness: Another "instance" of the six module might
753        # be floating around. Therefore, we can't use isinstance() to check for
754        # the six meta path importer, since the other six instance will have
755        # inserted an importer with different class.
756        if (type(importer).__name__ == "_SixMetaPathImporter" and
757            importer.name == __name__):
758            del sys.meta_path[i]
759            break
760    del i, importer
761# Finally, add the importer to the meta path import hook.
762sys.meta_path.append(_importer)
763