-
-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add input checks for interpolator (and other?) classes #190
Comments
For any potential "sprinters", here's what the problem is:
What happens is that the Basically, to close this issue, someone should add a type check on the inputs and are the sizes correct. @mnwhite may want to chime in on the classes and methods where this might be relevant. |
For this issue, you can actually use a type checker such as mypy (http://mypy-lang.org/) in order to validate typing. A type checker is just a program which can analyze your code and tell you if your declared types are incorrect. It is much nicer than runtime validation for a number of reasons:
The hitch here would be that python3.5 introduces native syntax for type annotations, and to be compatible with prior versions (e.g. python2) a clunky comment-based syntax can be used. I believe your plan is to drop support for python2 soon-ish, so it could be worth waiting until then and only supporting python3.5+ and then using the native syntax for it (https://www.python.org/dev/peps/pep-0484/). A simple example to make this all more concrete, consider these two functions which do the same thing: # runtime validation
def head(my_list):
if not isinstance(my_list, list) or any(not isinstance(x, int) for x in my_list):
raise TypeError('my_list must be a list of ints')
return my_list[0] if len(my_list) else None
# type checker validation using native syntax
def head(my_list: List[int]) -> Optional[int]:
return my_list[0] if len(my_list) else None For larger numbers of parameters and more complex types, this can massively reduce the amount of code you need to write while also removing a large potential for bugs while simultaneously making it much easier for other people to understand how to use the code (when I read the bottom example, I only need to read the
There are a lot of approaches to this, but the simplest could be some assert statements at the top of the function, e.g. def head(my_list: List[int]) -> int:
assert len(my_list), 'my_list must not be empty'
return my_list[0] Instead of asserting you can also raise a more specific exception type. Decorators can also help with readability, it would be simple to implement a decorator such as @non_empty('my_list')
def head(my_list: List[int]) -> int:
return my_list[0] Now we can promise that Sorry if this is an information overload- I'm happy to talk through any aspects in more detail if you're interested. There are a lot of tradeoffs to consider when looking at typing and validation, especially when it comes to a community project where you want to ease accessibility by reducing new concepts contributors would have to learn to be productive. |
As is, the
__init__
methods for the interpolator classes in HARK.interpolation do absolutely no input checking, which can lead to bizarre behavior and errors when illegal / incorrect inputs are passed. Input checks can be added fairly easily. These could include:Type checking: Throw an error if something is not an array that should be, etc.
Size checking: Make sure that passed arrays have the right size relative to each other.
Other stuff: E.g. for LinearInterp make sure that xSearchFunc (etc) are correct if specified.
The text was updated successfully, but these errors were encountered: