Skip to content

Commit

Permalink
Merge fa04cf0 into 30ef7f4
Browse files Browse the repository at this point in the history
  • Loading branch information
thequilo committed Oct 13, 2018
2 parents 30ef7f4 + fa04cf0 commit 41841d5
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 65 deletions.
4 changes: 3 additions & 1 deletion sacred/config/captured_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sacred.config.custom_containers import FallbackDict
from sacred.config.signature import Signature
from sacred.randomness import create_rnd, get_seed
from sacred.utils import ConfigError


def create_captured_function(function, prefix=None):
Expand Down Expand Up @@ -43,7 +44,8 @@ def captured_function(wrapped, instance, args, kwargs):
wrapped.logger.debug("Started")
start_time = time.time()
# =================== run actual function =================================
result = wrapped(*args, **kwargs)
with ConfigError.track(wrapped):
result = wrapped(*args, **kwargs)
# =========================================================================
if wrapped.logger is not None:
stop_time = time.time()
Expand Down
7 changes: 5 additions & 2 deletions sacred/config/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections import OrderedDict
import sys

from sacred.utils import MissingConfigError

if sys.version_info[0] < 3: # python2
def get_argspec(f):
Expand Down Expand Up @@ -156,5 +157,7 @@ def _assert_no_missing_args(self, args, kwargs, bound):
free_params = self.get_free_parameters(args, kwargs, bound)
missing_args = [m for m in free_params if m not in self.kwargs]
if missing_args:
raise TypeError("{} is missing value(s) for {}".format(
self.name, missing_args))
raise MissingConfigError(
'{} is missing value(s):'.format(self.name),
missing_configs=missing_args
)
37 changes: 27 additions & 10 deletions sacred/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
from __future__ import division, print_function, unicode_literals

import inspect
import sys

import os.path
import sys
from collections import OrderedDict

from docopt import docopt, printable_usage
Expand All @@ -20,7 +19,8 @@
from sacred.config.signature import Signature
from sacred.ingredient import Ingredient
from sacred.initialize import create_run
from sacred.utils import print_filtered_stacktrace, ensure_wellformed_argv
from sacred.utils import print_filtered_stacktrace, ensure_wellformed_argv, \
SacredError, format_sacred_error

__all__ = ('Experiment',)

Expand Down Expand Up @@ -261,16 +261,33 @@ def run_commandline(self, argv=None):

try:
return self.run(cmd_name, config_updates, named_configs, {}, args)
except Exception:
if not self.current_run or self.current_run.debug:
except Exception as e:
if self.current_run:
debug = self.current_run.debug
else:
# The usual command line options are applied after the run
# object is built completely. Some exceptions (e.g.
# ConfigAddedError) are raised before this. In these cases,
# the debug flag must be checked manually.
debug = args.get('--debug', False)

if debug:
# Debug: Don't change behaviour, just re-raise exception
raise
elif self.current_run.pdb:
elif self.current_run and self.current_run.pdb:
# Print exception and attach pdb debugger
import traceback
import pdb
traceback.print_exception(*sys.exc_info())
pdb.post_mortem()
else:
print_filtered_stacktrace()
# Handle pretty printing of exceptions. This includes
# filtering the stacktrace and printing the usage, as
# specified by the exceptions attributes
if isinstance(e, SacredError):
print(format_sacred_error(e, short_usage), file=sys.stderr)
else:
print_filtered_stacktrace()
exit(1)

def open_resource(self, filename, mode='r'):
Expand Down Expand Up @@ -446,12 +463,12 @@ def _create_run(self, command_name=None, config_updates=None,
def _check_command(self, cmd_name):
commands = dict(self.gather_commands())
if cmd_name is not None and cmd_name not in commands:
return 'Error: Command "{}" not found. Available commands are: '\
return 'Error: Command "{}" not found. Available commands are: ' \
'{}'.format(cmd_name, ", ".join(commands.keys()))

if cmd_name is None:
return 'Error: No command found to be run. Specify a command'\
' or define main function. Available commands'\
return 'Error: No command found to be run. Specify a command' \
' or define main function. Available commands' \
' are: {}'.format(", ".join(commands.keys()))

def _handle_help(self, args, usage):
Expand Down
9 changes: 5 additions & 4 deletions sacred/ingredient.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,12 @@ def traverse_ingredients(self):
If a circular structure among ingredients was detected.
"""
if self._is_traversing:
raise CircularDependencyError()
raise CircularDependencyError(ingredients=[self])
else:
self._is_traversing = True
yield self, 0
for ingredient in self.ingredients:
for ingred, depth in ingredient.traverse_ingredients():
yield ingred, depth + 1
with CircularDependencyError.track(self):
for ingredient in self.ingredients:
for ingred, depth in ingredient.traverse_ingredients():
yield ingred, depth + 1
self._is_traversing = False
12 changes: 9 additions & 3 deletions sacred/initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
from sacred.utils import (convert_to_nested_dict, create_basic_stream_logger,
get_by_dotted_path, is_prefix, rel_path,
iterate_flattened, set_by_dotted_path,
recursive_update, iter_prefixes, join_paths)
recursive_update, iter_prefixes, join_paths,
NamedConfigNotFoundError, ConfigAddedError)


class Scaffold(object):
Expand Down Expand Up @@ -85,6 +86,10 @@ def run_named_config(self, config_name):
if os.path.exists(config_name):
nc = ConfigDict(load_config_file(config_name))
else:
if config_name not in self.named_configs:
raise NamedConfigNotFoundError(
named_config=config_name,
available_named_configs=tuple(self.named_configs.keys()))
nc = self.named_configs[config_name]

cfg = nc(fixed=self.get_config_updates_recursive(),
Expand Down Expand Up @@ -170,8 +175,9 @@ def finalize_initialization(self, run):
def _warn_about_suspicious_changes(self):
for add in sorted(self.config_mods.added):
if not set(iter_prefixes(add)).intersection(self.captured_args):
raise KeyError('Added a new config entry "{}" that is not used'
' anywhere'.format(add))
if self.path:
add = join_paths(self.path, add)
raise ConfigAddedError(add, config=self.config)
else:
self.logger.warning('Added new config entry: "%s"' % add)

Expand Down
Loading

0 comments on commit 41841d5

Please sign in to comment.