Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""Test logger."""
from routemaster.logging import BaseLogger
class TestLogger(BaseLogger):
"""This logger is loaded during tests."""
def __init__(self, config, *args, **kwargs):
super().__init__(config, *args, **kwargs)
self.kwargs = kwargs
class InvalidLogger(object):
"""
This logger cannot be loaded.
It does not inherit from `routemaster.logging.BaseLogger`.
"""
def dynamic_logger(config):
"""This is a callable rather than a class."""
def dynamic_logger(config):
"""This is a callable rather than a class."""
return BaseLogger(config)
def _validate_context_lookups(
path: Path,
lookups: Iterable[str],
feed_names: List[str],
) -> None:
# Changing this? Also change context lookups in
# `routemaster.context.Context`
VALID_TOP_LEVEL = ('feeds', 'history', 'metadata')
for lookup in lookups:
location, *rest = lookup.split('.')
if location not in VALID_TOP_LEVEL:
valid_top_level = join_comma_or(f"'{x}'" for x in VALID_TOP_LEVEL)
raise ConfigError(
f"Invalid context lookup at {'.'.join(path)}: key {lookup} "
f"must start with one of {valid_top_level}.",
)
if location == 'feeds':
feed_name = rest[0]
if feed_name not in feed_names:
valid_names = join_comma_or(f"'{x}'" for x in feed_names)
raise ConfigError(
f"Invalid feed name at {'.'.join(path)}: key {lookup} "
f"references unknown feed '{feed_name}' (configured "
VALID_TOP_LEVEL = ('feeds', 'history', 'metadata')
for lookup in lookups:
location, *rest = lookup.split('.')
if location not in VALID_TOP_LEVEL:
valid_top_level = join_comma_or(f"'{x}'" for x in VALID_TOP_LEVEL)
raise ConfigError(
f"Invalid context lookup at {'.'.join(path)}: key {lookup} "
f"must start with one of {valid_top_level}.",
)
if location == 'feeds':
feed_name = rest[0]
if feed_name not in feed_names:
valid_names = join_comma_or(f"'{x}'" for x in feed_names)
raise ConfigError(
f"Invalid feed name at {'.'.join(path)}: key {lookup} "
f"references unknown feed '{feed_name}' (configured "
def _validate_context_lookups(
path: Path,
lookups: Iterable[str],
feed_names: List[str],
) -> None:
# Changing this? Also change context lookups in
# `routemaster.context.Context`
VALID_TOP_LEVEL = ('feeds', 'history', 'metadata')
for lookup in lookups:
location, *rest = lookup.split('.')
if location not in VALID_TOP_LEVEL:
valid_top_level = join_comma_or(f"'{x}'" for x in VALID_TOP_LEVEL)
raise ConfigError(
f"Invalid context lookup at {'.'.join(path)}: key {lookup} "
f"must start with one of {valid_top_level}.",
)
if location == 'feeds':
feed_name = rest[0]
if feed_name not in feed_names:
valid_names = join_comma_or(f"'{x}'" for x in feed_names)
raise ConfigError(
f"Invalid feed name at {'.'.join(path)}: key {lookup} "
f"references unknown feed '{feed_name}' (configured "
def _validate_config(app: App):
try:
validate_config(app, app.config)
except ValidationError as e:
msg = f"Validation Error: {e}"
logger.exception(msg)
click.get_current_context().exit(1)
def main(ctx, config_files):
"""Shared entrypoint configuration."""
logging.getLogger('schedule').setLevel(logging.CRITICAL)
config_data = layer_loader.load_files(
config_files,
loader=yaml.load,
)
try:
config = load_config(config_data)
except ConfigError:
logger.exception("Configuration Error")
click.get_current_context().exit(1)
ctx.obj = App(config)
_validate_config(ctx.obj)
def all_destinations(self) -> Iterable[str]:
"""Returns the constant next state."""
return [self.state]
class ContextNextStatesOption(NamedTuple):
"""Represents an option for a context conditional next state."""
state: str
value: Any
class ContextNextStates(NamedTuple):
"""Defined a choice based on a path in the given `label_context`."""
path: str
destinations: Iterable[ContextNextStatesOption]
default: str # noqa: E704 misidentified "multiple statements on one line"
def next_state_for_label(self, label_context: 'Context') -> str:
"""Returns next state based on context value at `self.path`."""
val = label_context.lookup(self.path.split('.'))
for destination in self.destinations:
if destination.value == val:
return destination.state
return self.default
def all_destinations(self) -> Iterable[str]:
"""Returns all possible destination states."""
return [x.state for x in self.destinations] + [self.default]
class NoNextStates(NamedTuple):
def applies(path: Sequence[str], d: Dict[str, Any]) -> bool:
component, path = path[0], path[1:]
if component in d:
if path:
return applies(path, d[component])
return True
return False
return applies(self.metadata_path.split('.'), update)
@dataclass
class OnEntryTrigger:
"""Trigger on entry to a given gate."""
Trigger = Union[TimeTrigger, IntervalTrigger, MetadataTrigger, OnEntryTrigger]
class ConstantNextState(NamedTuple):
"""Defines a constant choice, always chooses `state`."""
state: str
def next_state_for_label(self, label_context: Any) -> str:
"""Returns the constant next state."""
return self.state
def all_destinations(self) -> Iterable[str]:
"""Returns the constant next state."""
return [self.state]
class ContextNextStatesOption(NamedTuple):
pass
# Is this an integer value?
try:
return Token(
kind=TokenKind.NUMBER,
value=int(raw_token.value),
location=raw_token.location,
)
except ValueError:
pass
# A float?
try:
return Token(
kind=TokenKind.NUMBER,
value=float(raw_token.value),
location=raw_token.location,
)
except ValueError:
pass
# A duration?
duration_match = RE_DURATION.match(raw_token.value)
if duration_match is not None:
total_length = (
int(duration_match.group(1) or '0') * 24 * 60 * 60 +
int(duration_match.group(2) or '0') * 60 * 60 +
int(duration_match.group(3) or '0') * 60 +
int(duration_match.group(4) or '0')
)
return Token(