At least, if you tried to use it when passing an install_dir. Because
T.Sequence is horrible and we should never use it, and the annotations
are a lie that produces bugs.
So, fix the annotations on CustomTarget to never allow this to happen
again, and also fix the function too. Move some definitions elsewhere
inline to satisfy the linter.
Fixes#11157
There are two problems here: a typing problem, and an algorithm problem.
We expect it to always be passed to CustomTarget() as a list, but we ran
list() on it, which became horribly mangled if you violated the types
and passed a string instead. This caused weird*er* errors and didn't
even do anything. We want to do all validation in the interpreter,
anyway, and make the build level dumb.
Meanwhile we type it as accepting a T.Sequence, which technically
permits... a string, actually. This isn't intentional; the point of
using T.Sequence is out of a misguided idea that APIs are supposed to be
"technically correct" by allowing "anything that fulfills an interface",
which is a flawed concept because we aren't using interfaces here, and
also because "technically string fulfills the same interface as a list,
if we're talking sequences".
Basically:
- mypy is broken by design, because it typechecks "python", not "what we
wish python to be"
- we do not actually need to graciously permit passing tuples instead of
lists
As far as historic implementations of this logic go, we have formerly:
- originally, typeslistified anything
- switched to accepting list from the interpreter, redundantly ran list()
on the list we got, and mishandling API violations passing a string
(commit 11f9638035)
- switched to accepting anything, stringlistifying it if it was not
`None`, mishandling `[None]`, and invoking list(x) on a brand new list
from stringlistify (commit 157d438835)
- stopped stringlistify, just accept T.List[str | None] and re-cast to
list, violates typing because we use/handle plain None too
(commit a8521fef70)
- break typing by declaring we accept a simple string, which still
results in mishandling by converting 'foo' -> ['f', 'o', 'o']
(commit ac576530c4)
All of this. ALL of it. Is because we tried to be fancy and say we
accept T.Tuple; the only version of this logic that has ever worked
correctly is the original untyped do-all-validation-in-the-build-phase
typeslistified version.
Let's just call it what it is. We want a list | None, and we handle it too.
`configure_file` is both an extremely complicated implementation, and
a strange place for copying. It's a bit of a historical artifact, since
the fs module didn't yet exist. It makes more sense to move this to the
fs module and deprecate this `configure_file` version.
This new version works at build time rather than configure time, which
has the disadvantage it can't be passed to `run_command`, but with the
advantage that changes to the input don't require a full reconfigure.
Instead of using FeatureNew/FeatureDeprecated in the module.
The goal here is to be able to handle information about modules in a
single place, instead of having to handle it separately. Each module
simply defines some metadata, and then the interpreter handles the rest.
These are only used for type checking, so don't bother importing them at
runtime.
Generally add future annotations at the same time, to make sure that
existing uses of these imports don't need to be quoted.
The only advantage they have is they have the interpreter in arguments,
but it's already available as self.interpreter. We should discourage
usage of the interpreter API and rely on ModuleState object instead in
the future.
This also lift the restriction that a module method cannot add build
targets, but that was not enforced for snippet methods anyway (and some
modules were doing it) and it's really loose restriction as it should
check for many other things if we wanted to make it consistent.
With this change File objects created with the builtin files() function
can be used with the fs submodule like normal strings.
All methods that seem reasonable support FileOrSting arguments.
For example fs.exists() still only takes str arguments because meson
already ensures that File objects do exist when creating them with files().
Each user facing function of the fs module has an additional FeatureNew
check when used with File objects.
The test cases for fs are extended appropriately with tests for File objects.
All changes were created by running
"pyupgrade --py3-only --keep-percent-format"
and committing the results. I have not touched string formatting for
now.
- use set literals
- simplify .format() parameter naming
- remove __future__
- remove default "r" mode for open()
- use OSError rather than compatibility aliases
- remove stray parentheses in function(generator) scopes
- ModuleState is now a real class that will have methods in the future
for actions modules needs, instead of using interpreter internal API.
- New ModuleObject base class, similar to InterpreterObject, that should
be used by all objects returned by modules. Its methods gets the
ModuleState passed as first argument. It has a `methods` dictionary to
define what is public API that can be called from build definition.
- Method return value is not required to be a ModuleReturnValue any
more, it can be any type that interpreter can holderify, including
ModuleObject.
- Legacy module API is maintained until we port all modules.
In the future modules should be updated:
- Use methods dict.
- Remove snippets.
- Custom objects returned by modules should all be subclass of
ModuleObject to get the state iface in their methods.
- Modules should never call into interpreter directly and instead state
object should have wrapper API.
- Stop using ModuleReturnValue in methods that just return simple
objects like strings. Possibly remove ModuleReturnValue completely
since all objects that needs to be processed by interpreter (e.g.
CustomTarget) should be created through ModuleState API.
Following #7890, this patch introduces the ability to read the contents
of a file to the fs module.
This patch introduces the ability to read files at configure time, but
has some restrictions:
- binary files are not supported (I don't think this will prove a
problem, and if people are wanting to do something with binary
files, they should probably be shelling out to their own script).
- Only files outside the build directory allowed. This limitation
should prevent build loops.
Given that reading an arbitrary file at configure time can affect the
configuration in almost arbitrary ways, meson should force a reconfigure
when the given file changes. This is non-configurable, but this can
easily be changed with a future keyword argument.
D lang compilers have an option -release (or similar) which turns off
asserts, contracts, and other runtime type checking. This patch wires
that up to the b_ndebug flag.
Fixes#7082
is_samepath better reflects the nature of this function--that files
and directories can be compared.
Also, instead of raising exceptions, simply return False when one
or both .is_samepath(path1, path1) don't exist. This is more
intuitive behavior and avoids having an extra if fs.exist() to go
with every fs.is_samepath()