We have a lot of these. Some of them are harmless, if unidiomatic, such
as `if (condition)`, others are potentially dangerous `assert(...)`, as
`assert(condtion)` works as expected, but `assert(condition, message)`
will result in an assertion that never triggers, as what you're actually
asserting is `bool(tuple[2])`, which will always be true.
Because currently you can write something like:
```python
KwargInfo('capture', bool)
```
Which proclaims "this must be bool", but the default is then not valid.
Follow-up on commit 5a7b8d86d0
Sometimes, we find a parent meson.build which is also malformed, and we
shouldn't suggest that maybe the user meant to use that, if it isn't a
valid project() either. Do a rough and dirty check to see if the very
first line is a project() declaration, and if not, don't try to be
clever and suggest using it.
The "invalid source tree" error suffices here, since we're not
absolutely sure meson can be successfully run in that parent directory
and actually advising people about the wrong location is a lot more
confusing than just saying "please figure this out yourself, here is
what to look for".
Granted, we miss cases where project() comes after blank lines and/or
comments, but doing a full AST parse here is excessively overkill and
probably too painful to do, and we don't need to be *that* clever. So
let's be content with merely going above and beyond the call of duty.
Explicitly mention that the project definition is invalid, and clarify
that project is `project()` -- a function.
Also try to walk the directory tree upward, and if there are parent
meson.build files, just say this isn't the project root, and "maybe you
meant to run meson there instead?"
This won't catch calls to subdir('foo/bar') but we can't be perfect,
only better than before and catch the *majority* of such cases, and
hopefully it's a lot more clear if meson protests that the project is
"invalid, there is no project() function", where the user should look
for a potential solution.
Fixes#3426
This assert causes several type checkers (both mypy and pyright) to
force `obj` to be a base `HoldableObject` instead of the specialized
object. Since the check itself may still be valuable as we don't have
fully type annotation coverage it's simply been removed when type
checking to aid in type specialization.
Because of the convertor function we have no guarantee that what we're
getting is in fact a `Dict[str, TYPE_var]`, it might well be anything in
the values, so we need to do some casting and set the return type to
object. This works out fine in practice as our declared `TypeDict`
inputs in the actual function signatures will be used instead.
This commit introduces a new type of `HoldableObject`: The
`SecondLevelHolder`. The primary purpose of this class is
to handle cases where two (or more) `HoldableObject`s are
stored at the same time (with one default object). The
best (and currently only) example here is the `BothLibraries`
class.
As a side-effect from #8885 `find_program()` returns now `Executable`
objects when `meson.override_find_program` is called with an
executable target. To resolve this conflict the missing methods
from `ExternalProgram` are added to `BuildTarget`.
This allows checking specific values that are added or deprecated, which
we do a surprising amount of. This works with both containers and scalar
values