diff options
| author | Donald Stufft <donald@stufft.io> | 2014-12-05 22:56:45 -0500 |
|---|---|---|
| committer | Donald Stufft <donald@stufft.io> | 2014-12-05 22:56:45 -0500 |
| commit | 16637c90d03fd6f5b9c83cb97e7ba88d39c0d8d6 (patch) | |
| tree | c5c4b2a78a29eefa5ce2e97217f06fda4d4371fe | |
| parent | 816a9130efd20e877166c08eccaf11ce4139b90e (diff) | |
| download | py-bcrypt-git-16637c90d03fd6f5b9c83cb97e7ba88d39c0d8d6.tar.gz | |
Lazily load the library upon first use
| -rw-r--r-- | bcrypt/__init__.py | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/bcrypt/__init__.py b/bcrypt/__init__.py index 8cd02f6..bae9c35 100644 --- a/bcrypt/__init__.py +++ b/bcrypt/__init__.py @@ -19,8 +19,10 @@ from __future__ import division import binascii import os import sys +import threading from cffi import FFI +from cffi.verifier import Verifier import six @@ -51,6 +53,25 @@ def _create_modulename(cdef_sources, source, sys_version): return '_bcrypt_cffi_{0}{1}'.format(k1, k2) +class LazyLibrary(object): + def __init__(self, ffi): + self._ffi = ffi + self._lib = None + self._lock = threading.Lock() + + def __getattr__(self, name): + if self._lib is None: + with self._lock: + # We no cover this because this guard is here just to protect + # against concurrent loads of this library. This is pretty + # hard to test and the logic is simple and should hold fine + # without testing (famous last words). + if self._lib is None: # pragma: no cover + self._lib = self._ffi.verifier.load_library() + + return getattr(self._lib, name) + + _crypt_blowfish_dir = "crypt_blowfish-1.2" _bundled_dir = os.path.join(os.path.dirname(__file__), _crypt_blowfish_dir) @@ -68,8 +89,8 @@ SOURCE = """ _ffi = FFI() _ffi.cdef(CDEF) - -_bcrypt_lib = _ffi.verify( +_ffi.verifier = Verifier( + _ffi, SOURCE, sources=[ str(os.path.join(_bundled_dir, "crypt_blowfish.c")), @@ -86,6 +107,9 @@ _bcrypt_lib = _ffi.verify( ) +_bcrypt_lib = LazyLibrary(_ffi) + + def gensalt(rounds=12): salt = os.urandom(16) output = _ffi.new("unsigned char[]", 30) |
