From 4dce6e3c1751faf47bb6911c01af411a9f354101 Mon Sep 17 00:00:00 2001 From: IanCa Date: Mon, 3 Jul 2023 12:14:28 -0500 Subject: [PATCH 1/4] Revert inflect changes as it's fixed --- docs/requirements.txt | 3 +-- requirements.txt | 3 +-- setup.cfg | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index b3aa11ea9..3e8ec466f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,10 +1,9 @@ defusedxml>=0.7.1 -inflect==6.0.2 +inflect>=6.1.0 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 diff --git a/requirements.txt b/requirements.txt index f23f4bd4d..ea38afe5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,8 @@ defusedxml>=0.7.1 -inflect==6.0.2 +inflect>=6.1.0 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 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index da19578ed..fbd9ad553 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,6 @@ install_requires = openpyxl pandas portalocker - pydantic < 2 python-dateutil pytz semantic-version From 9dffeb9340085e415e621822c1a5fe3105f64a59 Mon Sep 17 00:00:00 2001 From: IanCa Date: Mon, 3 Jul 2023 12:25:04 -0500 Subject: [PATCH 2/4] Lower requirement to 6.0.5 for python 37 --- docs/requirements.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 3e8ec466f..952120af1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ defusedxml>=0.7.1 -inflect>=6.1.0 +inflect>=6.0.5 numpy>=1.21.6 openpyxl>=3.1.0 pandas>=1.3.5 diff --git a/requirements.txt b/requirements.txt index ea38afe5d..07c3304d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ defusedxml>=0.7.1 -inflect>=6.1.0 +inflect>=6.0.5 numpy>=1.21.6 openpyxl>=3.1.0 pandas>=1.3.5 From 9844ada9e8b67b60b8a9f65ffd6936f40928f91c Mon Sep 17 00:00:00 2001 From: IanCa Date: Mon, 3 Jul 2023 14:33:23 -0500 Subject: [PATCH 3/4] Throw hed file error in base input --- hed/errors/exceptions.py | 1 + hed/models/base_input.py | 20 +++++++++++--------- hed/models/sidecar.py | 11 +++++------ hed/models/tabular_input.py | 4 ++-- tests/models/test_base_input.py | 15 +++++++++++++++ tests/models/test_sidecar.py | 12 ++++++++++++ tests/models/test_spreadsheet_input.py | 1 + tests/models/test_tabular_input.py | 15 +++++++++++++++ 8 files changed, 62 insertions(+), 17 deletions(-) diff --git a/hed/errors/exceptions.py b/hed/errors/exceptions.py index 59ca86340..9f8ddbeb7 100644 --- a/hed/errors/exceptions.py +++ b/hed/errors/exceptions.py @@ -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' diff --git a/hed/models/base_input.py b/hed/models/base_input.py index f0c96eaaf..5a78729e8 100644 --- a/hed/models/base_input.py +++ b/hed/models/base_input.py @@ -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: @@ -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) diff --git a/hed/models/sidecar.py b/hed/models/sidecar.py index 735ad3f8b..867ba2e20 100644 --- a/hed/models/sidecar.py +++ b/hed/models/sidecar.py @@ -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) @@ -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. diff --git a/hed/models/tabular_input.py b/hed/models/tabular_input.py index b88ed5581..1b9570105 100644 --- a/hed/models/tabular_input.py +++ b/hed/models/tabular_input.py @@ -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: diff --git a/tests/models/test_base_input.py b/tests/models/test_base_input.py index bda6e1259..d93983d59 100644 --- a/tests/models/test_base_input.py +++ b/tests/models/test_base_input.py @@ -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 @@ -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): diff --git a/tests/models/test_sidecar.py b/tests/models/test_sidecar.py index 8383de6f8..897d01563 100644 --- a/tests/models/test_sidecar.py +++ b/tests/models/test_sidecar.py @@ -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" diff --git a/tests/models/test_spreadsheet_input.py b/tests/models/test_spreadsheet_input.py index 0a1d83a2e..eeee6bc8d 100644 --- a/tests/models/test_spreadsheet_input.py +++ b/tests/models/test_spreadsheet_input.py @@ -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) diff --git a/tests/models/test_tabular_input.py b/tests/models/test_tabular_input.py index c3c01f2b7..95eb527f0 100644 --- a/tests/models/test_tabular_input.py +++ b/tests/models/test_tabular_input.py @@ -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) @@ -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() From fdaca385163690efca7c3eb581204c05e39ca7e1 Mon Sep 17 00:00:00 2001 From: IanCa Date: Mon, 3 Jul 2023 14:57:18 -0500 Subject: [PATCH 4/4] Fix typo in wordcloud --- hed/tools/visualization/tag_word_cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hed/tools/visualization/tag_word_cloud.py b/hed/tools/visualization/tag_word_cloud.py index 4e352f387..c8d4159d7 100644 --- a/hed/tools/visualization/tag_word_cloud.py +++ b/hed/tools/visualization/tag_word_cloud.py @@ -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)