diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2011-12-06 12:40:53 -0500 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2011-12-06 12:40:53 -0500 |
| commit | d07f2084c1532c121935cebf92cdbdd41c43bb57 (patch) | |
| tree | 6b4de725a11627b7dab460ac1e000b4a107daae7 /passlib | |
| parent | 295e3874293a3697b593f7e15fcbed9f5d580fb4 (diff) | |
| download | passlib-d07f2084c1532c121935cebf92cdbdd41c43bb57.tar.gz | |
added compatibility module (passlib.utils.compat)
exports specialized range & map aliases, and some dict helpers
* all dict.iteritems() calls replaced with compat.iteritems(dict)
* all xrange() calls replaced with compat.irange()
* all range() calls replaced with compat.trange() and compat.lrange() as appropriate
* all map() calls replaced with compat.lmap()
Diffstat (limited to 'passlib')
| -rw-r--r-- | passlib/apache.py | 7 | ||||
| -rw-r--r-- | passlib/context.py | 20 | ||||
| -rw-r--r-- | passlib/handlers/fshp.py | 3 | ||||
| -rw-r--r-- | passlib/handlers/sun_md5_crypt.py | 3 | ||||
| -rw-r--r-- | passlib/tests/genconfig.py | 7 | ||||
| -rw-r--r-- | passlib/tests/test_ext_django.py | 3 | ||||
| -rw-r--r-- | passlib/tests/test_utils.py | 2 | ||||
| -rw-r--r-- | passlib/tests/utils.py | 3 | ||||
| -rw-r--r-- | passlib/utils/_blowfish/_gen_files.py | 9 | ||||
| -rw-r--r-- | passlib/utils/compat.py | 96 | ||||
| -rw-r--r-- | passlib/utils/des.py | 19 |
11 files changed, 136 insertions, 36 deletions
diff --git a/passlib/apache.py b/passlib/apache.py index 0bf3301..b43e04d 100644 --- a/passlib/apache.py +++ b/passlib/apache.py @@ -13,6 +13,7 @@ import sys from passlib.context import CryptContext from passlib.utils import render_bytes, bjoin, bytes, b, \ to_unicode, to_bytes, consteq +from passlib.utils.compat import lmap #pkg #local __all__ = [ @@ -319,7 +320,7 @@ class HtpasswdFile(_CommonFile): def users(self): "return list of all users in file" - return map(self._decode_ident, self._entry_order) + return lmap(self._decode_ident, self._entry_order) def update(self, user, password): """update password for user; adds user if needed. @@ -454,13 +455,13 @@ class HtdigestFile(_CommonFile): def realms(self): "return all realms listed in file" - return map(self._decode_ident, + return lmap(self._decode_ident, set(key[1] for key in self._entry_order)) def users(self, realm): "return list of all users within specified realm" realm = self._norm_realm(realm) - return map(self._decode_ident, + return lmap(self._decode_ident, (key[0] for key in self._entry_order if key[1] == realm)) def update(self, user, realm, password): diff --git a/passlib/context.py b/passlib/context.py index adcf467..91441c2 100644 --- a/passlib/context.py +++ b/passlib/context.py @@ -29,6 +29,7 @@ except ImportError: from passlib.registry import get_crypt_handler, _unload_handler_name from passlib.utils import to_bytes, to_unicode, bytes, Undef, \ is_crypt_handler, splitcomma, rng +from passlib.utils.compat import is_mapping, iteritems #pkg #local __all__ = [ @@ -103,13 +104,8 @@ def _parse_policy_value(cat, name, opt, value): def parse_policy_items(source): "helper to parse CryptPolicy options" - # py2k # - if hasattr(source, "iteritems"): - source = source.iteritems() - # py3k # - #if hasattr(source, "items"): - # source = source.items() - # end py3k # + if is_mapping(source): + source = iteritems(source) for key, value in source: cat, name, opt = _parse_policy_key(key) if name == "context": @@ -405,7 +401,7 @@ class CryptPolicy(object): dmap = self._deprecated = {} fmap = self._default = {} mvmap = self._min_verify_time = {} - for cat, config in options.iteritems(): + for cat, config in iteritems(options): kwds = config.pop("context", None) if not kwds: continue @@ -618,16 +614,16 @@ class CryptPolicy(object): if value: yield format_key(None, None, "schemes"), encode_hlist(value) - for cat, value in self._deprecated.iteritems(): + for cat, value in iteritems(self._deprecated): yield format_key(cat, None, "deprecated"), encode_nlist(value) - for cat, value in self._default.iteritems(): + for cat, value in iteritems(self._default): yield format_key(cat, None, "default"), encode_handler(value) - for cat, value in self._min_verify_time.iteritems(): + for cat, value in iteritems(self._min_verify_time): yield format_key(cat, None, "min_verify_time"), value - for cat, copts in self._options.iteritems(): + for cat, copts in iteritems(self._options): for name in sorted(copts): config = copts[name] for opt in sorted(config): diff --git a/passlib/handlers/fshp.py b/passlib/handlers/fshp.py index 0ca1dd3..e9bc23c 100644 --- a/passlib/handlers/fshp.py +++ b/passlib/handlers/fshp.py @@ -12,6 +12,7 @@ from warnings import warn #site #libs from passlib.utils import handlers as uh, bytes, b, to_hash_str +from passlib.utils.compat import iteritems from passlib.utils.pbkdf2 import pbkdf1 #pkg #local @@ -79,7 +80,7 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): } _variant_aliases = dict( [(unicode(k),k) for k in _variant_info] + - [(v[0],k) for k,v in _variant_info.items()] + [(v[0],k) for k,v in iteritems(_variant_info)] ) #========================================================= diff --git a/passlib/handlers/sun_md5_crypt.py b/passlib/handlers/sun_md5_crypt.py index 79b2872..6bfab75 100644 --- a/passlib/handlers/sun_md5_crypt.py +++ b/passlib/handlers/sun_md5_crypt.py @@ -18,6 +18,7 @@ from warnings import warn #site #libs from passlib.utils import h64, handlers as uh, to_hash_str, to_unicode, bytes, b, bord +from passlib.utils.compat import trange #pkg #local __all__ = [ @@ -70,7 +71,7 @@ MAGIC_HAMLET = b( ) #NOTE: these sequences are pre-calculated iteration ranges used by X & Y loops w/in rounds function below -xr = range(7) +xr = trange(7) _XY_ROUNDS = [ tuple((i,i,i+3) for i in xr), #xrounds 0 tuple((i,i+1,i+4) for i in xr), #xrounds 1 diff --git a/passlib/tests/genconfig.py b/passlib/tests/genconfig.py index 0abdaab..e544a7d 100644 --- a/passlib/tests/genconfig.py +++ b/passlib/tests/genconfig.py @@ -15,6 +15,7 @@ import time import sys #site #pkg +from passlib.utils.compat import iteritems from passlib.registry import get_crypt_handler #local log = logging.getLogger(__name__) @@ -76,7 +77,7 @@ class HashTimer(object): # self.samples = samples self.cache = {} - self.srange = range(samples) + self.srange = trange(samples) def time_encrypt(self, rounds): "check how long encryption for a given number of rounds will take" @@ -121,7 +122,7 @@ class HashTimer(object): #check if useful lower & upper bounds already exist in cache # lower = upper = None - for rounds, delta in self.cache.iteritems(): + for rounds, delta in iteritems(self.cache.iteritems): if delta < target: if lower is None or rounds > lower: lower = rounds @@ -203,7 +204,7 @@ class HashTimer(object): if not cache: raise RuntimeError("should not be called until cache populated by find_rounds()") get_rps = self.get_rps - rps = sum(r*get_rps(r,d) for r,d in cache.iteritems())/sum(cache) + rps = sum(r*get_rps(r,d) for r,d in iteritems(cache))/sum(cache) if rps > 1000: #for almost all cases, we'd return integer rps = int(rps) return rps diff --git a/passlib/tests/test_ext_django.py b/passlib/tests/test_ext_django.py index 95ee927..cd53b6f 100644 --- a/passlib/tests/test_ext_django.py +++ b/passlib/tests/test_ext_django.py @@ -16,6 +16,7 @@ from passlib.hash import sha256_crypt from passlib.tests.utils import TestCase, unittest, ut_version, catch_warnings import passlib.tests.test_drivers as td from passlib.utils import Undef +from passlib.utils.compat import iteritems from passlib.registry import get_crypt_handler #module @@ -53,7 +54,7 @@ if has_django: settings.configure() def update_settings(**kwds): - for k,v in kwds.iteritems(): + for k,v in iteritems(kwds): if v is Undef: if hasattr(settings, k): if has_django0: diff --git a/passlib/tests/test_utils.py b/passlib/tests/test_utils.py index 6c19679..b5fe81a 100644 --- a/passlib/tests/test_utils.py +++ b/passlib/tests/test_utils.py @@ -200,7 +200,7 @@ class MiscTest(TestCase): # NOTE: below code was used to generate stats for analysis ##from math import log as logb ##import timeit - ##multipliers = [ 1<<s for s in range(9)] + ##multipliers = [ 1<<s for s in irange(9)] ##correct = u"abcdefgh"*(1<<4) ##incorrect = u"abcdxfgh" ##print diff --git a/passlib/tests/utils.py b/passlib/tests/utils.py index 20c95bf..42706d3 100644 --- a/passlib/tests/utils.py +++ b/passlib/tests/utils.py @@ -37,6 +37,7 @@ from passlib import registry, utils from passlib.utils import classproperty, handlers as uh, \ has_rounds_info, has_salt_info, MissingBackendError, \ rounds_cost_values, b, bytes, native_str, NoneType +from passlib.utils.compat import iteritems #local __all__ = [ #util funcs @@ -662,7 +663,7 @@ class HandlerCase(TestCase): #check optional aliases list if cls.ident_aliases: - for alias, ident in cls.ident_aliases.iteritems(): + for alias, ident in iteritems(cls.ident_aliases): self.assertIsInstance(alias, unicode, "cls.ident_aliases keys must be unicode:") #XXX: allow ints? self.assertIsInstance(ident, unicode, diff --git a/passlib/utils/_blowfish/_gen_files.py b/passlib/utils/_blowfish/_gen_files.py index f02ff39..6256bc5 100644 --- a/passlib/utils/_blowfish/_gen_files.py +++ b/passlib/utils/_blowfish/_gen_files.py @@ -6,13 +6,14 @@ import os import textwrap # pkg +from passlib.utils.compat import irange # local #========================================================================== # helpers #========================================================================== def varlist(name, count): - return ", ".join(name + str(x) for x in range(count)) + return ", ".join(name + str(x) for x in irange(count)) def indent_block(block, padding): @@ -29,7 +30,7 @@ BFSTR = """\ """.strip() def render_encipher(write, indent=0): - for i in range(0, 15, 2): + for i in irange(0, 15, 2): write(indent, """\ # Feistel substitution on left word (round %(i)d) r ^= %(left)s ^ p%(i1)d @@ -73,7 +74,7 @@ def write_expand_function(write, indent=0): # integrate key #============================================================= """) - for i in range(18): + for i in irange(18): write(indent+1, """\ p%(i)d = P[%(i)d] ^ key_words[%(i)d] """, i=i) @@ -98,7 +99,7 @@ def write_expand_function(write, indent=0): """) - for i in range(2, 18, 2): + for i in irange(2, 18, 2): write(indent+1, """\ #------------------------------------------------ # update P[%(i)d] and P[%(i1)d] diff --git a/passlib/utils/compat.py b/passlib/utils/compat.py new file mode 100644 index 0000000..dc6e0c4 --- /dev/null +++ b/passlib/utils/compat.py @@ -0,0 +1,96 @@ +"""passlib.utils.compat - python 2/3 compatibility helpers""" +#============================================================================= +# figure out what version we're running +#============================================================================= +from sys import version as pyver +PY3 = pyver >= (3,0) +PY_MAX_25 = pyver < (2,6) # py 2.5 or earlier +PY_MIN_32 = pyver >= (3,2) # py 3.2 or later + +#============================================================================= +# the default exported vars +#============================================================================= +__all__ = [ + "u", "b", + "irange", "srange", ##"lrange", + "lmap", + "iteritems", +] + +if PY_MAX_25: + __all__.append("bytes") +elif PY3: + __all__.append("unicode") + +#============================================================================= +# typing +#============================================================================= +if PY_MAX_25: + def is_mapping(obj): + # non-exhaustive check, enough to distinguish from lists, etc + return hasattr(obj, "items") +else: + from collections import Mapping + def is_mapping(obj): + return isinstance(obj, Mapping) + +#============================================================================= +# unicode / bytes helpers +#============================================================================= +if PY3: + def u(s): + return s + def b(s): + return s.encode("latin-1") + unicode = str +# string_types = (str,) +else: + def u(s): + return s.decode("unicode_escape") + def b(s): + return s + if PY_MAX_25: + bytes = str +# string_types = (unicode,str) + +#============================================================================= +# bytes-specific helpers +#============================================================================= +# bytes format + +#============================================================================= +# iteration helpers +# +# irange - range iterator +# trange - immutable range sequence (list under py2, range object under py3) +# lrange - range list +# +# lmap - map to list +#============================================================================= +if PY3: + irange = trange = range + ##def lrange(*a,**k): + ## return list(range(*a,**k)) + + def lmap(*a, **k): + return list(map(*a,**k)) + # imap = map + +else: + irange = xrange + trange = range + ##lrange = range + + lmap = map + # from itertools import imap + +if PY3: + def iteritems(d): + return d.items() +else: + def iteritems(d): + return d.iteritems() + +#============================================================================= +# eof +#============================================================================= diff --git a/passlib/utils/des.py b/passlib/utils/des.py index 805a265..d9f4694 100644 --- a/passlib/utils/des.py +++ b/passlib/utils/des.py @@ -44,6 +44,7 @@ which has some nice notes on how this all works - #========================================================= #pkg from passlib.utils import bytes_to_int, int_to_bytes, bytes, bord, bjoin_ints +from passlib.utils.compat import trange #local __all__ = [ "expand_des_key", @@ -54,15 +55,15 @@ __all__ = [ #========================================================= #precalculated iteration ranges & constants #========================================================= -R8 = range(8) -RR8 = range(7, -1, -1) -RR4 = range(3, -1, -1) -RR12_1 = range(11, 1, -1) -RR9_1 = range(9,-1,-1) - -RR6_S2 = range(6, -1, -2) -RR14_S2 = range(14, -1, -2) -R16_S2 = range(0, 16, 2) +R8 = trange(8) +RR8 = trange(7, -1, -1) +RR4 = trange(3, -1, -1) +RR12_1 = trange(11, 1, -1) +RR9_1 = trange(9,-1,-1) + +RR6_S2 = trange(6, -1, -2) +RR14_S2 = trange(14, -1, -2) +R16_S2 = trange(0, 16, 2) INT_24_MAX = 0xffffff INT_64_MAX = 0xffffffff |
