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