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