|
47 | 47 | from .config_utils import ( |
48 | 48 | getqualattr, |
49 | 49 | add_to_path, |
50 | | - TaggedValue, |
| 50 | + ConfigWrapper, |
51 | 51 | ObjectStore, |
52 | 52 | classproperty, |
53 | 53 | ) |
@@ -201,6 +201,10 @@ def __init__(self, pyobject: "ConfigMixin"): |
201 | 201 | self._tags: dict[str, tuple[Any, str]] = {} |
202 | 202 | self._initinfo = "" |
203 | 203 |
|
| 204 | + # Per-argument properties set by ConfigWrapper (e.g., "stop_tags") |
| 205 | + # Maps argument name -> set of property strings |
| 206 | + self._args_properties: dict[str, set[str]] = {} |
| 207 | + |
204 | 208 | self._taskoutput = None |
205 | 209 | """Task output (caches the value of a submit)""" |
206 | 210 |
|
@@ -402,6 +406,10 @@ def __init__(self): |
402 | 406 | # Store {name: (value, source)} for conflict detection |
403 | 407 | self.tags_with_source: dict[str, tuple[Any, str]] = {} |
404 | 408 |
|
| 409 | + def should_recurse_arg(self, config, arg_name: str) -> bool: |
| 410 | + props = config.__xpm__._args_properties.get(arg_name) |
| 411 | + return props is None or "stop_tags" not in props |
| 412 | + |
405 | 413 | def postprocess(self, stub, config: Config, values): |
406 | 414 | for name, (value, source) in config.__xpm__._tags.items(): |
407 | 415 | if name in self.tags_with_source: |
@@ -1606,14 +1614,12 @@ def __setattr__(self, name: str, value): |
1606 | 1614 | # Check if this is an XPM argument |
1607 | 1615 | xpmtype = self.__xpmtype__ |
1608 | 1616 | if name in xpmtype.arguments: |
1609 | | - # Handle TaggedValue: extract value and add tag |
1610 | | - if isinstance(value, TaggedValue): |
1611 | | - actual_value = value.value |
| 1617 | + # Handle ConfigWrapper (tag, stop_tags, etc.) |
| 1618 | + if isinstance(value, ConfigWrapper): |
1612 | 1619 | source = get_caller_location(skip_frames=1) |
1613 | | - xpm.addtag(name, actual_value, source=source) |
1614 | | - xpm.set(name, actual_value) |
1615 | | - else: |
1616 | | - xpm.set(name, value) |
| 1620 | + value.apply(xpm, name, source=source) |
| 1621 | + value = value.value |
| 1622 | + xpm.set(name, value) |
1617 | 1623 | return |
1618 | 1624 |
|
1619 | 1625 | # Check for deprecated replacement warning |
@@ -1671,11 +1677,10 @@ def __init__(self, **kwargs): |
1671 | 1677 | continue |
1672 | 1678 | raise ValueError("%s is not an argument for %s" % (name, xpmtype)) |
1673 | 1679 |
|
1674 | | - # Special case of a tagged value |
1675 | | - if isinstance(value, TaggedValue): |
| 1680 | + # Handle ConfigWrapper (tag, stop_tags, etc.) |
| 1681 | + if isinstance(value, ConfigWrapper): |
| 1682 | + value.apply(xpm, name, source=xpm._initinfo) |
1676 | 1683 | value = value.value |
1677 | | - # Use _initinfo as source since tag is set at config creation |
1678 | | - self.__xpm__.addtag(name, value, source=xpm._initinfo) |
1679 | 1684 |
|
1680 | 1685 | # Really set the value |
1681 | 1686 | xpm.set(name, value) |
|
0 commit comments