Skip to content
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

ORM: replace InputValidationError with ValueError and TypeError #4888

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions aiida/cmdline/commands/cmd_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from aiida.cmdline.params.options.commands import code as options_code
from aiida.cmdline.utils import echo
from aiida.cmdline.utils.decorators import with_dbenv
from aiida.common.exceptions import InputValidationError


@verdi.group('code')
Expand Down Expand Up @@ -76,7 +75,6 @@ def set_code_builder(ctx, param, value):
@with_dbenv()
def setup_code(non_interactive, **kwargs):
"""Setup a new code."""
from aiida.common.exceptions import ValidationError
from aiida.orm.utils.builders.code import CodeBuilder

if kwargs.pop('on_computer'):
Expand All @@ -88,15 +86,15 @@ def setup_code(non_interactive, **kwargs):

try:
code = code_builder.new()
except InputValidationError as exception:
except ValueError as exception:
echo.echo_critical(f'invalid inputs: {exception}')

try:
code.store()
code.reveal()
except ValidationError as exception:
ramirezfranciscof marked this conversation as resolved.
Show resolved Hide resolved
except Exception as exception: # pylint: disable=broad-except
echo.echo_critical(f'Unable to store the Code: {exception}')

code.reveal()
echo.echo_success(f'Code<{code.pk}> {code.full_label} created')


Expand Down Expand Up @@ -244,7 +242,7 @@ def relabel(code, label):

try:
code.relabel(label)
except InputValidationError as exception:
except (TypeError, ValueError) as exception:
echo.echo_critical(f'invalid code label: {exception}')
else:
echo.echo_success(f'Code<{code.pk}> relabeled from {old_label} to {code.full_label}')
Expand Down
13 changes: 6 additions & 7 deletions aiida/orm/implementation/django/querybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from sqlalchemy.types import Float, Boolean

from aiida.backends.djsite.db import models
from aiida.common.exceptions import InputValidationError
from aiida.orm.implementation.querybuilder import BackendQueryBuilder


Expand Down Expand Up @@ -191,19 +190,19 @@ def get_filter_expr(self, operator, value, attr_key, is_attribute, alias=None, c
negation = False
if operator in ('longer', 'shorter', 'of_length'):
if not isinstance(value, int):
raise InputValidationError('You have to give an integer when comparing to a length')
raise TypeError('You have to give an integer when comparing to a length')
elif operator in ('like', 'ilike'):
if not isinstance(value, str):
raise InputValidationError(f'Value for operator {operator} has to be a string (you gave {value})')
raise TypeError(f'Value for operator {operator} has to be a string (you gave {value})')
elif operator == 'in':
try:
value_type_set = set(type(i) for i in value)
except TypeError:
raise TypeError('Value for operator `in` could not be iterated')
if not value_type_set:
raise InputValidationError('Value for operator `in` is an empty list')
raise ValueError('Value for operator `in` is an empty list')
if len(value_type_set) > 1:
raise InputValidationError(f'Value for operator `in` contains more than one type: {value}')
raise ValueError(f'Value for operator `in` contains more than one type: {value}')
elif operator in ('and', 'or'):
expressions_for_this_path = []
for filter_operation_dict in value:
Expand Down Expand Up @@ -298,7 +297,7 @@ def cast_according_to_type(path_in_json, value):
# Possible types are object, array, string, number, boolean, and null.
valid_types = ('object', 'array', 'string', 'number', 'boolean', 'null')
if value not in valid_types:
raise InputValidationError(f'value {value} for of_type is not among valid types\n{valid_types}')
raise ValueError(f'value {value} for of_type is not among valid types\n{valid_types}')
expr = jsonb_typeof(database_entity) == value
elif operator == 'like':
type_filter, casted_entity = cast_according_to_type(database_entity, value)
Expand Down Expand Up @@ -330,7 +329,7 @@ def cast_according_to_type(path_in_json, value):
],
else_=False)
else:
raise InputValidationError(f'Unknown operator {operator} for filters in JSON field')
raise ValueError(f'Unknown operator {operator} for filters in JSON field')
return expr

@staticmethod
Expand Down
20 changes: 7 additions & 13 deletions aiida/orm/implementation/querybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
import abc
import uuid

# pylint: disable=no-name-in-module, import-error
# pylint: disable=no-name-in-module,import-error
from sqlalchemy_utils.types.choice import Choice
from sqlalchemy.types import Integer, Float, Boolean, DateTime
from sqlalchemy.dialects.postgresql import JSONB

from aiida.common import exceptions
from aiida.common.lang import type_check
from aiida.common.exceptions import InputValidationError

__all__ = ('BackendQueryBuilder',)

Expand Down Expand Up @@ -220,7 +218,7 @@ def get_filter_expr_from_column(cls, operator, value, column):
elif operator == 'in':
expr = database_entity.in_(value)
else:
raise InputValidationError(f'Unknown operator {operator} for filters on columns')
raise ValueError(f'Unknown operator {operator} for filters on columns')
return expr

