Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow None as value for text widgets #7313

Merged
merged 21 commits into from
Sep 13, 2023

Conversation

LukasMasuch
Copy link
Collaborator

@LukasMasuch LukasMasuch commented Sep 12, 2023

Describe your changes

This PR adds support for setting None as the value in st.text_input and st.text_area. Using value=None will render an empty text input that returns None as long as the user hasn't provided an input. Once the user has typed into the text_input field, it will always return a string, even when empty (different to the None support of other widgets).

Testing Plan

  • Unit Tests: ✅
  • E2E Tests: ✅

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@LukasMasuch LukasMasuch marked this pull request as ready for review September 12, 2023 15:24
e2e_playwright/st_text_area_test.py Outdated Show resolved Hide resolved
e2e_playwright/st_text_area_test.py Show resolved Hide resolved
e2e_playwright/st_text_input_test.py Show resolved Hide resolved
e2e_playwright/st_text_input_test.py Outdated Show resolved Hide resolved
Comment on lines +74 to +95
@overload
def text_input(
self,
label: str,
value: SupportsStr = "",
max_chars: Optional[int] = None,
key: Optional[Key] = None,
value: str = "",
max_chars: int | None = None,
key: Key | None = None,
type: Literal["default", "password"] = "default",
help: Optional[str] = None,
autocomplete: Optional[str] = None,
on_change: Optional[WidgetCallback] = None,
args: Optional[WidgetArgs] = None,
kwargs: Optional[WidgetKwargs] = None,
help: str | None = None,
autocomplete: str | None = None,
on_change: WidgetCallback | None = None,
args: WidgetArgs | None = None,
kwargs: WidgetKwargs | None = None,
*, # keyword-only arguments:
placeholder: Optional[str] = None,
placeholder: str | None = None,
disabled: bool = False,
label_visibility: LabelVisibility = "visible",
) -> str:
pass

@overload
def text_input(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm, would it make more sense for the first @overload for this widget to take a value with type SupportsStr and return a str, then the second @overload is where value has type None and returns None (it might be necessary to make the None case the first overload in the list in case order is important)

I think this should be equivalent but a bit more clear

(same comment for text_area below)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That was my initial try as well, but it's giving me a mypy error:

Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader  [misc]

and if I change the order:

Overloaded function signatures 1 and 2 overlap with incompatible return types

The main issue seems to be with the SupportsStr protocol since this also includes None and it requires non-overlapping types here :( With the workaround by adding str explicitly, I can at least provide optimized typing for all uses with a normal string (which are most uses anyways).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I played around today a bit more with the overloads but didn't really find a way to get it to work other than the current workaround :(

lib/streamlit/elements/widgets/text_widgets.py Outdated Show resolved Hide resolved
@LukasMasuch LukasMasuch merged commit d93baa6 into develop Sep 13, 2023
87 checks passed
eric-skydio pushed a commit to eric-skydio/streamlit that referenced this pull request Dec 20, 2023
* Initial commit

* Implement none support for text input and area

* docstring change

* Update unit tests

* Finish unit tests

* Remove outdated widgets

* Update snapshots

* Update snapshots

* Add playwright script

* Change test id

* Add playwright e2e test

* Add text area test

* Fix e2e test

* Update snapshots

* Skip test in firefox

* Fix e2e test

* Update tests based on review comments

* Explicitly type None

* Use v for return value

* Rename return values to v
zyxue pushed a commit to zyxue/streamlit that referenced this pull request Mar 22, 2024
* Initial commit

* Implement none support for text input and area

* docstring change

* Update unit tests

* Finish unit tests

* Remove outdated widgets

* Update snapshots

* Update snapshots

* Add playwright script

* Change test id

* Add playwright e2e test

* Add text area test

* Fix e2e test

* Update snapshots

* Skip test in firefox

* Fix e2e test

* Update tests based on review comments

* Explicitly type None

* Use v for return value

* Rename return values to v
zyxue pushed a commit to zyxue/streamlit that referenced this pull request Apr 16, 2024
* Initial commit

* Implement none support for text input and area

* docstring change

* Update unit tests

* Finish unit tests

* Remove outdated widgets

* Update snapshots

* Update snapshots

* Add playwright script

* Change test id

* Add playwright e2e test

* Add text area test

* Fix e2e test

* Update snapshots

* Skip test in firefox

* Fix e2e test

* Update tests based on review comments

* Explicitly type None

* Use v for return value

* Rename return values to v
@LukasMasuch LukasMasuch deleted the feature/allow-none-for-text-widgets branch May 27, 2024 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants