diff --git a/src/natcap/invest/validation.py b/src/natcap/invest/validation.py index b94ac2c35..01d22526b 100644 --- a/src/natcap/invest/validation.py +++ b/src/natcap/invest/validation.py @@ -166,8 +166,8 @@ def check_directory(dirpath, must_exist=True, permissions='rx', **kwargs): must_exist=True (bool): If ``True``, the directory at ``dirpath`` must already exist on the filesystem. permissions='rx' (string): A string that includes the lowercase - characters ``r``, ``w`` and/or ``x``, indicating read, write, and execute - permissions (respectively) required for this directory. + characters ``r``, ``w`` and/or ``x``, indicating read, write, and + execute permissions (respectively) required for this directory. Returns: A string error message if an error was found. ``None`` otherwise. @@ -197,25 +197,27 @@ def check_directory(dirpath, must_exist=True, permissions='rx', **kwargs): if 'r' in permissions: try: os.scandir(dirpath).close() - except: + except OSError: return MESSAGES[MESSAGE_KEY].format(permission='read') - # Check for x access before checking for w, since w operations to a dir are dependent on x access + # Check for x access before checking for w, + # since w operations to a dir are dependent on x access if 'x' in permissions: try: cwd = os.getcwd() os.chdir(dirpath) - os.chdir(cwd) - except: + except OSError: return MESSAGES[MESSAGE_KEY].format(permission='execute') + finally: + os.chdir(cwd) if 'w' in permissions: try: - temp_path = os.path.join(dirpath, '__temp__workspace_validation_check.txt') + temp_path = os.path.join(dirpath, 'temp__workspace_validation.txt') with open(temp_path, 'w') as temp: temp.close() os.remove(temp_path) - except: + except OSError: return MESSAGES[MESSAGE_KEY].format(permission='write') @@ -225,8 +227,8 @@ def check_file(filepath, permissions='r', **kwargs): Args: filepath (string): The filepath to validate. permissions='r' (string): A string that includes the lowercase - characters ``r``, ``w`` and/or ``x``, indicating read, write, and execute - permissions (respectively) required for this file. + characters ``r``, ``w`` and/or ``x``, indicating read, write, and + execute permissions (respectively) required for this file. Returns: A string error message if an error was found. ``None`` otherwise. diff --git a/tests/test_validation.py b/tests/test_validation.py index 35da3a2ae..f5ad094f5 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -1,9 +1,6 @@ """Testing module for validation.""" -import codecs -import collections import functools import os -import platform import shutil import stat import string @@ -331,63 +328,91 @@ def test_workspace_not_exists(self): self.assertEqual(None, validation.check_directory( new_dir, must_exist=False, permissions='rwx')) -@unittest.skipIf(sys.platform.startswith('win'), 'requires support for os.chmod(), which is unreliable on Windows') + +@unittest.skipIf( + sys.platform.startswith('win'), + 'requires support for os.chmod(), which is unreliable on Windows') class DirectoryValidationMacOnly(unittest.TestCase): """Test Directory Permissions Validation.""" def test_invalid_permissions_r(self): - """Validation: when a folder must have read/write/execute permissions but is missing write and execute permissions.""" + """Validation: when a folder must have read/write/execute + permissions but is missing write and execute permissions.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IREAD) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='execute')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='execute')) def test_invalid_permissions_w(self): - """Validation: when a folder must have read/write/execute permissions but is missing read and execute permissions.""" + """Validation: when a folder must have read/write/execute + permissions but is missing read and execute permissions.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IWRITE) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) def test_invalid_permissions_x(self): - """Validation: when a folder must have read/write/execute permissions but is missing read and write permissions.""" + """Validation: when a folder must have read/write/execute + permissions but is missing read and write permissions.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IEXEC) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) def test_invalid_permissions_rw(self): - """Validation: when a folder must have read/write/execute permissions but is missing execute permission.""" + """Validation: when a folder must have read/write/execute + permissions but is missing execute permission.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IREAD | stat.S_IWRITE) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='execute')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='execute')) def test_invalid_permissions_rx(self): - """Validation: when a folder must have read/write/execute permissions but is missing write permission.""" + """Validation: when a folder must have read/write/execute + permissions but is missing write permission.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IREAD | stat.S_IEXEC) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='write')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='write')) def test_invalid_permissions_wx(self): - """Validation: when a folder must have read/write/execute permissions but is missing read permission.""" + """Validation: when a folder must have read/write/execute + permissions but is missing read permission.""" from natcap.invest import validation with tempfile.TemporaryDirectory() as tempdir: os.chmod(tempdir, stat.S_IWRITE | stat.S_IEXEC) - validation_warning = validation.check_directory(tempdir, permissions='rwx') - self.assertEqual(validation_warning, validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) + validation_warning = validation.check_directory(tempdir, + permissions='rwx') + self.assertEqual( + validation_warning, + validation.MESSAGES['NEED_PERMISSION_DIRECTORY'].format(permission='read')) + class FileValidation(unittest.TestCase): """Test File Validator.""" @@ -598,7 +623,6 @@ def test_vector_projected_in_m(self): def test_wrong_geom_type(self): """Validation: checks that the vector's geometry type is correct.""" - from natcap.invest import spec_utils from natcap.invest import validation driver = gdal.GetDriverByName('GPKG') filepath = os.path.join(self.workspace_dir, 'vector.gpkg') @@ -1428,7 +1452,6 @@ def test_csv_raster_validation_missing_file(self): }) self.assertIn('File not found', str(cm.exception)) - def test_csv_raster_validation_not_projected(self): """validation: validate unprojected raster within csv column""" from natcap.invest import validation