root / env / lib / python2.7 / site-packages / django / utils / six.py @ 1a305335
History | View | Annotate | Download (10.6 KB)
1 | 1a305335 | officers | """Utilities for writing code that runs on Python 2 and 3"""
|
---|---|---|---|
2 | |||
3 | import operator |
||
4 | import sys |
||
5 | import types |
||
6 | |||
7 | __author__ = "Benjamin Peterson <benjamin@python.org>"
|
||
8 | __version__ = "1.2.0"
|
||
9 | |||
10 | |||
11 | # True if we are running on Python 3.
|
||
12 | PY3 = sys.version_info[0] == 3 |
||
13 | |||
14 | if PY3:
|
||
15 | string_types = str,
|
||
16 | integer_types = int,
|
||
17 | class_types = type,
|
||
18 | text_type = str
|
||
19 | binary_type = bytes
|
||
20 | |||
21 | MAXSIZE = sys.maxsize |
||
22 | else:
|
||
23 | string_types = basestring,
|
||
24 | integer_types = (int, long) |
||
25 | class_types = (type, types.ClassType)
|
||
26 | text_type = unicode
|
||
27 | binary_type = str
|
||
28 | |||
29 | if sys.platform == "java": |
||
30 | # Jython always uses 32 bits.
|
||
31 | MAXSIZE = int((1 << 31) - 1) |
||
32 | else:
|
||
33 | # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
|
||
34 | class X(object): |
||
35 | def __len__(self): |
||
36 | return 1 << 31 |
||
37 | try:
|
||
38 | len(X())
|
||
39 | except OverflowError: |
||
40 | # 32-bit
|
||
41 | MAXSIZE = int((1 << 31) - 1) |
||
42 | else:
|
||
43 | # 64-bit
|
||
44 | MAXSIZE = int((1 << 63) - 1) |
||
45 | del X
|
||
46 | |||
47 | |||
48 | def _add_doc(func, doc): |
||
49 | """Add documentation to a function."""
|
||
50 | func.__doc__ = doc |
||
51 | |||
52 | |||
53 | def _import_module(name): |
||
54 | """Import module, returning the module after the last dot."""
|
||
55 | __import__(name)
|
||
56 | return sys.modules[name]
|
||
57 | |||
58 | |||
59 | class _LazyDescr(object): |
||
60 | |||
61 | def __init__(self, name): |
||
62 | self.name = name
|
||
63 | |||
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) |
||
69 | return result
|
||
70 | |||
71 | |||
72 | class MovedModule(_LazyDescr): |
||
73 | |||
74 | def __init__(self, name, old, new=None): |
||
75 | super(MovedModule, self).__init__(name) |
||
76 | if PY3:
|
||
77 | if new is None: |
||
78 | new = name |
||
79 | self.mod = new
|
||
80 | else:
|
||
81 | self.mod = old
|
||
82 | |||
83 | def _resolve(self): |
||
84 | return _import_module(self.mod) |
||
85 | |||
86 | |||
87 | class MovedAttribute(_LazyDescr): |
||
88 | |||
89 | def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): |
||
90 | super(MovedAttribute, self).__init__(name) |
||
91 | if PY3:
|
||
92 | if new_mod is None: |
||
93 | new_mod = name |
||
94 | self.mod = new_mod
|
||
95 | if new_attr is None: |
||
96 | if old_attr is None: |
||
97 | new_attr = name |
||
98 | else:
|
||
99 | new_attr = old_attr |
||
100 | self.attr = new_attr
|
||
101 | else:
|
||
102 | self.mod = old_mod
|
||
103 | if old_attr is None: |
||
104 | old_attr = name |
||
105 | self.attr = old_attr
|
||
106 | |||
107 | def _resolve(self): |
||
108 | module = _import_module(self.mod)
|
||
109 | return getattr(module, self.attr) |
||
110 | |||
111 | |||
112 | |||
113 | class _MovedItems(types.ModuleType): |
||
114 | """Lazy loading of moved objects"""
|
||
115 | |||
116 | |||
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"), |
||
127 | |||
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"), |
||
162 | ] |
||
163 | for attr in _moved_attributes: |
||
164 | setattr(_MovedItems, attr.name, attr)
|
||
165 | del attr
|
||
166 | |||
167 | moves = sys.modules["django.utils.six.moves"] = _MovedItems("moves") |
||
168 | |||
169 | |||
170 | def add_move(move): |
||
171 | """Add an item to six.moves."""
|
||
172 | setattr(_MovedItems, move.name, move)
|
||
173 | |||
174 | |||
175 | def remove_move(name): |
||
176 | """Remove item from six.moves."""
|
||
177 | try:
|
||
178 | delattr(_MovedItems, name)
|
||
179 | except AttributeError: |
||
180 | try:
|
||
181 | del moves.__dict__[name]
|
||
182 | except KeyError: |
||
183 | raise AttributeError("no such move, %r" % (name,)) |
||
184 | |||
185 | |||
186 | if PY3:
|
||
187 | _meth_func = "__func__"
|
||
188 | _meth_self = "__self__"
|
||
189 | |||
190 | _func_code = "__code__"
|
||
191 | _func_defaults = "__defaults__"
|
||
192 | |||
193 | _iterkeys = "keys"
|
||
194 | _itervalues = "values"
|
||
195 | _iteritems = "items"
|
||
196 | else:
|
||
197 | _meth_func = "im_func"
|
||
198 | _meth_self = "im_self"
|
||
199 | |||
200 | _func_code = "func_code"
|
||
201 | _func_defaults = "func_defaults"
|
||
202 | |||
203 | _iterkeys = "iterkeys"
|
||
204 | _itervalues = "itervalues"
|
||
205 | _iteritems = "iteritems"
|
||
206 | |||
207 | |||
208 | try:
|
||
209 | advance_iterator = next
|
||
210 | except NameError: |
||
211 | def advance_iterator(it): |
||
212 | return it.next()
|
||
213 | next = advance_iterator |
||
214 | |||
215 | |||
216 | if PY3:
|
||
217 | def get_unbound_function(unbound): |
||
218 | return unbound
|
||
219 | |||
220 | Iterator = object
|
||
221 | |||
222 | def callable(obj): |
||
223 | return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) |
||
224 | else:
|
||
225 | def get_unbound_function(unbound): |
||
226 | return unbound.im_func
|
||
227 | |||
228 | class Iterator(object): |
||
229 | |||
230 | def next(self): |
||
231 | return type(self).__next__(self) |
||
232 | |||
233 | callable = callable
|
||
234 | _add_doc(get_unbound_function, |
||
235 | """Get the function out of a possibly unbound function""")
|
||
236 | |||
237 | |||
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) |
||
242 | |||
243 | |||
244 | def iterkeys(d): |
||
245 | """Return an iterator over the keys of a dictionary."""
|
||
246 | return iter(getattr(d, _iterkeys)()) |
||
247 | |||
248 | def itervalues(d): |
||
249 | """Return an iterator over the values of a dictionary."""
|
||
250 | return iter(getattr(d, _itervalues)()) |
||
251 | |||
252 | def iteritems(d): |
||
253 | """Return an iterator over the (key, value) pairs of a dictionary."""
|
||
254 | return iter(getattr(d, _iteritems)()) |
||
255 | |||
256 | |||
257 | if PY3:
|
||
258 | def b(s): |
||
259 | return s.encode("latin-1") |
||
260 | def u(s): |
||
261 | return s
|
||
262 | if sys.version_info[1] <= 1: |
||
263 | def int2byte(i): |
||
264 | return bytes((i,)) |
||
265 | else:
|
||
266 | # This is about 2x faster than the implementation above on 3.2+
|
||
267 | int2byte = operator.methodcaller("to_bytes", 1, "big") |
||
268 | import io |
||
269 | StringIO = io.StringIO |
||
270 | BytesIO = io.BytesIO |
||
271 | else:
|
||
272 | def b(s): |
||
273 | return s
|
||
274 | def u(s): |
||
275 | return unicode(s, "unicode_escape") |
||
276 | int2byte = chr
|
||
277 | import StringIO |
||
278 | StringIO = BytesIO = StringIO.StringIO |
||
279 | _add_doc(b, """Byte literal""")
|
||
280 | _add_doc(u, """Text literal""")
|
||
281 | |||
282 | |||
283 | if PY3:
|
||
284 | import builtins |
||
285 | exec_ = getattr(builtins, "exec") |
||
286 | |||
287 | |||
288 | def reraise(tp, value, tb=None): |
||
289 | if value.__traceback__ is not tb: |
||
290 | raise value.with_traceback(tb)
|
||
291 | raise value
|
||
292 | |||
293 | |||
294 | print_ = getattr(builtins, "print") |
||
295 | del builtins
|
||
296 | |||
297 | else:
|
||
298 | def exec_(code, globs=None, locs=None): |
||
299 | """Execute code in a namespace."""
|
||
300 | if globs is None: |
||
301 | frame = sys._getframe(1)
|
||
302 | globs = frame.f_globals |
||
303 | if locs is None: |
||
304 | locs = frame.f_locals |
||
305 | del frame
|
||
306 | elif locs is None: |
||
307 | locs = globs |
||
308 | exec("""exec code in globs, locs""")
|
||
309 | |||
310 | |||
311 | exec_("""def reraise(tp, value, tb=None):
|
||
312 | raise tp, value, tb
|
||
313 | """)
|
||
314 | |||
315 | |||
316 | def print_(*args, **kwargs): |
||
317 | """The new-style print function."""
|
||
318 | fp = kwargs.pop("file", sys.stdout)
|
||
319 | if fp is None: |
||
320 | return
|
||
321 | def write(data): |
||
322 | if not isinstance(data, basestring): |
||
323 | data = str(data)
|
||
324 | fp.write(data) |
||
325 | want_unicode = False
|
||
326 | sep = kwargs.pop("sep", None) |
||
327 | if sep is not None: |
||
328 | if isinstance(sep, unicode): |
||
329 | want_unicode = True
|
||
330 | elif not isinstance(sep, str): |
||
331 | raise TypeError("sep must be None or a string") |
||
332 | end = kwargs.pop("end", None) |
||
333 | if end is not None: |
||
334 | if isinstance(end, unicode): |
||
335 | want_unicode = True
|
||
336 | elif not isinstance(end, str): |
||
337 | raise TypeError("end must be None or a string") |
||
338 | if kwargs:
|
||
339 | raise TypeError("invalid keyword arguments to print()") |
||
340 | if not want_unicode: |
||
341 | for arg in args: |
||
342 | if isinstance(arg, unicode): |
||
343 | want_unicode = True
|
||
344 | break
|
||
345 | if want_unicode:
|
||
346 | newline = unicode("\n") |
||
347 | space = unicode(" ") |
||
348 | else:
|
||
349 | newline = "\n"
|
||
350 | space = " "
|
||
351 | if sep is None: |
||
352 | sep = space |
||
353 | if end is None: |
||
354 | end = newline |
||
355 | for i, arg in enumerate(args): |
||
356 | if i:
|
||
357 | write(sep) |
||
358 | write(arg) |
||
359 | write(end) |
||
360 | |||
361 | _add_doc(reraise, """Reraise an exception.""")
|
||
362 | |||
363 | |||
364 | def with_metaclass(meta, base=object): |
||
365 | """Create a base class with a metaclass."""
|
||
366 | return meta("NewBase", (base,), {}) |
||
367 | |||
368 | |||
369 | ### Additional customizations for Django ###
|
||
370 | |||
371 | if PY3:
|
||
372 | _iterlists = "lists"
|
||
373 | else:
|
||
374 | _iterlists = "iterlists"
|
||
375 | |||
376 | def iterlists(d): |
||
377 | """Return an iterator over the values of a MultiValueDict."""
|
||
378 | return getattr(d, _iterlists)() |
||
379 | |||
380 | |||
381 | add_move(MovedModule("_dummy_thread", "dummy_thread")) |
||
382 | add_move(MovedModule("_thread", "thread")) |