Diff Coverage

Diff: origin/master...HEAD, staged and unstaged changes

Source File Diff Coverage (%) Missing Lines
hyper_parallel/auto_parallel/config_adapter/_strategy_output.py 100%  
hyper_parallel/components/losses/masked_ce.py 100%  
hyper_parallel/trainer/config/__init__.py 100%  
hyper_parallel/trainer/config/manager.py 25.0% 108-109,127,150,154,179-180,193,212
hyper_parallel/trainer/config/resolver.py 52.2% 214-218,224-228,258
hyper_parallel/trainer/config/target.py 66.7% 84
hyper_parallel/trainer/config/manager.py
104
105
106
107
108
109
110
111
112
113


def _suggestion(name: str, candidates: Iterable[str]) -> str:
    """Build a ``did you mean`` hint for an unknown configuration name."""
    matches = difflib.get_close_matches(name, candidates, n=1)
    return f"; did you mean {matches[0]!r}?" if matches else ""


def _replace_target_path(
    config: Target[Any],
123
124
125
126
127
128
129
130
131
        raise ConfigResolutionError(
            f"CLI.{full_path}: changing _target_ through an override is not supported"
        )

    signature = inspect.signature(config.callable)
    parameter = signature.parameters.get(name)
    has_var_kwargs = any(
        item.kind is inspect.Parameter.VAR_KEYWORD
        for item in signature.parameters.values()
146
147
148
149
150
151
152
153
154
155
156
157
158
        except AttributeError as exc:
            raise ConfigResolutionError(
                f"CLI.{full_path}: target argument is not configured"
            ) from exc
        return config.replace(**{name: _replace_path(child, parts[1:], value, path=full_path)})

    normalized = value
    if parameter is not None:
        annotation = _target_hints(config.callable, path=path).get(
            name,
            parameter.annotation,
        )
        if annotation not in (Any, object, inspect.Signature.empty):
175
176
177
178
179
180
181
182
183
184
        full_path = f"{path}.{name}" if path else name
        if name not in config:
            raise ConfigResolutionError(f"CLI.{path}: unknown mapping key {name!r}")
        if len(parts) == 1:
            return {**config, name: value}
        return {**config, name: _replace_path(config[name], parts[1:], value, path=full_path)}

    location = f"CLI.{path}" if path else "CLI"
    if not is_dataclass(config):
        raise ConfigResolutionError(
189
190
191
192
193
194
195
196
197
    name = parts[0]
    if name not in config_fields:
        target = getattr(config, "target", None)
        if isinstance(target, Target):
            return replace(config, target=_replace_target_path(target, parts, value, path=path))
        raise ConfigResolutionError(
            f"{location}: unknown field {name!r} on {type(config).__name__}"
            f"{_suggestion(name, config_fields)}"
        )
208
209
210
211
212
213
214
215
216
    if child is None:
        raise ConfigResolutionError(
            f"CLI.{full_path}: component was not selected by the YAML"
        )
    return replace(config, **{name: _replace_path(child, parts[1:], value, path=full_path)})


def _apply_typed_overrides(
    config: TrainerConfig,
hyper_parallel/trainer/config/resolver.py
210
211
212
213
214
215
216
217
218
219
220
221
222
    """Normalize a list, tuple, or mapping annotation."""

    if origin is list or annotation is list:
        return _normalize_list(value, args[0] if args else Any, path=path)
    if origin is tuple or annotation is tuple:
        return _normalize_tuple(value, args, path=path)
    if not isinstance(value, Mapping):
        raise _fail(path, f"expected mapping, got {type(value).__name__}")
    return dict(value)


def _coerce_class(value: object, annotation: object, *, path: str) -> object:
    """Normalize a value against a concrete class annotation."""
220
221
222
223
224
225
226
227
228
229
230
231

def _coerce_class(value: object, annotation: object, *, path: str) -> object:
    """Normalize a value against a concrete class annotation."""

    if not isinstance(annotation, type):
        raise _fail(path, f"unsupported type annotation {_type_name(annotation)}")
    if isinstance(value, annotation):
        return value
    raise _fail(
        path,
        f"expected {_type_name(annotation)}, got {type(value).__name__}",
    )
254
255
256
257
258
259
260
261
262
    if isinstance(annotation, type) and dataclasses.is_dataclass(annotation):
        # Nested dataclass items resolve from mappings in the same way as
        # top-level dataclass components.
        return _resolve_dataclass(value, annotation, path=path)
    return _coerce_class(value, annotation, path=path)


def _resolve_union(node: object, annotation: object, *, path: str) -> object:
    """Resolve one value against an Optional or general union."""
hyper_parallel/trainer/config/target.py
80
81
82
83
84
85
86
87
88

    @property
    def callable(self) -> Callable[..., _T]:
        """Return the wrapped callable, read-only, for callers outside this class."""
        return self._target_

    def build(self, **runtime_kwargs: Any) -> _T:
        """Invoke the target with configured and applicable runtime arguments."""
        signature = inspect.signature(self._target_)