asp.py: do not copy

This commit is contained in:
Harmen Stoppels 2024-04-18 11:51:31 +02:00 committed by Harmen Stoppels
parent 2bc2902fed
commit eb2ddf6fa2

View File

@ -15,6 +15,7 @@
import types import types
import typing import typing
import warnings import warnings
from contextlib import contextmanager
from typing import Callable, Dict, Iterator, List, NamedTuple, Optional, Set, Tuple, Type, Union from typing import Callable, Dict, Iterator, List, NamedTuple, Optional, Set, Tuple, Type, Union
import archspec.cpu import archspec.cpu
@ -119,6 +120,17 @@ def __str__(self):
return f"{self._name_.lower()}" return f"{self._name_.lower()}"
@contextmanager
def spec_with_name(spec, name):
"""Context manager to temporarily set the name of a spec"""
old_name = spec.name
spec.name = name
try:
yield spec
finally:
spec.name = old_name
class RequirementKind(enum.Enum): class RequirementKind(enum.Enum):
"""Purpose / provenance of a requirement""" """Purpose / provenance of a requirement"""
@ -1323,34 +1335,39 @@ def condition(
Returns: Returns:
int: id of the condition created by this function int: id of the condition created by this function
""" """
named_cond = required_spec.copy() name = required_spec.name or name
named_cond.name = named_cond.name or name if not name:
if not named_cond.name: raise ValueError(f"Must provide a name for anonymous condition: '{required_spec}'")
raise ValueError(f"Must provide a name for anonymous condition: '{named_cond}'")
# Check if we can emit the requirements before updating the condition ID counter. with spec_with_name(required_spec, name):
# In this way, if a condition can't be emitted but the exception is handled in the caller,
# we won't emit partial facts.
condition_id = next(self._id_counter) # Check if we can emit the requirements before updating the condition ID counter.
self.gen.fact(fn.pkg_fact(named_cond.name, fn.condition(condition_id))) # In this way, if a condition can't be emitted but the exception is handled in the
self.gen.fact(fn.condition_reason(condition_id, msg)) # caller, we won't emit partial facts.
trigger_id = self._get_condition_id( condition_id = next(self._id_counter)
named_cond, cache=self._trigger_cache, body=True, transform=transform_required self.gen.fact(fn.pkg_fact(required_spec.name, fn.condition(condition_id)))
) self.gen.fact(fn.condition_reason(condition_id, msg))
self.gen.fact(fn.pkg_fact(named_cond.name, fn.condition_trigger(condition_id, trigger_id)))
trigger_id = self._get_condition_id(
required_spec, cache=self._trigger_cache, body=True, transform=transform_required
)
self.gen.fact(
fn.pkg_fact(required_spec.name, fn.condition_trigger(condition_id, trigger_id))
)
if not imposed_spec:
return condition_id
effect_id = self._get_condition_id(
imposed_spec, cache=self._effect_cache, body=False, transform=transform_imposed
)
self.gen.fact(
fn.pkg_fact(required_spec.name, fn.condition_effect(condition_id, effect_id))
)
if not imposed_spec:
return condition_id return condition_id
effect_id = self._get_condition_id(
imposed_spec, cache=self._effect_cache, body=False, transform=transform_imposed
)
self.gen.fact(fn.pkg_fact(named_cond.name, fn.condition_effect(condition_id, effect_id)))
return condition_id
def impose(self, condition_id, imposed_spec, node=True, name=None, body=False): def impose(self, condition_id, imposed_spec, node=True, name=None, body=False):
imposed_constraints = self.spec_clauses(imposed_spec, body=body, required_from=name) imposed_constraints = self.spec_clauses(imposed_spec, body=body, required_from=name)
for pred in imposed_constraints: for pred in imposed_constraints: