11"""Utilities for writing code that runs on Python 2 and 3"""
22
3- # Copyright (c) 2010-2012 Benjamin Peterson
3+ # Copyright (c) 2010-2013 Benjamin Peterson
44#
55# Permission is hereby granted, free of charge, to any person obtaining a copy of
66# this software and associated documentation files (the "Software"), to deal in
@@ -209,22 +209,28 @@ def remove_move(name):
209209 _meth_func = "__func__"
210210 _meth_self = "__self__"
211211
212+ _func_closure = "__closure__"
212213 _func_code = "__code__"
213214 _func_defaults = "__defaults__"
215+ _func_globals = "__globals__"
214216
215217 _iterkeys = "keys"
216218 _itervalues = "values"
217219 _iteritems = "items"
220+ _iterlists = "lists"
218221else :
219222 _meth_func = "im_func"
220223 _meth_self = "im_self"
221224
225+ _func_closure = "func_closure"
222226 _func_code = "func_code"
223227 _func_defaults = "func_defaults"
228+ _func_globals = "func_globals"
224229
225230 _iterkeys = "iterkeys"
226231 _itervalues = "itervalues"
227232 _iteritems = "iteritems"
233+ _iterlists = "iterlists"
228234
229235
230236try :
@@ -235,14 +241,18 @@ def advance_iterator(it):
235241next = advance_iterator
236242
237243
244+ try :
245+ callable = callable
246+ except NameError :
247+ def callable (obj ):
248+ return any ("__call__" in klass .__dict__ for klass in type (obj ).__mro__ )
249+
250+
238251if PY3 :
239252 def get_unbound_function (unbound ):
240253 return unbound
241254
242255 Iterator = object
243-
244- def callable (obj ):
245- return any ("__call__" in klass .__dict__ for klass in type (obj ).__mro__ )
246256else :
247257 def get_unbound_function (unbound ):
248258 return unbound .im_func
@@ -259,21 +269,27 @@ def next(self):
259269
260270get_method_function = operator .attrgetter (_meth_func )
261271get_method_self = operator .attrgetter (_meth_self )
272+ get_function_closure = operator .attrgetter (_func_closure )
262273get_function_code = operator .attrgetter (_func_code )
263274get_function_defaults = operator .attrgetter (_func_defaults )
275+ get_function_globals = operator .attrgetter (_func_globals )
264276
265277
266- def iterkeys (d ):
278+ def iterkeys (d , ** kw ):
267279 """Return an iterator over the keys of a dictionary."""
268- return iter (getattr (d , _iterkeys )())
280+ return iter (getattr (d , _iterkeys )(** kw ))
269281
270- def itervalues (d ):
282+ def itervalues (d , ** kw ):
271283 """Return an iterator over the values of a dictionary."""
272- return iter (getattr (d , _itervalues )())
284+ return iter (getattr (d , _itervalues )(** kw ))
273285
274- def iteritems (d ):
286+ def iteritems (d , ** kw ):
275287 """Return an iterator over the (key, value) pairs of a dictionary."""
276- return iter (getattr (d , _iteritems )())
288+ return iter (getattr (d , _iteritems )(** kw ))
289+
290+ def iterlists (d , ** kw ):
291+ """Return an iterator over the (key, [values]) pairs of a dictionary."""
292+ return iter (getattr (d , _iterlists )(** kw ))
277293
278294
279295if PY3 :
@@ -317,17 +333,17 @@ def reraise(tp, value, tb=None):
317333 del builtins
318334
319335else :
320- def exec_ (code , globs = None , locs = None ):
336+ def exec_ (_code_ , _globs_ = None , _locs_ = None ):
321337 """Execute code in a namespace."""
322- if globs is None :
338+ if _globs_ is None :
323339 frame = sys ._getframe (1 )
324- globs = frame .f_globals
325- if locs is None :
326- locs = frame .f_locals
340+ _globs_ = frame .f_globals
341+ if _locs_ is None :
342+ _locs_ = frame .f_locals
327343 del frame
328- elif locs is None :
329- locs = globs
330- exec ("""exec code in globs, locs """ )
344+ elif _locs_ is None :
345+ _locs_ = _globs_
346+ exec ("""exec _code_ in _globs_, _locs_ """ )
331347
332348
333349 exec_ ("""def reraise(tp, value, tb=None):
@@ -391,24 +407,17 @@ def with_metaclass(meta, base=object):
391407### Additional customizations for Django ###
392408
393409if PY3 :
394- _iterlists = "lists"
395410 _assertRaisesRegex = "assertRaisesRegex"
396411 _assertRegex = "assertRegex"
397412 memoryview = memoryview
398413else :
399- _iterlists = "iterlists"
400414 _assertRaisesRegex = "assertRaisesRegexp"
401415 _assertRegex = "assertRegexpMatches"
402416 # memoryview and buffer are not stricly equivalent, but should be fine for
403417 # django core usage (mainly BinaryField)
404418 memoryview = buffer
405419
406420
407- def iterlists (d ):
408- """Return an iterator over the values of a MultiValueDict."""
409- return getattr (d , _iterlists )()
410-
411-
412421def assertRaisesRegex (self , * args , ** kwargs ):
413422 return getattr (self , _assertRaisesRegex )(* args , ** kwargs )
414423
0 commit comments