The wildcard-bound base resolution added for #938 matches a wildcard source module against the analysis's registry of parsed scripts by path suffix and takes the first script that matches. When two scripts in one analysis end with the same relative path, a/utils/tf_utils.py and b/utils/tf_utils.py say (two source roots, or a vendored copy beside the original), which one's import bindings are consulted depends on the registry's hash iteration order. A class whose base is written through that wildcard binding could then inherit, or not, across runs of the same program with no input change, which reads as a flake and is a resolution ambiguity. Latent, not observed: every fixture in the repository has one wildcard source per analysis, and the condition needs two with the same relative path.
Where
PythonParser.wildcardBoundRoot (the parser module): for each module the file wildcard-imports, the dotted name is turned into a relative path and every registered script equal to it or ending in / plus it is a candidate, and the loop returns the first candidate that binds the root. The registry is a hash map keyed by script name, so candidate order is iteration order.
Why It Is Recorded Now Rather Than Fixed In The Change That Introduced It
The change's witness set proves the resolution does not depend on the order modules are parsed, with an arm that varies that order and a certificate that the arm can fail. This is a different order, the registry's iteration order, and the arm cannot see it because its fixture has one wildcard source. A general sentence such as "the result does not depend on order" would have covered both, and only the parse-order half is true. So the ambiguity is stated at the method and here, and the two orders are kept apart.
Remedies
The minimal one makes the choice deterministic without resolving the ambiguity: order the candidates (exact match first, then by path) so the same program gives the same answer every run, and log when more than one candidate binds the root. The complete one resolves the wildcard the way the module parser resolves the import itself, against the script the importer actually reaches (its own local-module resolution, path-relative to the importer), so a same-suffix script elsewhere in the analysis is never a candidate. Either should come with a fixture holding two scripts of one relative path under different roots, wildcard-imported from different importers, asserting each importer's class inherits from what its own source binds.
The wildcard-bound base resolution added for #938 matches a wildcard source module against the analysis's registry of parsed scripts by path suffix and takes the first script that matches. When two scripts in one analysis end with the same relative path,
a/utils/tf_utils.pyandb/utils/tf_utils.pysay (two source roots, or a vendored copy beside the original), which one's import bindings are consulted depends on the registry's hash iteration order. A class whose base is written through that wildcard binding could then inherit, or not, across runs of the same program with no input change, which reads as a flake and is a resolution ambiguity. Latent, not observed: every fixture in the repository has one wildcard source per analysis, and the condition needs two with the same relative path.Where
PythonParser.wildcardBoundRoot(the parser module): for each module the file wildcard-imports, the dotted name is turned into a relative path and every registered script equal to it or ending in/plus it is a candidate, and the loop returns the first candidate that binds the root. The registry is a hash map keyed by script name, so candidate order is iteration order.Why It Is Recorded Now Rather Than Fixed In The Change That Introduced It
The change's witness set proves the resolution does not depend on the order modules are parsed, with an arm that varies that order and a certificate that the arm can fail. This is a different order, the registry's iteration order, and the arm cannot see it because its fixture has one wildcard source. A general sentence such as "the result does not depend on order" would have covered both, and only the parse-order half is true. So the ambiguity is stated at the method and here, and the two orders are kept apart.
Remedies
The minimal one makes the choice deterministic without resolving the ambiguity: order the candidates (exact match first, then by path) so the same program gives the same answer every run, and log when more than one candidate binds the root. The complete one resolves the wildcard the way the module parser resolves the import itself, against the script the importer actually reaches (its own local-module resolution, path-relative to the importer), so a same-suffix script elsewhere in the analysis is never a candidate. Either should come with a fixture holding two scripts of one relative path under different roots, wildcard-imported from different importers, asserting each importer's class inherits from what its own source binds.