Skip to content
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
3 changes: 1 addition & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
defusedxml>=0.7.1
inflect==6.0.2
inflect>=6.0.5
numpy>=1.21.6
openpyxl>=3.1.0
pandas>=1.3.5
portalocker>=2.7.0
pydantic<2 # For compatibility with inflect
semantic_version>=2.10.0
Sphinx>=5.2.2
sphinx_rtd_theme>=1.0.0
Expand Down
1 change: 1 addition & 0 deletions hed/errors/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


class HedExceptions:
GENERIC_ERROR = 'GENERIC_ERROR'
# A list of all exceptions that can be generated by the hedtools.
FILE_NOT_FOUND = 'fileNotFound'
BAD_PARAMETERS = 'badParameters'
Expand Down
20 changes: 11 additions & 9 deletions hed/models/base_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,7 @@ def __init__(self, file, file_type=None, worksheet_name=None, has_column_names=T
- An invalid dataframe was passed with size 0
- An invalid extension was provided
- A duplicate or empty column name appears

:raises OSError:
- Cannot open the indicated file

:raises KeyError:
- The specified worksheet name does not exist
"""
if mapper is None:
Expand Down Expand Up @@ -77,14 +73,20 @@ def __init__(self, file, file_type=None, worksheet_name=None, has_column_names=T
elif not file:
raise HedFileError(HedExceptions.FILE_NOT_FOUND, "Empty file passed to BaseInput.", file)
elif input_type in self.TEXT_EXTENSION:
self._dataframe = pandas.read_csv(file, delimiter='\t', header=pandas_header,
dtype=str, keep_default_na=True, na_values=None)
try:
self._dataframe = pandas.read_csv(file, delimiter='\t', header=pandas_header,
dtype=str, keep_default_na=True, na_values=None)
except Exception as e:
raise HedFileError(HedExceptions.GENERIC_ERROR, str(e), self.name) from e
# Convert nan values to a known value
self._dataframe = self._dataframe.fillna("n/a")
elif input_type in self.EXCEL_EXTENSION:
self._loaded_workbook = openpyxl.load_workbook(file)
loaded_worksheet = self.get_worksheet(self._worksheet_name)
self._dataframe = self._get_dataframe_from_worksheet(loaded_worksheet, has_column_names)
try:
self._loaded_workbook = openpyxl.load_workbook(file)
loaded_worksheet = self.get_worksheet(self._worksheet_name)
self._dataframe = self._get_dataframe_from_worksheet(loaded_worksheet, has_column_names)
except Exception as e:
raise HedFileError(HedExceptions.GENERIC_ERROR, str(e), self.name) from e
else:
raise HedFileError(HedExceptions.INVALID_EXTENSION, "", file)

Expand Down
11 changes: 5 additions & 6 deletions hed/models/sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ def load_sidecar_file(self, file):
if not self.name:
self.name = file
return self._load_json_file(fp)
except FileNotFoundError as e:
raise HedFileError(HedExceptions.FILE_NOT_FOUND, e.strerror, file)
except OSError as e:
raise HedFileError(HedExceptions.FILE_NOT_FOUND, e.strerror, file) from e
except TypeError as e:
raise HedFileError(HedExceptions.FILE_NOT_FOUND, str(e), file)
raise HedFileError(HedExceptions.FILE_NOT_FOUND, str(e), file) from e
else:
return self._load_json_file(file)

Expand Down Expand Up @@ -189,12 +189,11 @@ def _load_json_file(self, fp):

:raises HedFileError:
- If the file cannot be parsed.

"""
try:
return json.load(fp)
except json.decoder.JSONDecodeError as e:
raise HedFileError(HedExceptions.CANNOT_PARSE_JSON, str(e), self.name)
except (json.decoder.JSONDecodeError, AttributeError) as e:
raise HedFileError(HedExceptions.CANNOT_PARSE_JSON, str(e), self.name) from e

def extract_definitions(self, hed_schema=None, error_handler=None):
""" Gather and validate definitions in metadata.
Expand Down
4 changes: 2 additions & 2 deletions hed/models/tabular_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def __init__(self, file=None, sidecar=None, name=None):
""" Constructor for the TabularInput class.

Parameters:
file (str or file like): A tsv file to open.
sidecar (str or Sidecar): A Sidecar filename or Sidecar
file (str or FileLike): A tsv file to open.
sidecar (str or Sidecar or FileLike): A Sidecar or source file/filename.
name (str): The name to display for this file for error purposes.

:raises HedFileError:
Expand Down
2 changes: 1 addition & 1 deletion hed/tools/visualization/tag_word_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def create_wordcloud(word_dict, mask_path=None, background_color=None, width=400
kwargs.setdefault('contour_width', 3)
kwargs.setdefault('contour_color', 'black')
kwargs.setdefault('prefer_horizontal', 0.75)
kwargs.setdefault('default_color_func', default_color_func)
kwargs.setdefault('color_func', default_color_func)
kwargs.setdefault('relative_scaling', 1)
kwargs.setdefault('max_font_size', height / 15)
kwargs.setdefault('min_font_size', 5)
Expand Down
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
defusedxml>=0.7.1
inflect==6.0.2
inflect>=6.0.5
numpy>=1.21.6
openpyxl>=3.1.0
pandas>=1.3.5
portalocker>=2.7.0
pydantic<2 # For compatibility with inflect
semantic_version>=2.10.0
wordcloud==1.9.2
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ install_requires =
openpyxl
pandas
portalocker
pydantic < 2
python-dateutil
pytz
semantic-version
Expand Down
15 changes: 15 additions & 0 deletions tests/models/test_base_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from hed.models.column_mapper import ColumnMapper
from hed.models import DefinitionDict
from hed import schema
from hed import HedFileError

import pandas as pd
import numpy as np

Expand Down Expand Up @@ -60,6 +62,19 @@ def test_gathered_defs(self):
}
self.assertEqual(defs, expected_defs)

def test_file_not_found(self):
with self.assertRaises(HedFileError):
BaseInput('nonexistent_file.tsv')

def test_invalid_input_type_int(self):
with self.assertRaises(HedFileError):
BaseInput(123)

def test_invalid_input_type_dict(self):
with self.assertRaises(HedFileError):
BaseInput({'key': 'value'})



class TestInsertColumns(unittest.TestCase):

Expand Down
12 changes: 12 additions & 0 deletions tests/models/test_sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ def setUpClass(cls):
def tearDownClass(cls):
shutil.rmtree(cls.base_output_folder)

def test_file_not_found(self):
with self.assertRaises(HedFileError):
Sidecar('nonexistent_file.json')

def test_invalid_input_type_int(self):
with self.assertRaises(HedFileError):
Sidecar(123)

def test_invalid_input_type_dict(self):
with self.assertRaises(HedFileError):
Sidecar({'key': 'value'})

def test_invalid_filenames(self):
# Handle missing or invalid files.
invalid_json = "invalidxmlfile.json"
Expand Down
1 change: 1 addition & 0 deletions tests/models/test_spreadsheet_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def setUpClass(cls):
cls.base_output_folder = base_output
os.makedirs(base_output, exist_ok=True)


@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.base_output_folder)
Expand Down
15 changes: 15 additions & 0 deletions tests/models/test_tabular_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def setUpClass(cls):
cls.sidecar2 = Sidecar(sidecar2_path, name='face_small_json')
cls.base_output_folder = base_output_folder

cls.invalid_inputs = [123, {'key': 'value'}, 'nonexistent_file.tsv']

@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.base_output_folder)
Expand Down Expand Up @@ -82,6 +84,19 @@ def test_validate_file_warnings(self):
issues2a = input_file2.validate(hed_schema=self.hed_schema, error_handler=ErrorHandler(False))
breakHere = 3

def test_invalid_file(self):
for invalid_input in self.invalid_inputs:
with self.subTest(input=invalid_input):
with self.assertRaises(HedFileError):
TabularInput(file=invalid_input)

def test_invalid_sidecar(self):
for invalid_input in self.invalid_inputs:
with self.subTest(input=invalid_input):
with self.assertRaises(HedFileError):
# Replace 'valid_path.tsv' with a path to an existing .tsv file
TabularInput(file=self.events_path, sidecar=invalid_input)


if __name__ == '__main__':
unittest.main()