Skip to content

Honour the valid_empty flag even when Input has no validators.#5882

Closed
holdenweb wants to merge 2 commits into
Textualize:mainfrom
holdenweb:main
Closed

Honour the valid_empty flag even when Input has no validators.#5882
holdenweb wants to merge 2 commits into
Textualize:mainfrom
holdenweb:main

Conversation

@holdenweb

Copy link
Copy Markdown
Contributor

Please review the following checklist.

  • [x ] Docstrings on all new or modified functions / classes
  • [n/a?] Updated documentation
  • [n/a?] Updated CHANGELOG.md (where appropriate)

Discussed this in Discord.
This patch ensures that even without validators an empty input with valid_empty set to False will be rejected.

@holdenweb holdenweb changed the title Honour the valid_empty flag even when Input has no validators. Honour the valid_empty flag even when Input has no validators. [WIP] Jun 24, 2025
@holdenweb

holdenweb commented Jun 24, 2025

Copy link
Copy Markdown
Contributor Author

The logic of the present Input.validate begins as follows:

If the field has an empty validator set, the assumption appears to be that valid_empty need not be consulted, so the method returnsNone. It is unclear to me why this condition needed to be special cased.

It is also unclear why, under these circumstances, an empty value with valid_empty == False, which the next step checks for, would not be considered a failure.

The test_invalid_empty this PR adds checks that a valid_empty Input with no value indeed renders as invalid. It creates an Input with valid_empty=True and a single character value, rendering it valid, which is then backspaced, leaving it with the allegedly (?) invalid empty value. At present this test fails, passing the Input as valid.

Reversing the sequence in which the initial steps of validation are applied still passes all current tests, would appear to be backwards compatible, and ensures that the valid_empty value is correctly honoured for inputs with no validators.

Formerly an Input with `valid_empty=True` and no validators
would validate successfully even with an empty value.
@holdenweb holdenweb changed the title Honour the valid_empty flag even when Input has no validators. [WIP] Honour the valid_empty flag even when Input has no validators. Jun 24, 2025
def compose(self) -> ComposeResult:
yield Input(valid_empty=False, value="x")

async def test_invalid_empty():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You'll need an async with here.

self._reactive_valid_empty = valid_empty
self._valid = True

self._valid = not (input and not valid_empty)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find the negation requires a bit of mental parsing. Maybe self._valid = valid_empty and not input ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

More importantly, I presume you meant value rather than input here?

@holdenweb holdenweb Jun 24, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I take your point. However, I feel we really should use an equivalent expression :)

>>> for valid_empty in (True, False):
...   for input in (True, False):
...     print(f"{valid_empty=} {input=} {(not (input and not valid_empty), valid_empty and not input)}")
...
valid_empty=True input=True (True, False)
valid_empty=True input=False (True, True)
valid_empty=False input=True (False, False)
valid_empty=False input=False (True, False)

I'll use valid_empty or not input. de Morgan's law FTW!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Clearly this PR still needs a bit of work ...

@TomJGooding TomJGooding Jun 24, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry you've lost me. My point is that input is just an in-built Python function and has no relation to the Input in Textual.

@TomJGooding TomJGooding left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry if this has already been discussed over on Discord, but I don't understand this PR at all I'm afraid.

self._reactive_valid_empty = valid_empty
self._valid = True

self._valid = not (input and not valid_empty)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

More importantly, I presume you meant value rather than input here?

@holdenweb

Copy link
Copy Markdown
Contributor Author

I'm sorry I wasted your time with this PR, which as you have observed is completely mangled.
This is due to my persistence in working when ill, for which I can only apologise.

The actual fix required is simple, and will be the subject of a separate pull request coming shortly.

@holdenweb

Copy link
Copy Markdown
Contributor Author

No point going any further here.

@holdenweb holdenweb closed this Jun 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants