Skip to content

Conversation

@bonzini
Copy link
Collaborator

@bonzini bonzini commented Nov 20, 2025

This cleans up OverrideProgram and OverrideExecutable, replacing them with a single class that is a sibling of ExternalProgram. The two classes are a mess and complicate type annotations noticeably; this change removes the complication and even removes the need for a type alias, because you can almost always just use Program instead of ExternalProgram | Executable | OverrideProgram.

Extracted from #15107, removing support for depends/depend_files (not yet supported by find_program()) and for the ill-fated local_program() function.

Fixes: #15080

Free the name for a class.

Signed-off-by: Paolo Bonzini <[email protected]>
@bonzini bonzini requested a review from jpakkane as a code owner November 20, 2025 12:59
@bonzini bonzini force-pushed the program-hierarchy branch 3 times, most recently from 7388a93 to 6ad6658 Compare November 20, 2025 14:10
@bonzini bonzini added the refactoring No behavior changes label Nov 20, 2025
bonzini and others added 15 commits November 21, 2025 09:16
Signed-off-by: Paolo Bonzini <[email protected]>
OverrideProgram is a subclass of ExternalProgram, so you do not need to
have both.

Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Add a separate object that is like OverrideExecutable but isn't duck-typing
with Program.

[Paolo: remove depends/depend_files, as they are not supported yet by
 find_program()]

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of BuildTarget, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach custom_target() and run_target() that it is okay to
receive any Program.

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of BuildTarget, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach configure_file() and run_command() that it is
okay to receive any Program.

If it is not runnable, Meson will test and complain.

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of Executable, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach test() and benchmark() that it is okay
to receive any Program.

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of Executable, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach generator() that it is okay to receive any Program.

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of Executable, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach find_program() that it is okay to return any
Program, and propagate the new type to all the users.

Signed-off-by: Paolo Bonzini <[email protected]>
override_find_program() until now returned an OverrideExecutable,
which is a kind of Executable, or an OverrideProgram, which is
a kind of ExternalProgram.  In preparation for making it return a
LocalProgram, teach add_*_script() that it is okay to receive any
Program.

Signed-off-by: Paolo Bonzini <[email protected]>
This is not needed anymore now that there is a proper
LocalProgram object that find_program() returns.

Signed-off-by: Paolo Bonzini <[email protected]>
This matches the Python class name, which shows up in errors, and is simpler.

Signed-off-by: Paolo Bonzini <[email protected]>
These are useful for the many cases of creating lists of commands that
are mixtures of strings and programs
class Generator(HoldableObject):
def __init__(self, env: Environment,
exe: T.Union['Executable', programs.ExternalProgram],
exe: T.Union[Executable, programs.Program, CustomTarget, CustomTargetIndex],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does adding CustomTarget and CustomTargetIndex to the union belong to this commit? I don't understand why it is necessary in the context of the commit.

return repr_str.format(self.__class__.__name__, self.exe)

def get_exe(self) -> T.Union['Executable', programs.ExternalProgram]:
def get_exe(self) -> T.Union[Executable, programs.ExternalProgram, CustomTarget, CustomTargetIndex]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring No behavior changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OverrideExecutable and build.find_overrides should be in Interpreter

4 participants