Skip to content

Commit

Permalink
Review error message raised in exceptions (#173)
Browse files Browse the repository at this point in the history
* update error messages
  • Loading branch information
xadupre committed Jun 12, 2019
1 parent 26baa65 commit f427759
Show file tree
Hide file tree
Showing 40 changed files with 191 additions and 108 deletions.
3 changes: 2 additions & 1 deletion docs/examples/plot_convert_syntax.py
Expand Up @@ -117,7 +117,8 @@ def shape_calculator(operator):

def to_onnx_operator(self, inputs=None, outputs=('Y', )):
if inputs is None:
raise RuntimeError("inputs should contain one name")
raise RuntimeError("Parameter inputs should contain at least "
"one name.")
i0 = self.get_inputs(inputs, 0)
W = self.W_
S = self.S_
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/plot_custom_model.py
Expand Up @@ -96,11 +96,11 @@ def __init__(self, transformer=None, estimator=None,
self.keep_tsne_outputs = keep_tsne_outputs
if not hasattr(transformer, "fit_transform"):
raise AttributeError(
"transformer {} does not have a 'fit_transform' "
"Transformer {} does not have a 'fit_transform' "
"method.".format(type(transformer)))
if not hasattr(estimator, "predict"):
raise AttributeError(
"estimator {} does not have a 'predict' method.".format(
"Estimator {} does not have a 'predict' method.".format(
type(estimator)))
self.normalize = normalize
if kwargs:
Expand Down Expand Up @@ -205,7 +205,7 @@ def set_params(self, **values):
elif k.startswith('n_'):
pn[k[2:]] = v
else:
raise ValueError("Unexpected parameter name '{0}'".format(k))
raise ValueError("Unexpected parameter name '{0}'.".format(k))
self.transformer.set_params(**pt)
self.estimator.set_params(**pe)

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/plot_errors_pipeline.py
Expand Up @@ -102,7 +102,7 @@ def lightgbm_classifier_shape_extractor(operator):
operator.outputs[1].type = SequenceType(
DictionaryType(Int64TensorType([]), FloatTensorType([])), N)
else:
raise ValueError('Unsupported or mixed label types')
raise ValueError('Unsupported or mixed label types.')


###################################
Expand Down
10 changes: 6 additions & 4 deletions skl2onnx/_parse.py
Expand Up @@ -29,7 +29,7 @@

def _fetch_input_slice(scope, inputs, column_indices):
if not isinstance(inputs, list):
raise TypeError("inputs must be a list of 1 input.")
raise TypeError("Parameter inputs must be a list.")
if len(inputs) == 0:
raise RuntimeError("Operator ArrayFeatureExtractor requires at "
"least one inputs.")
Expand Down Expand Up @@ -63,7 +63,7 @@ def _parse_sklearn_simple_model(scope, model, inputs, custom_parsers=None):
"""
# alias can be None
if isinstance(model, str):
raise RuntimeError("model must be an object not a "
raise RuntimeError("Parameter model must be an object not a "
"string '{0}'.".format(model))
alias = _get_sklearn_operator_name(type(model))
this_operator = scope.declare_local_operator(alias, model)
Expand Down Expand Up @@ -208,8 +208,10 @@ def _parse_sklearn_column_transformer(scope, model, inputs,
if model_obj == "passthrough":
model_obj = FunctionTransformer()
else:
raise RuntimeError("Unknown operator nickname string "
"'{0}'.".format(model_obj))
raise RuntimeError("Unknown operator alias "
"'{0}'. These are specified in "
"_supported_operators.py."
"".format(model_obj))
var_out = parse_sklearn(
scope, model_obj,
transform_inputs, custom_parsers=custom_parsers)[0]
Expand Down
22 changes: 15 additions & 7 deletions skl2onnx/algebra/graph_state.py
Expand Up @@ -23,11 +23,12 @@ def __init__(self, inputs, outputs,
self.computed_outputs = None
self.attrs = attrs
if isinstance(self.inputs, tuple):
raise TypeError("inputs must be a list or a string or a Variable.")
raise TypeError("Parameter inputs must be a list or a string or a "
"Variable not tuple.")
elif not isinstance(self.inputs, list):
self.inputs = [self.inputs]
if self.expected_outputs is None:
raise ValueError("expected_outputs must be named.")
raise ValueError("Parameter outputs must not be empty.")
if not isinstance(self.expected_outputs, list):
self.expected_outputs = [self.expected_outputs]

Expand All @@ -53,13 +54,14 @@ def _get_var_name(self, var, unused, operator=None):
return var.full_name
elif isinstance(var, str):
return var
raise RuntimeError("Unexpected type {}".format(outputs))
raise RuntimeError("Unexpected output type {}".format(outputs))
elif hasattr(var, 'name') and isinstance(var.name, str) and var.name:
return var.name
elif isinstance(var, str):
return var
else:
raise RuntimeError("Unexpected type: {0}".format(type(var)))
raise RuntimeError("Unexpected type for parameter 'var': {0}."
"".format(type(var)))

def _add_constant(self, cst):
if isinstance(cst, np.ndarray):
Expand All @@ -70,7 +72,9 @@ def _add_constant(self, cst):
ty = onnx_proto.TensorProto.FLOAT
else:
raise NotImplementedError(
"Unable to guess ONNX type from type {}.".format(
"Unable to guess ONNX type from type {}. "
"You may raise an issue at https://github.com/onnx/"
"sklearn-onnx/issues.".format(
cst.dtype))
self.container.add_initializer(
name, ty, shape, cst.astype(np.float64).flatten())
Expand All @@ -82,7 +86,9 @@ def _add_constant(self, cst):
return name
else:
raise NotImplementedError(
"Unable to add a constant of type {}.".format(type(cst)))
"Unable to add a constant of type {}. "
"You may raise an issue at https://github.com/onnx/"
"sklearn-onnx/issues.".format(type(cst)))

def _get_output_name(self, output):
if isinstance(output, Variable):
Expand All @@ -93,7 +99,9 @@ def _get_output_name(self, output):
return output[0]
else:
raise NotImplementedError(
"Unexpected type {}\n{}".format(type(output), output))
"Unexpected output type {} [{}]. "
"You may raise an issue at https://github.com/onnx/"
"sklearn-onnx/issues.".format(type(output), output))

def run(self, operator=None):
if self.computed_outputs is None:
Expand Down
2 changes: 1 addition & 1 deletion skl2onnx/algebra/onnx_operator_mixin.py
Expand Up @@ -45,7 +45,7 @@ def infer_initial_types(self):
if hasattr(self, 'enumerate_initial_types'):
return list(self.enumerate_initial_types())
raise RuntimeError("Method enumerate_initial_types is missing "
"and initial_types are not defined")
"and initial_types are not defined.")

def _find_sklearn_parent(self):
if (hasattr(self.__class__, 'predict') and
Expand Down
8 changes: 5 additions & 3 deletions skl2onnx/algebra/type_helper.py
Expand Up @@ -62,13 +62,15 @@ def _guess_type(given_type):
return _guess_type_proto(ttype.elem_type, dims)
else:
raise NotImplementedError(
"Unsupported type '{}'".format(type(given_type)))
"Unsupported type '{}'. You may raise an issue "
"at https://github.com/onnx/sklearn-onnx/issues."
"".format(type(given_type)))


def guess_initial_types(X, initial_types):
if X is None:
if X is None and initial_types is None:
raise NotImplementedError("Initial types must be specified.")
else:
elif initial_types is None:
if isinstance(X, np.ndarray):
X = X[:1]
gt = _guess_type(X)
Expand Down
37 changes: 21 additions & 16 deletions skl2onnx/common/_topology.py
Expand Up @@ -112,12 +112,14 @@ def get_shape(tt):
elif elem == onnx_proto.TensorProto.INT32:
ty = Int32TensorType(shape)
else:
raise NotImplementedError(
"Unsupported type '{}' elem_type={}".format(
type(obj.type.tensor_type), elem))
raise NotImplementedError("Unsupported type '{}' "
"(elem_type={}).".format(
type(obj.type.tensor_type),
elem))
else:
raise NotImplementedError(
"Unsupported type '{}' as a string={}".format(type(obj), obj))
raise NotImplementedError("Unsupported type '{}' as "
"a string ({}).".format(
type(obj), obj))

return Variable(name, name, None, ty)

Expand All @@ -142,8 +144,8 @@ def __init__(self, onnx_name, scope, type, raw_operator, target_opset):
:param target_opset: The target opset number for the converted model.
"""
if isinstance(raw_operator, str):
raise RuntimeError("raw_operator must be an object not a "
"string '{0}'.".format(raw_operator))
raise RuntimeError("Parameter raw_operator must be an object not "
"a string '{0}'.".format(raw_operator))
# operator name in the converted model
self.onnx_name = onnx_name
self.scope = scope
Expand Down Expand Up @@ -272,7 +274,8 @@ def get_unique_variable_name(self, seed):
Creates a unique variable ID based on the given seed.
"""
if not isinstance(seed, str):
raise TypeError("seed must be a string not {}".format(type(seed)))
raise TypeError("Parameter seed must be a string not {}."
"".format(type(seed)))
return Topology._generate_unique_name(seed, self.onnx_variable_names)

def get_unique_operator_name(self, seed):
Expand Down Expand Up @@ -352,7 +355,7 @@ def delete_local_operator(self, onnx_name):
"""
if (onnx_name not in self.onnx_operator_names or
onnx_name not in self.operators):
raise RuntimeError('The operator to be removed not found')
raise RuntimeError('The operator to remove was not found.')
self.onnx_operator_names.discard(onnx_name)
del self.operators[onnx_name]

Expand All @@ -362,7 +365,7 @@ def delete_local_variable(self, onnx_name):
"""
if (onnx_name not in self.onnx_variable_names or
onnx_name not in self.variables):
raise RuntimeError('The variable to be removed not found')
raise RuntimeError('The variable to remove was not found.')
self.onnx_variable_names.discard(onnx_name)
raw_name = self.variables[onnx_name].raw_name
self.variable_name_mapping[raw_name].remove(onnx_name)
Expand Down Expand Up @@ -462,7 +465,7 @@ def _generate_unique_name(seed, existing_names):
:return: a string similar to the seed
"""
if seed == '':
raise ValueError('Name seed must be an non-empty string')
raise ValueError('Name seed must be a non-empty string.')

# Make the seed meet C-style naming convention
# Only alphabets and numbers are allowed
Expand Down Expand Up @@ -561,7 +564,7 @@ def topological_operator_iterator(self):
# an output somewhere
if variable.is_fed:
raise RuntimeError('One variable can only be '
'assigned once')
'assigned once.')
# Mark this variable as filled
variable.is_fed = True
# Make this operator as handled
Expand Down Expand Up @@ -917,8 +920,8 @@ def convert_topology(topology, model_name, doc_string, target_opset,
elif target_opset > get_opset_number_from_onnx():
found = get_opset_number_from_onnx()
raise RuntimeError(
"target_opset {} > {} is higher than the number of the installed "
"onnx package. See "
"Parameter target_opset {} > {} is higher than the "
"number of the installed onnx package. See "
"https://github.com/onnx/onnx/blob/master/docs/Versioning.md#released-versions" # noqa
".".format(target_opset, found))

Expand Down Expand Up @@ -1014,8 +1017,10 @@ def convert_topology(topology, model_name, doc_string, target_opset,
except ValueError:
raise MissingConverter(
"Unable to find converter for alias '{}' type "
"'{}'.".format(operator.type,
type(getattr(operator, 'raw_model', None))))
"'{}'. You may raise an issue at "
"https://github.com/onnx/sklearn-onnx/issues."
"".format(operator.type,
type(getattr(operator, 'raw_model', None))))
conv(scope, operator, container)

# Create a graph from its main components
Expand Down
24 changes: 15 additions & 9 deletions skl2onnx/common/data_types.py
Expand Up @@ -30,10 +30,10 @@ def _guess_type_proto(data_type, dims):
elif data_type == onnx_proto.TensorProto.BOOL:
return BooleanTensorType(dims)
else:
raise NotImplementedError("Unsupported type '{}' "
"data_type={}".format(
type(data_type),
dims))
raise NotImplementedError(
"Unsupported data_type '{}'. You may raise an issue "
"at https://github.com/onnx/sklearn-onnx/issues."
"".format(data_type))


def _guess_type_proto_str(data_type, dims):
Expand All @@ -51,8 +51,10 @@ def _guess_type_proto_str(data_type, dims):
elif data_type == "tensor(bool)":
return BooleanTensorType(dims)
else:
raise NotImplementedError("Unsupported data_type='{}'".format(
data_type))
raise NotImplementedError(
"Unsupported data_type '{}'. You may raise an issue "
"at https://github.com/onnx/sklearn-onnx/issues."
"".format(data_type))


def _guess_numpy_type(data_type, dims):
Expand All @@ -72,8 +74,10 @@ def _guess_numpy_type(data_type, dims):
elif data_type == np.bool:
return BooleanTensorType(dims)
else:
raise NotImplementedError("Unsupported data_type='{}'".format(
data_type))
raise NotImplementedError(
"Unsupported data_type '{}'. You may raise an issue "
"at https://github.com/onnx/sklearn-onnx/issues."
"".format(data_type))


def guess_data_type(type_, shape=None):
Expand All @@ -96,4 +100,6 @@ def guess_data_type(type_, shape=None):
return [('input', _guess_numpy_type(type_.dtype, type_.shape))]
else:
raise TypeError("Type {} cannot be converted into a "
"DataType.".format(type(type_)))
"DataType. You may raise an issue at "
"https://github.com/onnx/sklearn-onnx/issues."
"".format(type(type_)))
4 changes: 3 additions & 1 deletion skl2onnx/common/exceptions.py
Expand Up @@ -35,7 +35,9 @@ def __init__(self, msg):
class MissingConverter(RuntimeError):
"""
Raised when there is no registered converter
for a machine learning operator.
for a machine learning operator. If the model is
part of scikit-learn, you may raise an issue at
https://github.com/onnx/sklearn-onnx/issues.
"""
def __init__(self, msg):
super().__init__(msg + _missing_converter)
4 changes: 2 additions & 2 deletions skl2onnx/common/shape_calculator.py
Expand Up @@ -32,7 +32,7 @@ def calculate_linear_classifier_output_shapes(operator):
FloatTensorType, Int64TensorType])

