Skip to content

Commit

Permalink
Ignore new entrypoints when using old versions of the driver (#5)
Browse files Browse the repository at this point in the history
* Ignore new entrypoints when using old versions of the driver

Allow the Python API to work with existing versions of the driver as we
add new entrypoints to the API.  New functions throw a Version Mismatch
error if used on a driver that doesn't support them.

* Removing excess whitespace
  • Loading branch information
strainmike committed Mar 29, 2017
1 parent 87b2cc4 commit 6e5b95b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
26 changes: 17 additions & 9 deletions nifpga/statuscheckedlibrary.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .status import check_status
from .status import check_status, VersionMismatchError
import ctypes
import ctypes.util

Expand Down Expand Up @@ -176,14 +176,22 @@ def __init__(self, library_name, library_function_infos):
library = ctypes.cdll.LoadLibrary(library)
function_infos = []
for lfi in library_function_infos:
func = getattr(library, lfi.name_in_library) # i.e., dlsym()
# ctypes functions have special 'argtypes' and 'restype' fields
# that we set, so ctypes can automatically convert types and knows
# how to call into the library.
func.argtypes = [named_argtype.argtype for named_argtype in lfi.named_argtypes]
# Assume that everything returns an NiFpga_Status
func.restype = StatusType

try:
func = getattr(library, lfi.name_in_library) # i.e., dlsym()
# ctypes functions have special 'argtypes' and 'restype' fields
# that we set, so ctypes can automatically convert types and knows
# how to call into the library.
func.argtypes = [named_argtype.argtype for named_argtype in lfi.named_argtypes]
# Assume that everything returns an NiFpga_Status
func.restype = StatusType
except AttributeError:
# if we can't find the symbol, instead insert a function that
# always returns the VersionMismatch error, that way they can
# use the rest of the API
def returnsVersionMismatchError(*args, **kwargs):
""" Always returns the version mismatch error code. """
return VersionMismatchError.CODE
func = returnsVersionMismatchError
function_infos.append(
FunctionInfo(function=func,
name=lfi.pretty_name,
Expand Down
26 changes: 26 additions & 0 deletions nifpga/tests/test_nifpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,32 @@ def test_get_unknown_warning(self):
self.assertIn("nptr: b'1'", str(warning))


class StatusCheckedLibraryTestFunctionDoesntExist(unittest.TestCase):
"""
New versions of NiFpga will have new functions. We want the API to support
old versions of NiFpga without erroring because it can't find certain symbols.
So StatusCheckedLibrary will return FeatureNotSupported for symbols it can't
find.
"""
def setUp(self):
self._c_runtime = StatusCheckedLibrary(
"c",
library_function_infos=[
LibraryFunctionInfo(
pretty_name="DoesntExist",
name_in_library="functionThatDoesntExist",
named_argtypes=[
NamedArgtype("nptr", ctypes.c_char_p),
])
])

def test_correct_error(self):
with self.assertRaises(nifpga.VersionMismatchError):
self._c_runtime.DoesntExist(b"0")
with self.assertRaises(nifpga.VersionMismatchError):
self._c_runtime["DoesntExist"](b"0")


class StatusCheckedLibraryTestMockedLibrary(unittest.TestCase):
"""
Since we can't load NiFpga on a dev machine unless we have all its
Expand Down

0 comments on commit 6e5b95b

Please sign in to comment.