Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.5.x] Fixed #21823 -- Upgraded six to 1.5.2

Backport of 780ae7e from master.
  • Loading branch information...
commit 682420d108ee3e056ea0d538b61ffa2a850a2222 1 parent 60054e6
Tim Graham authored January 26, 2014

Showing 1 changed file with 104 additions and 35 deletions. Show diff stats Hide diff stats

  1. 139  django/utils/six.py
139  django/utils/six.py
... ...
@@ -1,6 +1,6 @@
1 1
 """Utilities for writing code that runs on Python 2 and 3"""
2 2
 
3  
-# Copyright (c) 2010-2013 Benjamin Peterson
  3
+# Copyright (c) 2010-2014 Benjamin Peterson
4 4
 #
5 5
 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 6
 # of this software and associated documentation files (the "Software"), to deal
@@ -25,7 +25,7 @@
25 25
 import types
26 26
 
27 27
 __author__ = "Benjamin Peterson <benjamin@python.org>"
28  
-__version__ = "1.4.0"
  28
+__version__ = "1.5.2"
29 29
 
30 30
 
31 31
 # Useful for very coarse version differentiation.
@@ -84,9 +84,9 @@ def __init__(self, name):
84 84
 
85 85
     def __get__(self, obj, tp):
86 86
         result = self._resolve()
87  
-        setattr(obj, self.name, result)
  87
+        setattr(obj, self.name, result) # Invokes __set__.
88 88
         # This is a bit ugly, but it avoids running this again.
89  
-        delattr(tp, self.name)
  89
+        delattr(obj.__class__, self.name)
90 90
         return result
91 91
 
92 92
 
@@ -104,6 +104,35 @@ def __init__(self, name, old, new=None):
104 104
     def _resolve(self):
105 105
         return _import_module(self.mod)
106 106
 
  107
+    def __getattr__(self, attr):
  108
+        # Hack around the Django autoreloader. The reloader tries to get
  109
+        # __file__ or __name__ of every module in sys.modules. This doesn't work
  110
+        # well if this MovedModule is for an module that is unavailable on this
  111
+        # machine (like winreg on Unix systems). Thus, we pretend __file__ and
  112
+        # __name__ don't exist if the module hasn't been loaded yet. See issues
  113
+        # #51 and #53.
  114
+        if attr in ("__file__", "__name__") and self.mod not in sys.modules:
  115
+            raise AttributeError
  116
+        _module = self._resolve()
  117
+        value = getattr(_module, attr)
  118
+        setattr(self, attr, value)
  119
+        return value
  120
+
  121
+
  122
+class _LazyModule(types.ModuleType):
  123
+
  124
+    def __init__(self, name):
  125
+        super(_LazyModule, self).__init__(name)
  126
+        self.__doc__ = self.__class__.__doc__
  127
+
  128
+    def __dir__(self):
  129
+        attrs = ["__doc__", "__name__"]
  130
+        attrs += [attr.name for attr in self._moved_attributes]
  131
+        return attrs
  132
+
  133
+    # Subclasses should override this
  134
+    _moved_attributes = []
  135
+
107 136
 
108 137
 class MovedAttribute(_LazyDescr):
109 138
 
@@ -131,7 +160,7 @@ def _resolve(self):
131 160
 
132 161
 
133 162
 
134  
-class _MovedItems(types.ModuleType):
  163
+class _MovedItems(_LazyModule):
135 164
     """Lazy loading of moved objects"""
136 165
 
137 166
 
@@ -153,6 +182,7 @@ class _MovedItems(types.ModuleType):
153 182
     MovedModule("builtins", "__builtin__"),
154 183
     MovedModule("configparser", "ConfigParser"),
155 184
     MovedModule("copyreg", "copy_reg"),
  185
+    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
156 186
     MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
157 187
     MovedModule("http_cookies", "Cookie", "http.cookies"),
158 188
     MovedModule("html_entities", "htmlentitydefs", "html.entities"),
@@ -168,12 +198,14 @@ class _MovedItems(types.ModuleType):
168 198
     MovedModule("queue", "Queue"),
169 199
     MovedModule("reprlib", "repr"),
170 200
     MovedModule("socketserver", "SocketServer"),
  201
+    MovedModule("_thread", "thread", "_thread"),
171 202
     MovedModule("tkinter", "Tkinter"),
172 203
     MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
173 204
     MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
174 205
     MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
175 206
     MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
176 207
     MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
  208
+    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
177 209
     MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
178 210
     MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
179 211
     MovedModule("tkinter_colorchooser", "tkColorChooser",
@@ -185,21 +217,25 @@ class _MovedItems(types.ModuleType):
185 217
     MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
186 218
     MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
187 219
                 "tkinter.simpledialog"),
188  
-    MovedModule("urllib_parse", "six.moves.urllib_parse", "urllib.parse"),
189  
-    MovedModule("urllib_error", "six.moves.urllib_error", "urllib.error"),
190  
-    MovedModule("urllib", "six.moves.urllib", "six.moves.urllib"),
  220
+    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
  221
+    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
  222
+    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
191 223
     MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
  224
+    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
192 225
     MovedModule("winreg", "_winreg"),
193 226
 ]
194 227
 for attr in _moved_attributes:
195 228
     setattr(_MovedItems, attr.name, attr)
  229
+    if isinstance(attr, MovedModule):
  230
+        sys.modules[__name__ + ".moves." + attr.name] = attr
196 231
 del attr
197 232
 
198  
-moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves")
  233
+_MovedItems._moved_attributes = _moved_attributes
199 234
 
  235
+moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves")
200 236
 
201 237
 
202  
-class Module_six_moves_urllib_parse(types.ModuleType):
  238
+class Module_six_moves_urllib_parse(_LazyModule):
203 239
     """Lazy loading of moved objects in six.moves.urllib_parse"""
204 240
 
205 241
 
@@ -223,11 +259,12 @@ class Module_six_moves_urllib_parse(types.ModuleType):
223 259
     setattr(Module_six_moves_urllib_parse, attr.name, attr)
224 260
 del attr
225 261
 
226  
-sys.modules[__name__ + ".moves.urllib_parse"] = Module_six_moves_urllib_parse("six.moves.urllib_parse")
227  
-sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse("six.moves.urllib.parse")
  262
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
228 263
 
  264
+sys.modules[__name__ + ".moves.urllib_parse"] = sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse")
229 265
 
230  
-class Module_six_moves_urllib_error(types.ModuleType):
  266
+
  267
+class Module_six_moves_urllib_error(_LazyModule):
231 268
     """Lazy loading of moved objects in six.moves.urllib_error"""
232 269
 
233 270
 
@@ -240,11 +277,12 @@ class Module_six_moves_urllib_error(types.ModuleType):
240 277
     setattr(Module_six_moves_urllib_error, attr.name, attr)
241 278
 del attr
242 279
 
243  
-sys.modules[__name__ + ".moves.urllib_error"] = Module_six_moves_urllib_error("six.moves.urllib_error")
244  
-sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error("six.moves.urllib.error")
  280
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
  281
+
  282
+sys.modules[__name__ + ".moves.urllib_error"] = sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error")
245 283
 
246 284
 
247  
-class Module_six_moves_urllib_request(types.ModuleType):
  285
+class Module_six_moves_urllib_request(_LazyModule):
248 286
     """Lazy loading of moved objects in six.moves.urllib_request"""
249 287
 
250 288
 
@@ -281,16 +319,18 @@ class Module_six_moves_urllib_request(types.ModuleType):
281 319
     MovedAttribute("urlcleanup", "urllib", "urllib.request"),
282 320
     MovedAttribute("URLopener", "urllib", "urllib.request"),
283 321
     MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
  322
+    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
284 323
 ]
285 324
 for attr in _urllib_request_moved_attributes:
286 325
     setattr(Module_six_moves_urllib_request, attr.name, attr)
287 326
 del attr
288 327
 
289  
-sys.modules[__name__ + ".moves.urllib_request"] = Module_six_moves_urllib_request("six.moves.urllib_request")
290  
-sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request("six.moves.urllib.request")
  328
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
291 329
 
  330
+sys.modules[__name__ + ".moves.urllib_request"] = sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request")
292 331
 
293  
-class Module_six_moves_urllib_response(types.ModuleType):
  332
+
  333
+class Module_six_moves_urllib_response(_LazyModule):
294 334
     """Lazy loading of moved objects in six.moves.urllib_response"""
295 335
 
296 336
 
@@ -304,11 +344,12 @@ class Module_six_moves_urllib_response(types.ModuleType):
304 344
     setattr(Module_six_moves_urllib_response, attr.name, attr)
305 345
 del attr
306 346
 
307  
-sys.modules[__name__ + ".moves.urllib_response"] = Module_six_moves_urllib_response("six.moves.urllib_response")
308  
-sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response("six.moves.urllib.response")
  347
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
  348
+
  349
+sys.modules[__name__ + ".moves.urllib_response"] = sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response")
309 350
 
310 351
 
311  
-class Module_six_moves_urllib_robotparser(types.ModuleType):
  352
+class Module_six_moves_urllib_robotparser(_LazyModule):
312 353
     """Lazy loading of moved objects in six.moves.urllib_robotparser"""
313 354
 
314 355
 
@@ -319,8 +360,9 @@ class Module_six_moves_urllib_robotparser(types.ModuleType):
319 360
     setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
320 361
 del attr
321 362
 
322  
-sys.modules[__name__ + ".moves.urllib_robotparser"] = Module_six_moves_urllib_robotparser("six.moves.urllib_robotparser")
323  
-sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser("six.moves.urllib.robotparser")
  363
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
  364
+
  365
+sys.modules[__name__ + ".moves.urllib_robotparser"] = sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser")
324 366
 
325 367
 
326 368
 class Module_six_moves_urllib(types.ModuleType):
@@ -331,8 +373,11 @@ class Module_six_moves_urllib(types.ModuleType):
331 373
     response = sys.modules[__name__ + ".moves.urllib_response"]
332 374
     robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"]
333 375
 
  376
+    def __dir__(self):
  377
+        return ['parse', 'error', 'request', 'response', 'robotparser']
334 378
 
335  
-sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib("six.moves.urllib")
  379
+
  380
+sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib")
336 381
 
337 382
 
338 383
 def add_move(move):
@@ -464,8 +509,9 @@ def int2byte(i):
464 509
 else:
465 510
     def b(s):
466 511
         return s
  512
+    # Workaround for standalone backslash
467 513
     def u(s):
468  
-        return unicode(s, "unicode_escape")
  514
+        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
469 515
     unichr = unichr
470 516
     int2byte = chr
471 517
     def byte2int(bs):
@@ -481,8 +527,7 @@ def iterbytes(buf):
481 527
 
482 528
 
483 529
 if PY3:
484  
-    import builtins
485  
-    exec_ = getattr(builtins, "exec")
  530
+    exec_ = getattr(moves.builtins, "exec")
486 531
 
487 532
 
488 533
     def reraise(tp, value, tb=None):
@@ -490,10 +535,6 @@ def reraise(tp, value, tb=None):
490 535
             raise value.with_traceback(tb)
491 536
         raise value
492 537
 
493  
-
494  
-    print_ = getattr(builtins, "print")
495  
-    del builtins
496  
-
497 538
 else:
498 539
     def exec_(_code_, _globs_=None, _locs_=None):
499 540
         """Execute code in a namespace."""
@@ -513,14 +554,24 @@ def exec_(_code_, _globs_=None, _locs_=None):
513 554
 """)
514 555
 
515 556
 
  557
+print_ = getattr(moves.builtins, "print", None)
  558
+if print_ is None:
516 559
     def print_(*args, **kwargs):
517  
-        """The new-style print function."""
  560
+        """The new-style print function for Python 2.4 and 2.5."""
518 561
         fp = kwargs.pop("file", sys.stdout)
519 562
         if fp is None:
520 563
             return
521 564
         def write(data):
522 565
             if not isinstance(data, basestring):
523 566
                 data = str(data)
  567
+            # If the file has an encoding, encode unicode with it.
  568
+            if (isinstance(fp, file) and
  569
+                isinstance(data, unicode) and
  570
+                fp.encoding is not None):
  571
+                errors = getattr(fp, "errors", None)
  572
+                if errors is None:
  573
+                    errors = "strict"
  574
+                data = data.encode(fp.encoding, errors)
524 575
             fp.write(data)
525 576
         want_unicode = False
526 577
         sep = kwargs.pop("sep", None)
@@ -571,8 +622,12 @@ def wrapper(cls):
571 622
         orig_vars = cls.__dict__.copy()
572 623
         orig_vars.pop('__dict__', None)
573 624
         orig_vars.pop('__weakref__', None)
574  
-        for slots_var in orig_vars.get('__slots__', ()):
575  
-            orig_vars.pop(slots_var)
  625
+        slots = orig_vars.get('__slots__')
  626
+        if slots is not None:
  627
+            if isinstance(slots, str):
  628
+                slots = [slots]
  629
+            for slots_var in slots:
  630
+                orig_vars.pop(slots_var)
576 631
         return metaclass(cls.__name__, cls.__bases__, orig_vars)
577 632
     return wrapper
578 633
 
@@ -581,13 +636,27 @@ def wrapper(cls):
581 636
 
582 637
 if PY3:
583 638
     _assertRaisesRegex = "assertRaisesRegex"
  639
+    _assertRegex = "assertRegex"
  640
+    memoryview = memoryview
584 641
 else:
585 642
     _assertRaisesRegex = "assertRaisesRegexp"
  643
+    _assertRegex = "assertRegexpMatches"
  644
+    # memoryview and buffer are not stricly equivalent, but should be fine for
  645
+    # django core usage (mainly BinaryField). However, Jython doesn't support
  646
+    # buffer (see http://bugs.jython.org/issue1521), so we have to be careful.
  647
+    if sys.platform.startswith('java'):
  648
+        memoryview = memoryview
  649
+    else:
  650
+        memoryview = buffer
586 651
 
587 652
 
588 653
 def assertRaisesRegex(self, *args, **kwargs):
589 654
     return getattr(self, _assertRaisesRegex)(*args, **kwargs)
590 655
 
591 656
 
  657
+def assertRegex(self, *args, **kwargs):
  658
+    return getattr(self, _assertRegex)(*args, **kwargs)
  659
+
  660
+
592 661
 add_move(MovedModule("_dummy_thread", "dummy_thread"))
593 662
 add_move(MovedModule("_thread", "thread"))

0 notes on commit 682420d

Please sign in to comment.
Something went wrong with that request. Please try again.