bfflearn 0.4.0__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bfflearn-0.4.2/CHANGELOG.md +32 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/CITATION.cff +2 -2
- {bfflearn-0.4.0/bfflearn.egg-info → bfflearn-0.4.2}/PKG-INFO +1 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/__init__.py +1 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/learning.py +37 -10
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/utils.py +5 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/logs.py +5 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/plotting.py +397 -105
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/rdf.py +30 -38
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/_shared/campaign.py +18 -15
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/learn/config.py +82 -2
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/learn/main.py +79 -13
- {bfflearn-0.4.0 → bfflearn-0.4.2/bfflearn.egg-info}/PKG-INFO +1 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bfflearn.egg-info/SOURCES.txt +1 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/changelog.md +21 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/fit-lgp.md +8 -0
- bfflearn-0.4.2/docs/configuration/learn.md +87 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/validate.md +2 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/pyproject.toml +1 -1
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_learning_problem.py +30 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_utils.py +10 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/io/test_logs.py +53 -2
- bfflearn-0.4.2/tests/qoi/test_rdf.py +184 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/test_examples.py +12 -0
- bfflearn-0.4.2/tests/test_plotting.py +392 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/test_release_metadata.py +2 -2
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_configs.py +40 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_regressions.py +70 -2
- bfflearn-0.4.0/CHANGELOG.md +0 -183
- bfflearn-0.4.0/docs/configuration/learn.md +0 -54
- bfflearn-0.4.0/tests/test_plotting.py +0 -166
- {bfflearn-0.4.0 → bfflearn-0.4.2}/AGENTS.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/CONTRIBUTING.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/LICENSE +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/MANIFEST.in +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/README.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/SECURITY.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/SUPPORT.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/effective_observations.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/gaussian_process.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/kernels.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/likelihoods.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/means.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/posterior.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/priors.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/bayes/results.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/cli.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/bias.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/campaign.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/sample.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/specs.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/domain/systems.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/colvars.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/commands.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/cp2k.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/extxyz.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/mdp.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/plumed.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/progress.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/schedulers.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/io/utils.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/mcmc/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/mcmc/convergence.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/mcmc/proposal.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/mcmc/sampler.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/analysis.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/data.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/hbonds.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/qoi/routines.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/tools.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/topology.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/_shared/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/_shared/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/_shared/preparation.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/_shared/scheduler.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build_qoi_datasets/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build_qoi_datasets/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/build_qoi_datasets/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/examples.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/fit_lgp/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/fit_lgp/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/fit_lgp/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/label_snapshots/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/label_snapshots/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/label_snapshots/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/learn/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/md/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/md/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/md/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/sample_parameters/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/sample_parameters/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/sample_parameters/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/validate/__init__.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/validate/config.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bff/workflows/validate/main.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bfflearn.egg-info/dependency_links.txt +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bfflearn.egg-info/entry_points.txt +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bfflearn.egg-info/requires.txt +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/bfflearn.egg-info/top_level.txt +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/architecture.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/assets/bff-logo.pdf +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/assets/bff-logo.svg +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/cli.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/build-qoi-datasets.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/build.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/label-snapshots.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/configuration/sample-parameters.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/development.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/examples/acetate.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/examples/arbitrary-data.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/examples/index.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/examples/neon-mie-lgpmd.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/index.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/installation.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/docs/migration.md +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/mkdocs.yml +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/setup.cfg +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_effective_observations.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_gaussian_process.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_likelihoods.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_priors_posterior.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/bayes/test_results.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/domain/test_specs.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/io/_fake_mdanalysis.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/io/test_cp2k.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/io/test_cp2k_collect.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/io/test_mdp.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/mcmc/test_convergence.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/mcmc/test_proposal.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/mcmc/test_sampler.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/qoi/test_analysis.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/qoi/test_data.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/test_topology.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_charge_constraints.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_pipeline_manifests.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_preparation.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_scheduler.py +0 -0
- {bfflearn-0.4.0 → bfflearn-0.4.2}/tests/workflows/test_validate.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## `0.4.2` - 2026-10-02
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
|
|
5
|
+
- Bounded the posterior sample counts used for default corner, standard
|
|
6
|
+
marginal, and QoI marginal plots. The standard marginal cap accepts `-1` or
|
|
7
|
+
`null` to use every sample. QoI likelihood attribution now runs in adaptive
|
|
8
|
+
batches to avoid CUDA memory exhaustion after learning.
|
|
9
|
+
- Centered default LGP hyperparameter priors on the observed input and residual
|
|
10
|
+
target scales, avoiding noise-dominated fits for scalar QoIs whose natural
|
|
11
|
+
parameter or output scales differ substantially from one.
|
|
12
|
+
- Reported the mode of each posterior marginal instead of its mean, limited
|
|
13
|
+
charge modes to three decimal places, and formatted other parameter modes
|
|
14
|
+
with three significant digits.
|
|
15
|
+
- Balanced marginal plots across rows of at most five parameters, placed each
|
|
16
|
+
arbitrary `define` parameter on an independent axis, and added configurable
|
|
17
|
+
axis labels through `plots.plot_metadata`. Marginal figures now reserve
|
|
18
|
+
measured space for legends so they cannot overlap single- or multi-panel
|
|
19
|
+
plots, align y-axis labels within subplot columns, and leave sufficient
|
|
20
|
+
gutters between neighboring panel sections.
|
|
21
|
+
- Made local validation progress visible immediately, including campaigns with
|
|
22
|
+
a single sample, and advanced the displayed count only after each MD job has
|
|
23
|
+
completed.
|
|
24
|
+
|
|
25
|
+
## `0.4.1` - 2026-08-25
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Simplified RDF calculation so selection handling and atom-type expansion
|
|
30
|
+
occur in the QoI adapter while the numerical kernel operates directly on
|
|
31
|
+
MDAnalysis AtomGroups. Dynamic selections and numerical behavior are
|
|
32
|
+
preserved.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
message: "If you use BFF, please cite the repository and the associated paper."
|
|
3
3
|
title: "Bayesic Force Fields"
|
|
4
|
-
version: "0.4.
|
|
5
|
-
date-released: "2026-
|
|
4
|
+
version: "0.4.2"
|
|
5
|
+
date-released: "2026-10-02"
|
|
6
6
|
authors:
|
|
7
7
|
- family-names: Kostal
|
|
8
8
|
given-names: Vojtech
|
|
@@ -369,6 +369,42 @@ def _default_checkpoint_path(fn_posterior: Path) -> Path:
|
|
|
369
369
|
return fn_posterior.with_name(f"{stem}.ckpt{suffix}")
|
|
370
370
|
|
|
371
371
|
|
|
372
|
+
def _default_lgp_hyperpriors(
|
|
373
|
+
X: torch.Tensor,
|
|
374
|
+
residuals: torch.Tensor,
|
|
375
|
+
) -> Priors:
|
|
376
|
+
"""Build scale-aware priors for log GP hyperparameters."""
|
|
377
|
+
input_scales = X.std(dim=0, unbiased=False)
|
|
378
|
+
input_scales = torch.where(
|
|
379
|
+
torch.isfinite(input_scales) & (input_scales > 0),
|
|
380
|
+
input_scales,
|
|
381
|
+
torch.ones_like(input_scales),
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
target_scale = residuals.std(unbiased=False)
|
|
385
|
+
if not torch.isfinite(target_scale) or target_scale <= 0:
|
|
386
|
+
target_scale = torch.sqrt(torch.mean(residuals.square()))
|
|
387
|
+
if not torch.isfinite(target_scale) or target_scale <= 0:
|
|
388
|
+
target_scale = torch.ones((), dtype=residuals.dtype)
|
|
389
|
+
|
|
390
|
+
# LocalGaussianProcess adds ``sigma`` directly to the covariance diagonal,
|
|
391
|
+
# so its natural scale is a fraction of the target variance.
|
|
392
|
+
noise_scale = 0.1 * target_scale.square()
|
|
393
|
+
tiny = torch.finfo(noise_scale.dtype).tiny
|
|
394
|
+
noise_scale = torch.clamp(noise_scale, min=tiny)
|
|
395
|
+
|
|
396
|
+
return Priors(
|
|
397
|
+
[
|
|
398
|
+
Prior("normal", float(torch.log(scale)), 2.0, name=f"length_{i}")
|
|
399
|
+
for i, scale in enumerate(input_scales)
|
|
400
|
+
]
|
|
401
|
+
+ [
|
|
402
|
+
Prior("normal", float(torch.log(target_scale)), 2.0, name="width"),
|
|
403
|
+
Prior("normal", float(torch.log(noise_scale)), 3.0, name="noise"),
|
|
404
|
+
]
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
|
|
372
408
|
def fit_lgp_committee(
|
|
373
409
|
X: torch.Tensor,
|
|
374
410
|
y: torch.Tensor,
|
|
@@ -400,16 +436,7 @@ def fit_lgp_committee(
|
|
|
400
436
|
|
|
401
437
|
n_params = X.shape[1]
|
|
402
438
|
if hyperpriors is None:
|
|
403
|
-
priors =
|
|
404
|
-
[
|
|
405
|
-
Prior("normal", -2.0, 2.0, name=f"length_{i}")
|
|
406
|
-
for i in range(n_params)
|
|
407
|
-
]
|
|
408
|
-
+ [
|
|
409
|
-
Prior("normal", -2.0, 2.0, name="width"),
|
|
410
|
-
Prior("normal", -2.0, 3.0, name="noise"),
|
|
411
|
-
]
|
|
412
|
-
)
|
|
439
|
+
priors = _default_lgp_hyperpriors(X_hyper, y_hyper - y_hyper_mean)
|
|
413
440
|
else:
|
|
414
441
|
priors = Priors.from_any(hyperpriors)
|
|
415
442
|
if len(priors) != n_params + 2:
|
|
@@ -215,6 +215,11 @@ def find_max_stable_lr(
|
|
|
215
215
|
else:
|
|
216
216
|
learning_rates = list(learning_rates)
|
|
217
217
|
lower, upper = param_bounds
|
|
218
|
+
# Log-scale hyperparameters can legitimately start outside the generic
|
|
219
|
+
# stability window when the underlying data are very small or very large.
|
|
220
|
+
# Preserve the explosion guard while always admitting the supplied start.
|
|
221
|
+
lower = min(lower, float(p0.min()) - 1.0)
|
|
222
|
+
upper = max(upper, float(p0.max()) + 1.0)
|
|
218
223
|
for lr in learning_rates:
|
|
219
224
|
x = p0.clone().detach().requires_grad_(True)
|
|
220
225
|
opt = torch.optim.SGD([x], lr=lr)
|
|
@@ -216,6 +216,7 @@ class Logger:
|
|
|
216
216
|
level: int = 1,
|
|
217
217
|
overwrite: bool = False,
|
|
218
218
|
style: str | tuple[str, ...] | None = None,
|
|
219
|
+
write_file: bool = True,
|
|
219
220
|
) -> None:
|
|
220
221
|
"""Write a pytest-style line with a status block right aligned."""
|
|
221
222
|
prefix = self._prefix(level)
|
|
@@ -223,7 +224,8 @@ class Logger:
|
|
|
223
224
|
plain_len = len(prefix) + len(message) + len(status)
|
|
224
225
|
spacing = " " * max(width - plain_len, 1)
|
|
225
226
|
line = f"{prefix}{message}{spacing}{status}"
|
|
226
|
-
|
|
227
|
+
if write_file:
|
|
228
|
+
self._write_file(line)
|
|
227
229
|
self._write_console(line, overwrite=overwrite, style=style)
|
|
228
230
|
|
|
229
231
|
def progress_status(
|
|
@@ -234,6 +236,7 @@ class Logger:
|
|
|
234
236
|
*,
|
|
235
237
|
level: int = 1,
|
|
236
238
|
overwrite: bool = False,
|
|
239
|
+
write_file: bool = True,
|
|
237
240
|
) -> None:
|
|
238
241
|
"""Write a pytest-style progress line with ``[ 42%]`` on the right."""
|
|
239
242
|
percent = 100 if total <= 0 else round(100 * current / total)
|
|
@@ -244,6 +247,7 @@ class Logger:
|
|
|
244
247
|
level=level,
|
|
245
248
|
overwrite=overwrite,
|
|
246
249
|
style="magenta",
|
|
250
|
+
write_file=write_file,
|
|
247
251
|
)
|
|
248
252
|
|
|
249
253
|
def result_summary(
|