Use class count, not instance - #52
Conversation
|
Follow-up: from petsctools import OptionsManager
class A(OptionsManager): pass
class B(A): pass
print([cls({}, default_prefix="firedrake_").options_prefix
for cls in (A, B, A, B, OptionsManager, A)])This is not hypothetical for Firedrake, which uses So the option-inheritance hazard is weakened rather than removed: whether a solver built inside Naming the class outright keeps one counter for the whole hierarchy: options_prefix = f"{default_prefix}{OptionsManager.count}_"
OptionsManager.count += 1Happy to reopen #53, which does that and adds a uniqueness assertion to AI-assisted: found and checked with Claude Code. |
|
I guess the collision will go away when NLVS stops inheriting from OptionsManager |
|
You make a great point. We should be using |
* Revert "Use class count, not instance (#52)" This reverts commit 729712d. * Give each autogenerated options prefix a unique index `self.count += 1` reads the class attribute and rebinds the result onto the instance, so `OptionsManager.count` stayed at zero and every manager built without an explicit `options_prefix` was handed the same prefix, `{default_prefix}0_`. Sharing a prefix means sharing a namespace in the global options database. A manager built while another manager's options are inserted picks those options up as if they had been passed on the command line. In Firedrake this makes any solver constructed inside a solve inherit the outer solver's parameters: the mass solve behind `Mesh.cell_sizes`, for instance, runs with the outer `-pc_type mg` and then fails to coarsen a problem that has no hierarchy of its own. Increment the counter on `OptionsManager` itself, so that one counter serves the whole hierarchy. `type(self).count += 1` is not enough: `OptionsManager` is used as a mixin -- Firedrake has `NonlinearVariationalSolver` -> `LinearVariationalSolver` -> `LinearSolver`, and `LinearEigensolver` -- and it reads the inherited value but writes the incremented one onto the subclass, so each class walks a counter of its own and prefixes repeat across the hierarchy: firedrake_2_ handed to both a LinearVariationalSolver and a NonlinearVariationalSolver `test_options_prefix` builds two subclasses and the base class in turn and checks the prefixes are distinct, which fails on either spelling of the bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
No description provided.