openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

135 lines
3.9 KiB

""" Utility functions for package."""
from abc import ABCMeta, abstractmethod
import datetime
import decimal
import inspect
import json
import sys
from . import six
class JSONSerializable(six.with_metaclass(ABCMeta, object)):
""" Common functionality for json serializable objects."""
serialize = staticmethod(json.dumps)
deserialize = staticmethod(json.loads)
@abstractmethod
def json(self):
raise NotImplementedError()
@classmethod
def from_json(cls, json_str):
data = cls.deserialize(json_str)
if not isinstance(data, dict):
raise ValueError("data should be dict")
return cls(**data)
class DatetimeDecimalEncoder(json.JSONEncoder):
""" Encoder for datetime and decimal serialization.
Usage: json.dumps(object, cls=DatetimeDecimalEncoder)
NOTE: _iterencode does not work
"""
def default(self, o):
""" Encode JSON.
:return str: A JSON encoded string
"""
if isinstance(o, decimal.Decimal):
return float(o)
if isinstance(o, (datetime.datetime, datetime.date)):
return o.isoformat()
return json.JSONEncoder.default(self, o)
def is_invalid_params_py2(func, *args, **kwargs):
""" Check, whether function 'func' accepts parameters 'args', 'kwargs'.
NOTE: Method is called after funct(*args, **kwargs) generated TypeError,
it is aimed to destinguish TypeError because of invalid parameters from
TypeError from inside the function.
.. versionadded: 1.9.0
"""
funcargs, varargs, varkwargs, defaults = inspect.getargspec(func)
unexpected = set(kwargs.keys()) - set(funcargs)
if len(unexpected) > 0:
return True
params = [funcarg for funcarg in funcargs if funcarg not in kwargs]
funcargs_required = funcargs[:-len(defaults)] \
if defaults is not None \
else funcargs
params_required = [
funcarg for funcarg in funcargs_required
if funcarg not in kwargs
]
return not (len(params_required) <= len(args) <= len(params))
def is_invalid_params_py3(func, *args, **kwargs):
"""
Use inspect.signature instead of inspect.getargspec or
inspect.getfullargspec (based on inspect.signature itself) as it provides
more information about function parameters.
.. versionadded: 1.11.2
"""
signature = inspect.signature(func)
parameters = signature.parameters
unexpected = set(kwargs.keys()) - set(parameters.keys())
if len(unexpected) > 0:
return True
params = [
parameter for name, parameter in parameters.items()
if name not in kwargs
]
params_required = [
param for param in params
if param.default is param.empty
]
return not (len(params_required) <= len(args) <= len(params))
def is_invalid_params(func, *args, **kwargs):
"""
Method:
Validate pre-defined criteria, if any is True - function is invalid
0. func should be callable
1. kwargs should not have unexpected keywords
2. remove kwargs.keys from func.parameters
3. number of args should be <= remaining func.parameters
4. number of args should be >= remaining func.parameters less default
"""
# For builtin functions inspect.getargspec(funct) return error. If builtin
# function generates TypeError, it is because of wrong parameters.
if not inspect.isfunction(func):
return True
if sys.version_info >= (3, 3):
return is_invalid_params_py3(func, *args, **kwargs)
else:
# NOTE: use Python2 method for Python 3.2 as well. Starting from Python
# 3.3 it is recommended to use inspect.signature instead.
# In Python 3.0 - 3.2 inspect.getfullargspec is preferred but these
# versions are almost not supported. Users should consider upgrading.
return is_invalid_params_py2(func, *args, **kwargs)