-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathspecifiers.py
55 lines (40 loc) · 1.79 KB
/
specifiers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
"""Specifiers and associated objects."""
from typing import Any
from probRobScene.core.distributions import to_distribution
from probRobScene.core.lazy_eval import (DelayedArgument, toDelayedArgument, requiredProperties,
needs_lazy_evaluation, LazilyEvaluable)
from probRobScene.core.utils import RuntimeParseError
## Specifiers themselves
class Specifier:
"""Specifier providing a value for a property given dependencies.
Any optionally-specified properties are evaluated as attributes of the primary value.
"""
def __init__(self, prop, value, deps=None, optionals=None):
if deps is None:
deps = set()
if isinstance(value, LazilyEvaluable):
deps |= value.required_properties()
if optionals is None:
optionals = {}
self.property = prop
self.value = toDelayedArgument(value)
if prop in deps:
raise RuntimeParseError(f'specifier for property {prop} depends on itself')
self.requiredProperties = deps
self.optionals = optionals
def __str__(self):
return f'<Specifier of {self.property}>'
## Support for property defaults
class PropertyDefault:
"""A default value, possibly with dependencies."""
def __init__(self, requiredProperties, attributes, value):
self.requiredProperties = requiredProperties
self.value = value
def resolve_for(self, prop):
"""Create a Specifier for a property from this default and any superclass defaults."""
return Specifier(prop, DelayedArgument(self.requiredProperties, self.value))
def pd_for_value(value: Any) -> PropertyDefault:
if isinstance(value, PropertyDefault):
return value
else:
return PropertyDefault(set(), set(), lambda self: value)