1 """Utilities for writing code that runs on Python 2 and 3"""
3 # Copyright (c) 2010-2014 Benjamin Peterson
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:
12 # The above copyright notice and this permission notice shall be included in all
13 # copies or substantial portions of the Software.
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
23 from __future__ import absolute_import
30 __author__ = "Benjamin Peterson <benjamin@python.org>"
34 # Useful for very coarse version differentiation.
35 PY2 = sys.version_info[0] == 2
36 PY3 = sys.version_info[0] == 3
47 string_types = basestring,
48 integer_types = (int, long)
49 class_types = (type, types.ClassType)
53 if sys.platform.startswith("java"):
54 # Jython always uses 32 bits.
55 MAXSIZE = int((1 << 31) - 1)
57 # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
65 MAXSIZE = int((1 << 31) - 1)
68 MAXSIZE = int((1 << 63) - 1)
72 def _add_doc(func, doc):
73 """Add documentation to a function."""
77 def _import_module(name):
78 """Import module, returning the module after the last dot."""
80 return sys.modules[name]
83 class _LazyDescr(object):
85 def __init__(self, name):
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)
96 class MovedModule(_LazyDescr):
98 def __init__(self, name, old, new=None):
99 super(MovedModule, self).__init__(name)
108 return _import_module(self.mod)
110 def __getattr__(self, attr):
111 _module = self._resolve()
112 value = getattr(_module, attr)
113 setattr(self, attr, value)
117 class _LazyModule(types.ModuleType):
119 def __init__(self, name):
120 super(_LazyModule, self).__init__(name)
121 self.__doc__ = self.__class__.__doc__
124 attrs = ["__doc__", "__name__"]
125 attrs += [attr.name for attr in self._moved_attributes]
128 # Subclasses should override this
129 _moved_attributes = []
132 class MovedAttribute(_LazyDescr):
134 def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
135 super(MovedAttribute, self).__init__(name)
153 module = _import_module(self.mod)
154 return getattr(module, self.attr)
157 class _SixMetaPathImporter(object):
159 A meta path importer to import six.moves and its submodules.
161 This class implements a PEP302 finder and loader. It should be compatible
162 with Python 2.5 and all existing versions of Python3
164 def __init__(self, six_module_name):
165 self.name = six_module_name
166 self.known_modules = {}
168 def _add_module(self, mod, *fullnames):
169 for fullname in fullnames:
170 self.known_modules[self.name + "." + fullname] = mod
172 def _get_module(self, fullname):
173 return self.known_modules[self.name + "." + fullname]
175 def find_module(self, fullname, path=None):
176 if fullname in self.known_modules:
180 def __get_module(self, fullname):
182 return self.known_modules[fullname]
184 raise ImportError("This loader does not know module " + fullname)
186 def load_module(self, fullname):
188 # in case of a reload
189 return sys.modules[fullname]
192 mod = self.__get_module(fullname)
193 if isinstance(mod, MovedModule):
196 mod.__loader__ = self
197 sys.modules[fullname] = mod
200 def is_package(self, fullname):
202 Return true, if the named module is a package.
204 We need this method to get correct spec objects with
205 Python 3.4 (see PEP451)
207 return hasattr(self.__get_module(fullname), "__path__")
209 def get_code(self, fullname):
212 Required, if is_package is implemented"""
213 self.__get_module(fullname) # eventually raises ImportError
215 get_source = get_code # same as get_code
217 _importer = _SixMetaPathImporter(__name__)
220 class _MovedItems(_LazyModule):
221 """Lazy loading of moved objects"""
222 __path__ = [] # mark as package
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"),
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"),
292 for attr in _moved_attributes:
293 setattr(_MovedItems, attr.name, attr)
294 if isinstance(attr, MovedModule):
295 _importer._add_module(attr, "moves." + attr.name)
298 _MovedItems._moved_attributes = _moved_attributes
300 moves = _MovedItems(__name__ + ".moves")
301 _importer._add_module(moves, "moves")
304 class Module_six_moves_urllib_parse(_LazyModule):
305 """Lazy loading of moved objects in six.moves.urllib_parse"""
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"),
333 for attr in _urllib_parse_moved_attributes:
334 setattr(Module_six_moves_urllib_parse, attr.name, attr)
337 Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
339 _importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
340 "moves.urllib_parse", "moves.urllib.parse")
343 class Module_six_moves_urllib_error(_LazyModule):
344 """Lazy loading of moved objects in six.moves.urllib_error"""
347 _urllib_error_moved_attributes = [
348 MovedAttribute("URLError", "urllib2", "urllib.error"),
349 MovedAttribute("HTTPError", "urllib2", "urllib.error"),
350 MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
352 for attr in _urllib_error_moved_attributes:
353 setattr(Module_six_moves_urllib_error, attr.name, attr)
356 Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
358 _importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
359 "moves.urllib_error", "moves.urllib.error")
362 class Module_six_moves_urllib_request(_LazyModule):
363 """Lazy loading of moved objects in six.moves.urllib_request"""
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"),
401 for attr in _urllib_request_moved_attributes:
402 setattr(Module_six_moves_urllib_request, attr.name, attr)
405 Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
407 _importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
408 "moves.urllib_request", "moves.urllib.request")
411 class Module_six_moves_urllib_response(_LazyModule):
412 """Lazy loading of moved objects in six.moves.urllib_response"""
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"),
421 for attr in _urllib_response_moved_attributes:
422 setattr(Module_six_moves_urllib_response, attr.name, attr)
425 Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
427 _importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
428 "moves.urllib_response", "moves.urllib.response")
431 class Module_six_moves_urllib_robotparser(_LazyModule):
432 """Lazy loading of moved objects in six.moves.urllib_robotparser"""
435 _urllib_robotparser_moved_attributes = [
436 MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
438 for attr in _urllib_robotparser_moved_attributes:
439 setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
442 Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
444 _importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
445 "moves.urllib_robotparser", "moves.urllib.robotparser")
448 class 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")
458 return ['parse', 'error', 'request', 'response', 'robotparser']
460 _importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
465 """Add an item to six.moves."""
466 setattr(_MovedItems, move.name, move)
469 def remove_move(name):
470 """Remove item from six.moves."""
472 delattr(_MovedItems, name)
473 except AttributeError:
475 del moves.__dict__[name]
477 raise AttributeError("no such move, %r" % (name,))
481 _meth_func = "__func__"
482 _meth_self = "__self__"
484 _func_closure = "__closure__"
485 _func_code = "__code__"
486 _func_defaults = "__defaults__"
487 _func_globals = "__globals__"
489 _meth_func = "im_func"
490 _meth_self = "im_self"
492 _func_closure = "func_closure"
493 _func_code = "func_code"
494 _func_defaults = "func_defaults"
495 _func_globals = "func_globals"
499 advance_iterator = next
501 def advance_iterator(it):
503 next = advance_iterator
510 return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
514 def get_unbound_function(unbound):
517 create_bound_method = types.MethodType
521 def get_unbound_function(unbound):
522 return unbound.im_func
524 def create_bound_method(func, obj):
525 return types.MethodType(func, obj, obj.__class__)
527 class Iterator(object):
530 return type(self).__next__(self)
533 _add_doc(get_unbound_function,
534 """Get the function out of a possibly unbound function""")
537 get_method_function = operator.attrgetter(_meth_func)
538 get_method_self = operator.attrgetter(_meth_self)
539 get_function_closure = operator.attrgetter(_func_closure)
540 get_function_code = operator.attrgetter(_func_code)
541 get_function_defaults = operator.attrgetter(_func_defaults)
542 get_function_globals = operator.attrgetter(_func_globals)
546 def iterkeys(d, **kw):
547 return iter(d.keys(**kw))
549 def itervalues(d, **kw):
550 return iter(d.values(**kw))
552 def iteritems(d, **kw):
553 return iter(d.items(**kw))
555 def iterlists(d, **kw):
556 return iter(d.lists(**kw))
558 def iterkeys(d, **kw):
559 return iter(d.iterkeys(**kw))
561 def itervalues(d, **kw):
562 return iter(d.itervalues(**kw))
564 def iteritems(d, **kw):
565 return iter(d.iteritems(**kw))
567 def iterlists(d, **kw):
568 return iter(d.iterlists(**kw))
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.")
573 "Return an iterator over the (key, value) pairs of a dictionary.")
575 "Return an iterator over the (key, [values]) pairs of a dictionary.")
580 return s.encode("latin-1")
584 if sys.version_info[1] <= 1:
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
594 StringIO = io.StringIO
599 # Workaround for standalone backslash
601 return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
606 def indexbytes(buf, i):
609 return (ord(byte) for byte in buf)
611 StringIO = BytesIO = StringIO.StringIO
612 _add_doc(b, """Byte literal""")
613 _add_doc(u, """Text literal""")
617 exec_ = getattr(moves.builtins, "exec")
620 def reraise(tp, value, tb=None):
623 if value.__traceback__ is not tb:
624 raise value.with_traceback(tb)
628 def exec_(_code_, _globs_=None, _locs_=None):
629 """Execute code in a namespace."""
631 frame = sys._getframe(1)
632 _globs_ = frame.f_globals
634 _locs_ = frame.f_locals
638 exec("""exec _code_ in _globs_, _locs_""")
641 exec_("""def reraise(tp, value, tb=None):
646 print_ = getattr(moves.builtins, "print", 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)
654 if not isinstance(data, basestring):
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)
663 data = data.encode(fp.encoding, errors)
666 sep = kwargs.pop("sep", None)
668 if isinstance(sep, unicode):
670 elif not isinstance(sep, str):
671 raise TypeError("sep must be None or a string")
672 end = kwargs.pop("end", None)
674 if isinstance(end, unicode):
676 elif not isinstance(end, str):
677 raise TypeError("end must be None or a string")
679 raise TypeError("invalid keyword arguments to print()")
682 if isinstance(arg, unicode):
686 newline = unicode("\n")
695 for i, arg in enumerate(args):
701 _add_doc(reraise, """Reraise an exception.""")
703 if sys.version_info[0:2] < (3, 4):
704 def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
705 updated=functools.WRAPPER_UPDATES):
707 f = functools.wraps(wrapped)(f)
708 f.__wrapped__ = wrapped
712 wraps = functools.wraps
714 def 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', (), {})
725 def add_metaclass(metaclass):
726 """Class decorator for creating a class with a metaclass."""
728 orig_vars = cls.__dict__.copy()
729 slots = orig_vars.get('__slots__')
730 if slots is not None:
731 if isinstance(slots, str):
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)
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
745 if 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.)
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__):
761 # Finally, add the importer to the meta path import hook.
762 sys.meta_path.append(_importer)