Skip to content
Snippets Groups Projects
Commit 9eba70e1 authored by Donald Stufft's avatar Donald Stufft
Browse files

Don't compile on import

parent fbbe466f
No related branches found
No related tags found
No related merge requests found
......@@ -5,8 +5,10 @@ from __future__ import absolute_import
from __future__ import division
import functools
import os.path
from cffi import FFI
from cffi.verifier import Verifier
__all__ = ["ffi", "lib"]
......@@ -74,11 +76,23 @@ ffi.cdef(
)
lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
#lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
ffi.verifier = Verifier(ffi,
"#include <sodium.h>",
# We need to set a tmp directory otherwise when build_ext is run it'll get
# built in nacl/*.so but when ffi.verifier.load_library() is run it'll
# look (and ultimately build again) in nacl/__pycache__/*.so
tmpdir=os.path.abspath(os.path.dirname(__file__)),
# We need to link to the sodium library
libraries=["sodium"],
)
# This works around a bug in PyPy where CFFI exposed functions do not have a
# __name__ attribute. See https://bugs.pypy.org/issue1452
# __name__ attribute. See https://bugs.pypy.org/issue1452
def wraps(wrapped):
def inner(func):
if hasattr(wrapped, "__name__"):
......@@ -89,9 +103,9 @@ def wraps(wrapped):
# A lot of the functions in nacl return 0 for success and a negative integer
# for failure. This is inconvenient in Python as 0 is a falsey value while
# negative integers are truthy. This wrapper has them return True/False as
# you'd expect in Python
# for failure. This is inconvenient in Python as 0 is a falsey value while
# negative integers are truthy. This wrapper has them return True/False as
# you'd expect in Python
def wrap_nacl_function(func):
@wraps(func)
def wrapper(*args, **kwargs):
......@@ -99,20 +113,48 @@ def wrap_nacl_function(func):
return ret == 0
return wrapper
lib.crypto_secretbox = wrap_nacl_function(lib.crypto_secretbox)
lib.crypto_secretbox_open = wrap_nacl_function(lib.crypto_secretbox_open)
lib.crypto_sign_seed_keypair = wrap_nacl_function(lib.crypto_sign_seed_keypair)
lib.crypto_sign = wrap_nacl_function(lib.crypto_sign)
lib.crypto_sign_open = wrap_nacl_function(lib.crypto_sign_open)
class Library(object):
wrap = [
"crypto_secretbox",
"crypto_secretbox_open",
"crypto_sign_seed_keypair",
"crypto_sign",
"crypto_sign_open",
"crypto_box_keypair",
"crypto_box_afternm",
"crypto_box_open_afternm",
"crypto_box_beforenm",
"crypto_hash",
"crypto_hash_sha256",
"crypto_hash_sha512",
"crypto_scalarmult_curve25519_base",
]
def __init__(self, ffi):
self._ffi = ffi
self._initalized = False
def __getattr__(self, name):
if not self._initalized:
self._lib = self._ffi.verifier.load_library()
# redirect attribute access to the underlying lib
attr = getattr(self._lib, name)
# If this is a function that we're wrapping do the actual wrapping
if name in self.wrap:
attr = wrap_nacl_function(attr)
lib.crypto_box_keypair = wrap_nacl_function(lib.crypto_box_keypair)
lib.crypto_box_afternm = wrap_nacl_function(lib.crypto_box_afternm)
lib.crypto_box_open_afternm = wrap_nacl_function(lib.crypto_box_open_afternm)
lib.crypto_box_beforenm = wrap_nacl_function(lib.crypto_box_beforenm)
# Go ahead and assign the returned value to this class so we don't
# need to do this lookup again
setattr(self, name, attr)
lib.crypto_hash = wrap_nacl_function(lib.crypto_hash)
lib.crypto_hash_sha256 = wrap_nacl_function(lib.crypto_hash_sha256)
lib.crypto_hash_sha512 = wrap_nacl_function(lib.crypto_hash_sha512)
return attr
lib.crypto_scalarmult_curve25519_base = wrap_nacl_function(lib.crypto_scalarmult_curve25519_base)
lib = Library(ffi)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment