Skip to content

Commit

Permalink
Merge pull request #2591 from cta-observatory/fix_traits
Browse files Browse the repository at this point in the history
Fix error messages for non-existing path
  • Loading branch information
kosack authored Sep 11, 2024
2 parents f0a3cff + f217ede commit 4b85d1f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
1 change: 1 addition & 0 deletions docs/changes/2591.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix error message for non-existent config files.
18 changes: 9 additions & 9 deletions src/ctapipe/core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ def main():
trait=Path(
exists=True,
directory_ok=False,
help=(
"List of configuration files with parameters to load "
"in addition to command-line parameters. "
"The order listed is the order of precedence (later config parameters "
"overwrite earlier ones), however parameters specified on the "
"command line always have the highest precedence. "
"Config files may be in JSON, YAML, TOML, or Python format"
),
)
),
help=(
"List of configuration files with parameters to load "
"in addition to command-line parameters. "
"The order listed is the order of precedence (later config parameters "
"overwrite earlier ones), however parameters specified on the "
"command line always have the highest precedence. "
"Config files may be in JSON, YAML, TOML, or Python format"
),
).tag(config=True)

log_config = Dict(default_value={}).tag(config=True)
Expand Down
36 changes: 21 additions & 15 deletions src/ctapipe/core/traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@
logger = logging.getLogger(__name__)


class PathError:
"""Signal Non-Existence of a Path"""

def __init__(self, path, reason):
self.path = path
self.reason = reason

def __repr__(self):
return f"'{self.path}': {self.reason}"


# Aliases
Bool = traitlets.Bool
Int = traitlets.Int
Expand Down Expand Up @@ -111,9 +122,9 @@ def validate(self, obj, value):
try:
quantity = u.Quantity(value)
except TypeError:
return self.error(obj, value)
self.error(obj, value)
except ValueError:
return self.error(obj, value)
self.error(obj, value)

if self.physical_type is not None:
given_type = u.get_physical_type(quantity)
Expand All @@ -136,7 +147,7 @@ def validate(self, obj, value):
the_time.format = "iso"
return the_time
except ValueError:
return self.error(obj, value)
self.error(obj, value)

def info(self):
info = "an ISO8601 datestring or Time instance"
Expand Down Expand Up @@ -204,19 +215,19 @@ def validate(self, obj, value):
self.error(obj, value)

if not isinstance(value, str | pathlib.Path):
return self.error(obj, value)
self.error(obj, value)

# expand any environment variables in the path:
value = os.path.expandvars(value)

if isinstance(value, str):
if value == "":
return self.error(obj, value)
self.error(obj, value)

try:
url = urlparse(value)
except ValueError:
return self.error(obj, value)
self.error(obj, value)

if url.scheme in ("http", "https"):
# here to avoid circular import, since every module imports
Expand All @@ -233,23 +244,18 @@ def validate(self, obj, value):
elif url.scheme in ("", "file"):
value = pathlib.Path(url.netloc, url.path)
else:
return self.error(obj, value)
self.error(obj, value)

value = value.absolute()
exists = value.exists()
if self.exists is not None:
if exists != self.exists:
raise TraitError(
'Path "{}" {} exist'.format(
value, "does not" if self.exists else "must not"
)
)
raise TraitError(PathError(value, "does not exist"), self.info(), self)
if exists:
if not self.directory_ok and value.is_dir():
raise TraitError(f'Path "{value}" must not be a directory')
raise TraitError(PathError(value, "is a directory"), self.info(), self)
if not self.file_ok and value.is_file():
raise TraitError(f'Path "{value}" must not be a file')

raise TraitError(PathError(value, "is a file"), self.info(), self)
return value


Expand Down

0 comments on commit 4b85d1f

Please sign in to comment.