def get_projectable_attribute(self, alias, column_name, attrpath, cast=None, **kwargs):
Expand All @@ -244,7 +242,7 @@ def get_projectable_attribute(self, alias, column_name, attrpath, cast=None, **k
elif cast == 'd':
entity = entity.astext.cast(DateTime)
else:
raise InputValidationError(f'Unkown casting key {cast}')
raise ValueError(f'Unkown casting key {cast}')
return entity

def get_aiida_res(self, res):
Expand Down Expand Up @@ -399,13 +397,9 @@ def get_column(self, colname, alias): # pylint: disable=no-self-use
"""
try:
return getattr(alias, colname)
except AttributeError:
raise exceptions.InputValidationError(
except AttributeError as exc:
raise ValueError(
sphuber marked this conversation as resolved.
Show resolved Hide resolved
'{} is not a column of {}\n'
'Valid columns are:\n'
'{}'.format(
colname,
alias,
'\n'.join(alias._sa_class_manager.mapper.c.keys()) # pylint: disable=protected-access
)
)
'{}'.format(colname, alias, '\n'.join(alias._sa_class_manager.mapper.c.keys())) # pylint: disable=protected-access
) from exc
13 changes: 6 additions & 7 deletions aiida/orm/implementation/sqlalchemy/querybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from sqlalchemy.sql.expression import case, FunctionElement
from sqlalchemy.ext.compiler import compiles

from aiida.common.exceptions import InputValidationError
from aiida.common.exceptions import NotExistent
from aiida.orm.implementation.querybuilder import BackendQueryBuilder

Expand Down Expand Up @@ -220,20 +219,20 @@ def get_filter_expr(self, operator, value, attr_key, is_attribute, alias=None, c
negation = False
if operator in ('longer', 'shorter', 'of_length'):
if not isinstance(value, int):
raise InputValidationError('You have to give an integer when comparing to a length')
raise TypeError('You have to give an integer when comparing to a length')
elif operator in ('like', 'ilike'):
if not isinstance(value, str):
raise InputValidationError(f'Value for operator {operator} has to be a string (you gave {value})')
raise TypeError(f'Value for operator {operator} has to be a string (you gave {value})')

elif operator == 'in':
try:
value_type_set = set(type(i) for i in value)
except TypeError:
raise TypeError('Value for operator `in` could not be iterated')
if not value_type_set:
raise InputValidationError('Value for operator `in` is an empty list')
raise ValueError('Value for operator `in` is an empty list')
if len(value_type_set) > 1:
raise InputValidationError(f'Value for operator `in` contains more than one type: {value}')
raise ValueError(f'Value for operator `in` contains more than one type: {value}')
elif operator in ('and', 'or'):
expressions_for_this_path = []
for filter_operation_dict in value:
Expand Down Expand Up @@ -322,7 +321,7 @@ def cast_according_to_type(path_in_json, value):
# Possible types are object, array, string, number, boolean, and null.
valid_types = ('object', 'array', 'string', 'number', 'boolean', 'null')
if value not in valid_types:
raise InputValidationError(f'value {value} for of_type is not among valid types\n{valid_types}')
raise ValueError(f'value {value} for of_type is not among valid types\n{valid_types}')
expr = jsonb_typeof(database_entity) == value
elif operator == 'like':
type_filter, casted_entity = cast_according_to_type(database_entity, value)
Expand Down Expand Up @@ -354,7 +353,7 @@ def cast_according_to_type(path_in_json, value):
],
else_=False)
else:
raise InputValidationError(f'Unknown operator {operator} for filters in JSON field')
raise ValueError(f'Unknown operator {operator} for filters in JSON field')
return expr

@staticmethod
Expand Down
5 changes: 2 additions & 3 deletions aiida/orm/nodes/data/array/trajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,6 @@ def show_mpl_pos(self, **kwargs): # pylint: disable=too-many-locals
:param bool dont_block: If True, interpreter is not blocked when figure is displayed.
"""
from ase.data import atomic_numbers
from aiida.common.exceptions import InputValidationError

# Reading the arrays I need:
positions = self.get_positions()
Expand Down Expand Up @@ -632,9 +631,9 @@ def show_mpl_pos(self, **kwargs): # pylint: disable=too-many-locals
elif colors == 'cpk':
from ase.data.colors import cpk_colors as colors
else:
raise InputValidationError(f'Unknown color spec {colors}')
raise ValueError(f'Unknown color spec {colors}')
if kwargs:
raise InputValidationError(f'Unrecognized keyword {kwargs.keys()}')
raise ValueError(f'Unrecognized keyword {kwargs.keys()}')

if element_list is None:
# If not all elements are allowed
Expand Down
24 changes: 12 additions & 12 deletions aiida/orm/nodes/data/array/xy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
on them.
"""
import numpy as np
from aiida.common.exceptions import InputValidationError, NotExistent
from aiida.common.exceptions import NotExistent
from .array import ArrayData


Expand Down Expand Up @@ -43,19 +43,19 @@ class XyData(ArrayData):
def _arrayandname_validator(array, name, units):
"""
Validates that the array is an numpy.ndarray and that the name is
of type str. Raises InputValidationError if this not the case.
of type str. Raises TypeError or ValueError if this not the case.
"""
if not isinstance(name, str):
raise InputValidationError('The name must always be a str.')
raise TypeError('The name must always be a str.')

if not isinstance(array, np.ndarray):
raise InputValidationError('The input array must always be a numpy array')
raise TypeError('The input array must always be a numpy array')
try:
array.astype(float)
except ValueError:
raise InputValidationError('The input array must only contain floats')
except ValueError as exc:
raise TypeError('The input array must only contain floats') from exc
if not isinstance(units, str):
raise InputValidationError('The units must always be a str.')
raise TypeError('The units must always be a str.')

def set_x(self, x_array, x_name, x_units):
"""
Expand Down Expand Up @@ -86,20 +86,20 @@ def set_y(self, y_arrays, y_names, y_units):

# checks that the input lengths match
if len(y_arrays) != len(y_names):
raise InputValidationError('Length of arrays and names do not match!')
raise ValueError('Length of arrays and names do not match!')
if len(y_units) != len(y_names):
raise InputValidationError('Length of units does not match!')
raise ValueError('Length of units does not match!')

# Try to get the x_array
try:
x_array = self.get_x()[1]
except NotExistent:
raise InputValidationError('X array has not been set yet')
except NotExistent as exc:
raise ValueError('X array has not been set yet') from exc
# validate each of the y_arrays
for num, (y_array, y_name, y_unit) in enumerate(zip(y_arrays, y_names, y_units)):
self._arrayandname_validator(y_array, y_name, y_unit)
if np.shape(y_array) != np.shape(x_array):
raise InputValidationError(f'y_array {y_name} did not have the same shape has the x_array!')
raise ValueError(f'y_array {y_name} did not have the same shape has the x_array!')
self.set_array(f'y_array_{num}', y_array)

# if the y_arrays pass the initial validation, sets each
Expand Down
12 changes: 6 additions & 6 deletions aiida/orm/nodes/data/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def label(self, value):
"""
if '@' in str(value):
msg = "Code labels must not contain the '@' symbol"
raise exceptions.InputValidationError(msg)
raise ValueError(msg)

super(Code, self.__class__).label.fset(self, value) # pylint: disable=no-member

Expand Down Expand Up @@ -191,7 +191,7 @@ def get(cls, pk=None, label=None, machinename=None):

:raise aiida.common.NotExistent: if no code identified by the given string is found
:raise aiida.common.MultipleObjectsError: if the string cannot identify uniquely a code
:raise aiida.common.InputValidationError: if neither a pk nor a label was passed in
:raise ValueError: if neither a pk nor a label was passed in
"""
# pylint: disable=arguments-differ
from aiida.orm.utils import load_code
Expand All @@ -211,7 +211,7 @@ def get(cls, pk=None, label=None, machinename=None):
return cls.get_code_helper(label, machinename)

else:
raise exceptions.InputValidationError('Pass either pk or code label (and machinename)')
raise ValueError('Pass either pk or code label (and machinename)')

@classmethod
def get_from_string(cls, code_string):
Expand All @@ -230,15 +230,15 @@ def get_from_string(cls, code_string):
:raise aiida.common.NotExistent: if no code identified by the given string is found
:raise aiida.common.MultipleObjectsError: if the string cannot identify uniquely
a code
:raise aiida.common.InputValidationError: if code_string is not of string type
:raise TypeError: if code_string is not of string type

"""
from aiida.common.exceptions import NotExistent, MultipleObjectsError, InputValidationError
from aiida.common.exceptions import NotExistent, MultipleObjectsError

try:
label, _, machinename = code_string.partition('@')
except AttributeError:
raise InputValidationError('the provided code_string is not of valid string type')
raise TypeError('the provided code_string is not of valid string type')

try:
return cls.get_code_helper(label, machinename)
Expand Down
4 changes: 2 additions & 2 deletions aiida/orm/nodes/data/orbital.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""Data plugin to model an atomic orbital."""
import copy

from aiida.common.exceptions import ValidationError, InputValidationError
from aiida.common.exceptions import ValidationError
from aiida.plugins import OrbitalFactory
from .data import Data

Expand Down Expand Up @@ -80,7 +80,7 @@ def set_orbitals(self, orbitals):
try:
_orbital_type = orbital_dict['_orbital_type']
except KeyError:
raise InputValidationError(f'No _orbital_type found in: {orbital_dict}')
raise ValueError(f'No _orbital_type found in: {orbital_dict}')
orbital_dicts.append(orbital_dict)
self.set_attribute('orbital_dicts', orbital_dicts)

Expand Down
Loading