M rework/io.py +33 -6
@@ 4,7 4,8 @@ from datetime import datetime as dt
from dateutil.parser import (
isoparse,
- parse as defaultparse
+ parse as defaultparse,
+ ParserError
)
from dateutil.relativedelta import relativedelta
from psyl import lisp
@@ 50,6 51,10 @@ class number(_iobase):
def binary_encode(self, args):
val = self.val(args)
if val is not None:
+ if not isinstance(val, (int, float)):
+ raise TypeError(
+ f'value `{repr(val)}` is not a number'
+ )
return str(val).encode('utf-8')
def binary_decode(self, args):
@@ 67,6 72,10 @@ class string(_iobase):
def binary_encode(self, args):
val = self.val(args)
if val is not None:
+ if not isinstance(val, str):
+ raise TypeError(
+ f'value `{repr(val)}` is not a string'
+ )
return val.encode('utf-8')
def binary_decode(self, args):
@@ 78,7 87,13 @@ class string(_iobase):
class file(_iobase):
def binary_encode(self, args):
- return self.val(args)
+ val = self.val(args)
+ if val is not None:
+ if not isinstance(val, bytes):
+ raise TypeError(
+ f'value `{repr(val)}` is not bytes'
+ )
+ return val
def binary_decode(self, args):
return args.get(self.name)
@@ 90,10 105,20 @@ class datetime(_iobase):
val = self.val(args)
if val is None:
return
+ if not isinstance(val, (str, dt)):
+ raise TypeError(
+ f'value `{repr(val)}` is not str/datetime'
+ )
+
if isinstance(val, str):
- val = val.encode('utf-8')
- else:
- val = val.isoformat().encode('utf-8')
+ try:
+ val = defaultparse(val)
+ except ParserError:
+ raise TypeError(
+ f'value `{repr(val)}` is not a valid datetime'
+ )
+
+ val = val.isoformat().encode('utf-8')
return val
def binary_decode(self, args):
@@ 140,7 165,9 @@ class moment(_iobase):
lisp.evaluate(val, env=_MOMENT_ENV)
except:
import traceback as tb; tb.print_exc()
- raise
+ raise TypeError(
+ f'value `{repr(val)}` is not a valid moment expression'
+ )
return val.encode('utf-8')
M setup.py +1 -1
@@ 26,7 26,7 @@ setup(name='rework',
'inireader',
'apscheduler',
'pyzstd',
- 'dateutils',
+ 'python-dateutil',
'psyl'
],
package_data={'rework': [
M tests/test_api.py +21 -3
@@ 266,9 266,27 @@ def test_prepare_with_inputs(engine, cle
res = engine.execute('select count(*) from rework.sched').scalar()
assert res == 1
+ for name, badvalue in (
+ ('name', 42),
+ ('myfile.txt', 'hello'),
+ ('weight', '65'),
+ ('birthdate', 'lol'),
+ ):
+ failargs = args.copy()
+ failargs[name] = badvalue
+ with pytest.raises(TypeError):
+ api.prepare(
+ engine,
+ 'yummy',
+ rule='* * * * * *',
+ _anyrule=True,
+ inputdata=failargs,
+ metadata={'user': 'Babar'}
+ )
+
failargs = args.copy()
- failargs['name'] = 42
- with pytest.raises(AttributeError):
+ failargs['option'] = 3.14
+ with pytest.raises(ValueError):
api.prepare(
engine,
'yummy',
@@ 350,7 368,7 @@ def test_prepare_inputs_nr_domain_mismat
register_tasks()
api.freeze_operations(engine)
data = {
- 'history': '0'
+ 'history': 0
}
with pytest.raises(Exception):
sid = api.prepare(