Skip to content

Allow and skip empty elements in Command construction#4632

Open
LecrisUT wants to merge 1 commit intoteemtee:mainfrom
LecrisUT:chore/skip-empty-command
Open

Allow and skip empty elements in Command construction#4632
LecrisUT wants to merge 1 commit intoteemtee:mainfrom
LecrisUT:chore/skip-empty-command

Conversation

@LecrisUT
Copy link
Contributor

@LecrisUT LecrisUT commented Mar 2, 2026

Technically a bug because if the first element is "" it will become " actual_command" which can have some tricky consequences

Pull Request Checklist

  • implement the feature

Signed-off-by: Cristian Le <git@lecris.dev>
@LecrisUT LecrisUT added status | blocking other work An important pull request, blocking other pull requests or issues ci | full test Pull request is ready for the full test execution review | trivial Very easy for review, even for beginners, so don't be afraid to have a look! :-) labels Mar 2, 2026
_CommandElement = str
#: A single element of raw command line in its ``list`` form.
RawCommandElement = Union[str, Path]
RawCommandElement = Union[str, Path, None]
Copy link
Contributor

Choose a reason for hiding this comment

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

I can see the issue with Command('ls', ''), but how would None get it? Is the relaxation of this type needed? What will be easier if we could let None travel through our code unchecked until dropped in Command? That seems risky.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well without this whenever we want to use this feature we would have to use an empty "" explicitly. None seems more explicit in that case as an element that will not be expanded.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, isn't None or "" appearing as command element the actual issue, i.e. something feeding Command with things that cannot function as command elements? Dropping it would make things work, but that really seems like silencing errors. If you ran into something like that, we should probably fix the callsite, and maybe raise a ValueError to catch future violations. Empty strings are sneaky bastards, we should root them out as soon as we spot them, if they travel through our calls, we are probably missing checks somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well this happens in constructs such as

if self.guest.facts.sudo_prefix:
command = Command(self.guest.facts.sudo_prefix) + self._base_command

which I think would be perfectly valid

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean prefectly valid to avoid the prior if check and use the whole thing

command = Command('bootc')
if self.guest.facts.sudo_prefix:
command = Command(self.guest.facts.sudo_prefix, 'bootc')

Becoming just

command = Command(self.guest.facts.sudo_prefix, 'bootc')

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. So dropping the test, and just constructing the command, relying on Command filtering out all invalid items?

I get the use case, but it really seems risky to me, because once this "negative" kind of items is allowed, sooner or later an unwanted and unexpected one would sneak in, without us noticing :/

If I had my way, I would root out empty strings completely, including the sudo_prefix, because the emptiness is often misused to track "undefined", "unset", or "unknown" kind of info. Maybe we could turn sudo_prefix into something friendlier to other kids... Not sure what though, I'd like to think about this first.

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean prefectly valid to avoid the prior if check and use the whole thing

command = Command('bootc')
if self.guest.facts.sudo_prefix:
command = Command(self.guest.facts.sudo_prefix, 'bootc')

Becoming just

command = Command(self.guest.facts.sudo_prefix, 'bootc')

Got it.

It might seem I'm needlessly paranoid... But I really dislike empty strings being silently dropped; with the history of people (mis)using empty strings, it's practically guaranteed the silence will harm us one day. So I'd like to find something we could verify. Maybe a type for strings that can be empty, and it does not bear any boolean-like meaning, who knows.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses an issue in Command construction where an initial empty string element would create a command with a leading space. This is resolved by filtering out any falsy elements, such as empty strings and None, during command initialization. The type hint for RawCommandElement has been updated to include None to align with this change.

Note: Security Review is unavailable for this PR.

@thrix thrix added this to planning Mar 4, 2026
@github-project-automation github-project-automation bot moved this to backlog in planning Mar 4, 2026
@thrix thrix moved this from backlog to implement in planning Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci | full test Pull request is ready for the full test execution review | trivial Very easy for review, even for beginners, so don't be afraid to have a look! :-) status | blocking other work An important pull request, blocking other pull requests or issues

Projects

Status: implement

Development

Successfully merging this pull request may close these issues.

2 participants