1 """Utilities for writing code that runs on Python 2 and 3"""
7 __author__
= "Benjamin Peterson <benjamin@python.org>"
11 # True if we are running on Python 3.
12 PY3
= sys
.version_info
[0] == 3
23 string_types
= basestring
,
24 integer_types
= (int, long)
25 class_types
= (type, types
.ClassType
)
29 if sys
.platform
== "java":
30 # Jython always uses 32 bits.
31 MAXSIZE
= int((1 << 31) - 1)
33 # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
41 MAXSIZE
= int((1 << 31) - 1)
44 MAXSIZE
= int((1 << 63) - 1)
48 def _add_doc(func
, doc
):
49 """Add documentation to a function."""
53 def _import_module(name
):
54 """Import module, returning the module after the last dot."""
56 return sys
.modules
[name
]
59 class _LazyDescr(object):
61 def __init__(self
, name
):
64 def __get__(self
, obj
, tp
):
65 result
= self
._resolve
()
66 setattr(obj
, self
.name
, result
)
67 # This is a bit ugly, but it avoids running this again.
68 delattr(tp
, self
.name
)
72 class MovedModule(_LazyDescr
):
74 def __init__(self
, name
, old
, new
=None):
75 super(MovedModule
, self
).__init
__(name
)
84 return _import_module(self
.mod
)
87 class MovedAttribute(_LazyDescr
):
89 def __init__(self
, name
, old_mod
, new_mod
, old_attr
=None, new_attr
=None):
90 super(MovedAttribute
, self
).__init
__(name
)
108 module
= _import_module(self
.mod
)
109 return getattr(module
, self
.attr
)
113 class _MovedItems(types
.ModuleType
):
114 """Lazy loading of moved objects"""
117 _moved_attributes
= [
118 MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
119 MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
120 MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
121 MovedAttribute("map", "itertools", "builtins", "imap", "map"),
122 MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
123 MovedAttribute("reduce", "__builtin__", "functools"),
124 MovedAttribute("StringIO", "StringIO", "io"),
125 MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
126 MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
128 MovedModule("builtins", "__builtin__"),
129 MovedModule("configparser", "ConfigParser"),
130 MovedModule("copyreg", "copy_reg"),
131 MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
132 MovedModule("http_cookies", "Cookie", "http.cookies"),
133 MovedModule("html_entities", "htmlentitydefs", "html.entities"),
134 MovedModule("html_parser", "HTMLParser", "html.parser"),
135 MovedModule("http_client", "httplib", "http.client"),
136 MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
137 MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
138 MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
139 MovedModule("cPickle", "cPickle", "pickle"),
140 MovedModule("queue", "Queue"),
141 MovedModule("reprlib", "repr"),
142 MovedModule("socketserver", "SocketServer"),
143 MovedModule("tkinter", "Tkinter"),
144 MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
145 MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
146 MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
147 MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
148 MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
149 MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
150 MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
151 MovedModule("tkinter_colorchooser", "tkColorChooser",
152 "tkinter.colorchooser"),
153 MovedModule("tkinter_commondialog", "tkCommonDialog",
154 "tkinter.commondialog"),
155 MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
156 MovedModule("tkinter_font", "tkFont", "tkinter.font"),
157 MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
158 MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
159 "tkinter.simpledialog"),
160 MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
161 MovedModule("winreg", "_winreg"),
163 for attr
in _moved_attributes
:
164 setattr(_MovedItems
, attr
.name
, attr
)
167 moves
= sys
.modules
["django.utils.six.moves"] = _MovedItems("moves")
171 """Add an item to six.moves."""
172 setattr(_MovedItems
, move
.name
, move
)
175 def remove_move(name
):
176 """Remove item from six.moves."""
178 delattr(_MovedItems
, name
)
179 except AttributeError:
181 del moves
.__dict
__[name
]
183 raise AttributeError("no such move, %r" % (name
,))
187 _meth_func
= "__func__"
188 _meth_self
= "__self__"
190 _func_code
= "__code__"
191 _func_defaults
= "__defaults__"
194 _itervalues
= "values"
197 _meth_func
= "im_func"
198 _meth_self
= "im_self"
200 _func_code
= "func_code"
201 _func_defaults
= "func_defaults"
203 _iterkeys
= "iterkeys"
204 _itervalues
= "itervalues"
205 _iteritems
= "iteritems"
209 advance_iterator
= next
211 def advance_iterator(it
):
213 next
= advance_iterator
217 def get_unbound_function(unbound
):
223 return any("__call__" in klass
.__dict
__ for klass
in type(obj
).__mro
__)
225 def get_unbound_function(unbound
):
226 return unbound
.im_func
228 class Iterator(object):
231 return type(self
).__next
__(self
)
234 _add_doc(get_unbound_function
,
235 """Get the function out of a possibly unbound function""")
238 get_method_function
= operator
.attrgetter(_meth_func
)
239 get_method_self
= operator
.attrgetter(_meth_self
)
240 get_function_code
= operator
.attrgetter(_func_code
)
241 get_function_defaults
= operator
.attrgetter(_func_defaults
)
245 """Return an iterator over the keys of a dictionary."""
246 return iter(getattr(d
, _iterkeys
)())
249 """Return an iterator over the values of a dictionary."""
250 return iter(getattr(d
, _itervalues
)())
253 """Return an iterator over the (key, value) pairs of a dictionary."""
254 return iter(getattr(d
, _iteritems
)())
259 return s
.encode("latin-1")
262 if sys
.version_info
[1] <= 1:
266 # This is about 2x faster than the implementation above on 3.2+
267 int2byte
= operator
.methodcaller("to_bytes", 1, "big")
269 StringIO
= io
.StringIO
275 return unicode(s
, "unicode_escape")
278 StringIO
= BytesIO
= StringIO
.StringIO
279 _add_doc(b
, """Byte literal""")
280 _add_doc(u
, """Text literal""")
285 exec_
= getattr(builtins
, "exec")
288 def reraise(tp
, value
, tb
=None):
289 if value
.__traceback
__ is not tb
:
290 raise value
.with_traceback(tb
)
294 print_
= getattr(builtins
, "print")
298 def exec_(code
, globs
=None, locs
=None):
299 """Execute code in a namespace."""
301 frame
= sys
._getframe
(1)
302 globs
= frame
.f_globals
304 locs
= frame
.f_locals
308 exec("""exec code in globs, locs""")
311 exec_("""def reraise(tp, value, tb=None):
316 def print_(*args
, **kwargs
):
317 """The new-style print function."""
318 fp
= kwargs
.pop("file", sys
.stdout
)
322 if not isinstance(data
, basestring
):
326 sep
= kwargs
.pop("sep", None)
328 if isinstance(sep
, unicode):
330 elif not isinstance(sep
, str):
331 raise TypeError("sep must be None or a string")
332 end
= kwargs
.pop("end", None)
334 if isinstance(end
, unicode):
336 elif not isinstance(end
, str):
337 raise TypeError("end must be None or a string")
339 raise TypeError("invalid keyword arguments to print()")
342 if isinstance(arg
, unicode):
346 newline
= unicode("\n")
355 for i
, arg
in enumerate(args
):
361 _add_doc(reraise
, """Reraise an exception.""")
364 def with_metaclass(meta
, base
=object):
365 """Create a base class with a metaclass."""
366 return meta("NewBase", (base
,), {})
369 ### Additional customizations for Django ###
374 _iterlists
= "iterlists"
377 """Return an iterator over the values of a MultiValueDict."""
378 return getattr(d
, _iterlists
)()
381 add_move(MovedModule("_dummy_thread", "dummy_thread"))
382 add_move(MovedModule("_thread", "thread"))