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