Context Manager To Validate Data
I'm trying to mull over a good solution to this and nothing is coming to mind. As an exercise, I'm trying to create a context manager that will handle data validation, something li
Solution 1:
You could use a regular context manager to wrap unittest.mock.patch
, and save a reference the original input
function prior to patching it. Then you can pass the original input
to your patched
function:
import unittest.mock
import contextlib
from functools import partial
defpatched(validation, orig_input, *args):
whileTrue:
p = orig_input(*args)
if validation(p):
breakreturn p
@contextlib.contextmanagerdefvalidator(validate_func):
func = partial(patched, validate_func, input) # original input reference saved here
patch = unittest.mock.patch('builtins.input', func)
patch.start()
try:
yieldfinally:
patch.stop()
validation = lambda x: len(x) <= 10
Then you can use the contextmanager like this:
with validator(validation):
x = input("10 or less: ")
x = input("10 or less (unpatched): ")
print("done")
Sample output:
10 or less:abcdefghijklmnop10 or less:abcdefgdfgdgd10 or less:abcdef10orless(unpatched):abcdefghijklmnopdone
Solution 2:
A decorator that accepts parameters could do it pretty nicely (http://www.artima.com/weblogs/viewpost.jsp?thread=240845):
max10 = lambda x: len(x) <= 10defvalidator(test):
defwrap(func):
defwrapped(*args, **kwargs):
result = func(*args, **kwargs)
if test(result):
return result
returnNonereturn wrapped
return wrap
The regular way to use it:
@validator(max10)defvalid_input(prompt="Please enter a name: "):
return raw_input(prompt)
print valid_input()
Applying the decorator manually looks closer to what you're asking for:
valid_input = validator(max10)(raw_input)
print valid_input("Please enter a name: ")
Post a Comment for "Context Manager To Validate Data"