What is your suggestion?
When override=True is added to an existing direct self.requires(...), the requirement silently stops being a dependency of the package (it disappears from self.dependencies, no CMakeDeps config with include dirs is generated, etc.). This is the documented behavior, and force is the correct tool when the package is directly consumed — I understand the force vs override distinction.
The problem is purely ergonomic, and there are two complementary improvements:
- Warn on no-op / misused overrides (primary proposal)
Emit a warning at graph-resolution time when a require with override=True does not actually override any transitive node. This almost always means the author meant force=True. Today it fails silently: no warning, the package drops out of the graph, and the build breaks later, far from the cause.
- Consider a more explicit trait name (secondary, non-breaking)
The name override reads as "override the version of this dependency," whereas it actually means "this is not a dependency, only a transitive version constraint." The trait that distinguishes the two behaviors is really whether the dependency edge is kept:
force=True → keeps the edge, wins version conflicts.
override=True → no edge, version constraint only.
Without breaking existing recipes, a more self-documenting alias (e.g. override_transitive=True) for the current override behavior would make intent obvious at the call site and reduce the recurring force vs override confusion. override could stay as a kept alias.
Example:
# pkgB/conanfile.py — consumes headers from foo
def requirements(self):
self.requires("foo/1.0") # direct; foo headers used in pkgB code
# changing it to:
self.requires("foo/1.0", override=True) # foo silently drops out of the graph,
# no warning; build later fails on missing foo headers
Have you read the CONTRIBUTING guide?
What is your suggestion?
When override=True is added to an existing direct self.requires(...), the requirement silently stops being a dependency of the package (it disappears from self.dependencies, no CMakeDeps config with include dirs is generated, etc.). This is the documented behavior, and force is the correct tool when the package is directly consumed — I understand the force vs override distinction.
The problem is purely ergonomic, and there are two complementary improvements:
Emit a warning at graph-resolution time when a require with override=True does not actually override any transitive node. This almost always means the author meant force=True. Today it fails silently: no warning, the package drops out of the graph, and the build breaks later, far from the cause.
The name override reads as "override the version of this dependency," whereas it actually means "this is not a dependency, only a transitive version constraint." The trait that distinguishes the two behaviors is really whether the dependency edge is kept:
force=True → keeps the edge, wins version conflicts.
override=True → no edge, version constraint only.
Without breaking existing recipes, a more self-documenting alias (e.g. override_transitive=True) for the current override behavior would make intent obvious at the call site and reduce the recurring force vs override confusion. override could stay as a kept alias.
Example:
Have you read the CONTRIBUTING guide?