if len(operator.inputs[0].type.shape) != 2:
raise RuntimeError('Input must be a [N, C]-tensor')
raise RuntimeError('Inputs must be a [N, C]-tensor.')

N = operator.inputs[0].type.shape[0]

Expand All @@ -59,7 +59,7 @@ def calculate_linear_classifier_output_shapes(operator):
# the positive class
operator.outputs[1].type = FloatTensorType(shape=[N, 1])
else:
raise ValueError('Unsupported or mixed label types')
raise ValueError('Label types must be all integers or all strings.')


def calculate_linear_regressor_output_shapes(operator):
Expand Down
2 changes: 1 addition & 1 deletion skl2onnx/helpers/investigate.py
Expand Up @@ -71,7 +71,7 @@ def enumerate_pipeline_models(pipe, coor=None, vs=None):
pass
else:
raise TypeError(
"pipe is not a scikit-learn object: {}\n{}".format(
"Parameter pipe is not a scikit-learn object: {}\n{}".format(
type(pipe), pipe))


Expand Down
6 changes: 3 additions & 3 deletions skl2onnx/helpers/onnx_helper.py
Expand Up @@ -50,7 +50,7 @@ def enumerate_model_node_outputs(model):
Enumerates all the node of a model.
"""
if not hasattr(model, "graph"):
raise TypeError("*model* is not an *ONNX* model but "
raise TypeError("Parameter model is not an ONNX model but "
"{}".format(type(model)))
for node in model.graph.node:
for out in node.output:
Expand All @@ -69,9 +69,9 @@ def select_model_inputs_outputs(model, outputs=None, inputs=None):
The function removes unneeded files.
"""
if inputs is not None:
raise NotImplementedError("Inputs cannot be changed yet.")
raise NotImplementedError("Parameter inputs cannot be empty.")
if outputs is None:
raise RuntimeError("outputs and inputs are None")
raise RuntimeError("Parameter outputs cannot be None.")
if not isinstance(outputs, list):
outputs = [outputs]

Expand Down
4 changes: 2 additions & 2 deletions skl2onnx/operator_converters/common.py
Expand Up @@ -34,8 +34,8 @@ def concatenate_variables(scope, variables, container):
number_type_set = {FloatType, FloatTensorType, Int64Type, Int64TensorType}
if (StringType in type_set and
any(number_type in type_set for number_type in number_type_set)):
raise RuntimeError('We are not able to concatenate numerical '
'tensor(s) and string tensor(s)')
raise RuntimeError('Numerical tensor(s) and string tensor(s) '
'cannot be concatenated.')
# input variables' names we want to concatenate
input_names = []
# dimensions of the variables that is going to be concatenated
Expand Down
2 changes: 1 addition & 1 deletion skl2onnx/operator_converters/decision_tree.py
Expand Up @@ -34,7 +34,7 @@ def convert_sklearn_decision_tree_classifier(scope, operator, container):
class_labels = [str(i) for i in classes]
attrs['classlabels_strings'] = class_labels
else:
raise ValueError('Only support pure string or integer class labels')
raise ValueError('Labels must be all integers or all strings.')

add_tree_to_attribute_pairs(attrs, True, op.tree_, 0, 1., 0, True)

Expand Down

0 comments on commit f427759

Please sign in to comment.