cool-easter-32542
08/05/2024, 1:27 AM1 fails to start, with a hard "Exception: Expected ... to be a float but given 1" error, and this isn't handled gracefully.
The workaround is either:
• fix the specific problem (e.g. add .0, like 1.0)
• set [GLOBAL].native_options_validation = "ignore"
However, this is a hard-break that makes upgrading harder.
This may be related to the Rust parser, which has code that tries to paper over the difference:
pants/src/rust/engine/options/src/lib.rs
Lines 148 to 156 in</pantsbuild/pants/commit/a2acb196216ce5cabe45ee6a039eb5d5f530777a|a2acb19>
| if let Some(value) = self.get_string(id)? { |
| ---------------------------------------------------------- |
| let parsed_as_float = f64::parse(&value) |
| .map(Some) |
| .map_err(\|e| e.render(self.display(id))); |
| if parsed_as_float.is_err() { |
| // See if we can parse as an int and coerce it to a float. |
| if let Ok(i) = i64::parse(&value) { |
| return Ok(Some(i as f64)); |
| } |
We are also theoretically just running the Rust parser in parallel, and use [GLOBAL].native_options_validation (https://www.pantsbuild.org/2.22/reference/global-options#native_options_validation) to control whether something is an error or not, but that's not applying in this case: setting it to warning doesn't downgrade the error.
Reproducer:
cd $(mktemp -d)
cat > pants.toml <<EOF
[GLOBAL]
pants_version = "2.22.0.dev2"
pantsd_timeout_when_multiple_invocations = 1
EOF
# OK: prints the version
PANTS_VERSION=2.22.0.dev1 pants version
# BUG: Exception: Expected [GLOBAL] pantsd_timeout_when_multiple_invocations to be a float but given 1
pants --print-stacktrace version
# BUG: still exception, not warning
pants --native-options-validation=warning version
Stacktrace output of the first `BUG`:
11:16:40.86 [ERROR] 1 Exception encountered:
Engine traceback:
in root
..
in pants.core.util_rules.environments.determine_local_environment
..
in pants.core.util_rules.environments.determine_all_environments
..
in construct_scope_environments_preview
..
Traceback (most recent call last):
File ".../pants/option/subsystem.py", line 319, in _construct_subsystem
scoped_options = await Get(ScopedOptions, Scope(str(subsystem_typ.options_scope)))
File ".../pants/engine/internals/selectors.py", line 124, in __await__
result = yield self
File ".../pants/engine/internals/options_parsing.py", line 49, in parse_options
return _Options(options_bootstrapper, build_config, union_membership)
File "<string>", line 6, in __init__
File ".../pants/engine/internals/options_parsing.py", line 33, in __post_init__
assert self.options is not None
File ".../pants/util/memo.py", line 123, in memoize
result = func(*args, **kwargs)
File ".../pants/engine/internals/options_parsing.py", line 37, in options
return self.options_bootstrapper.full_options(self.build_config, self.union_membership)
File ".../pants/option/options_bootstrapper.py", line 310, in full_options
GlobalOptions.validate_instance(options.for_global_scope())
File ".../pants/option/options.py", line 529, in for_global_scope
return self.for_scope(GLOBAL_SCOPE)
File ".../pants/util/memo.py", line 123, in memoize
result = func(*args, **kwargs)
File ".../pants/option/options.py", line 396, in for_scope
native_values = self.get_parser(scope).parse_args_native(self._native_parser)
File ".../pants/option/parser.py", line 202, in parse_args_native
val, rank = native_parser.get(
File ".../pants/option/native_options.py", line 124, in get
val, rank_int = getter(option_id, default) # type:ignore
Exception: Expected [GLOBAL] pantsd_timeout_when_multiple_invocations to be a float but given 1
Traceback (most recent call last):
File ".../pants/bin/daemon_pants_runner.py", line 133, in single_daemonized_run
scheduler, options_initializer = self._core.prepare(options_bootstrapper, complete_env)
File ".../pants/pantsd/pants_daemon_core.py", line 128, in prepare
build_config = self._options_initializer.build_config(options_bootstrapper, env)
File ".../pants/init/options_initializer.py", line 154, in build_config
return _initialize_build_configuration(self._plugin_resolver, options_bootstrapper, env)
File ".../pants/init/options_initializer.py", line 59, in _initialize_build_configuration
working_set = plugin_resolver.resolve(options_bootstrapper, env, backends_requirements)
File ".../pants/init/plugin_resolver.py", line 141, in resolve
for resolved_plugin_location in self._resolve_plugins(options_bootstrapper, env, request):
File ".../pants/init/plugin_resolver.py", line 163, in _resolve_plugins
params = Params(request, determine_bootstrap_environment(session))
File ".../pants/core/util_rules/environments.py", line 456, in determine_bootstrap_environment
session.product_request(ChosenLocalEnvironmentName, [Params()])[0],
File ".../pants/engine/internals/scheduler.py", line 585, in product_request
return self.execute(request)
File ".../pants/engine/internals/scheduler.py", line 526, in execute
self._raise_on_error([t for _, t in throws])
File ".../pants/engine/internals/scheduler.py", line 510, in _raise_on_error
raise ExecutionError(
pants.engine.internals.scheduler.ExecutionError: 1 Exception encountered:
Engine traceback:
in root
..
in pants.core.util_rules.environments.determine_local_environment
..
in pants.core.util_rules.environments.determine_all_environments
..
in construct_scope_environments_preview
..
Traceback (most recent call last):
File ".../pants/option/subsystem.py", line 319, in _construct_subsystem
scoped_options = await Get(ScopedOptions, Scope(str(subsystem_typ.options_scope)))
File ".../pants/engine/internals/selectors.py", line 124, in __await__
result = yield self
File ".../pants/engine/internals/options_parsing.py", line 49, in parse_options
return _Options(options_bootstrapper, build_config, union_membership)
File "<string>", line 6, in __init__
File ".../pants/engine/internals/options_parsing.py", line 33, in __post_init__
assert self.options is not None
File ".../pants/util/memo.py", line 123, in memoize
result = func(*args, **kwargs)
File ".../pants/engine/internals/options_parsing.py", line 37, in options
return self.options_bootstrapper.full_options(self.build_config, self.union_membership)
File ".../pants/option/options_bootstrapper.py", line 310, in full_options
GlobalOptions.validate_instance(options.for_global_scope())
File ".../pants/option/options.py", line 529, in for_global_scope
return self.for_scope(GLOBAL_SCOPE)
File ".../pants/util/memo.py", line 123, in memoize
result = func(*args, **kwargs)
File ".../pants/option/options.py", line 396, in for_scope
native_values = self.get_parser(scope).parse_args_native(self._native_parser)
File ".../pants/option/parser.py", line 202, in parse_args_native
val, rank = native_parser.get(
File ".../pants/option/native_options.py", line 124, in get
val, rank_int = getter(option_id, default) # type:ignore
Exception: Expected [GLOBAL] pantsd_timeout_when_multiple_invocations to be a float but given 1
Pants version
2.22.0.dev2, 2.22.0rc2, 2.23.0.dev5
OS
macOS
Additional info
Comparison: <https://github.com/pantsbuild/pants/compare/release_2.22.0.dev1...release_2.22.0.dev2|relea…
pantsbuild/pantscool-easter-32542
08/05/2024, 8:36 PMcool-easter-32542
08/05/2024, 8:36 PM