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

Have st.number_input warn user of mismatched type and format string #2604

Merged
merged 3 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 11 additions & 5 deletions lib/streamlit/elements/number_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def number_input(
format : str or None
A printf-style format string controlling how the interface should
display numbers. Output must be purely numeric. This does not impact
the return value. Valid formatters: %d %e %f %g %i
the return value. Valid formatters: %d %e %f %g %i %u
key : str
An optional string to use as the unique key for the widget.
If this is omitted, a key will be generated for the widget
Expand Down Expand Up @@ -91,14 +91,20 @@ def number_input(
if format is None:
format = "%d" if int_value else "%0.2f"

# Warn user if they format an int type as a float or vice versa.
if format in ["%d", "%u", "%i"] and float_value:
# Warn user to check if displaying float as int was really intended.
import streamlit as st

st.warning(
"Warning: NumberInput value below is float, but format {} displays as integer.".format(
format
)
"Warning: NumberInput value below has type float,"
vdonato marked this conversation as resolved.
Show resolved Hide resolved
" but format {} displays as integer.".format(format)
)
elif format[-1] == "f" and int_value:
import streamlit as st

st.warning(
"Warning: NumberInput value below has type int so is"
" displayed as int despite format string {}.".format(format)
)

if step is None:
Expand Down
23 changes: 22 additions & 1 deletion lib/tests/streamlit/number_input_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import streamlit as st
from streamlit.errors import StreamlitAPIException
from streamlit.js_number import JSNumber
from streamlit.proto.Alert_pb2 import Alert as AlertProto
from streamlit.proto.NumberInput_pb2 import NumberInput
from tests import testutil

Expand All @@ -35,7 +36,7 @@ def test_data_type(self):
st.number_input("Label", value=0.5)
c = self.get_delta_from_queue().new_element.number_input
self.assertEqual(NumberInput.FLOAT, c.data_type)

def test_min_value_zero_sets_default_value(self):
st.number_input("Label", 0, 10)
c = self.get_delta_from_queue().new_element.number_input
Expand Down Expand Up @@ -124,6 +125,26 @@ def test_accept_valid_formats(self):
c = self.get_delta_from_queue().new_element.number_input
self.assertEqual(c.format, "%" + char)

def test_warns_on_float_type_with_int_format(self):
vdonato marked this conversation as resolved.
Show resolved Hide resolved
st.number_input("the label", value=5.0, format="%d")

c = self.get_delta_from_queue(-2).new_element.alert
self.assertEqual(c.format, AlertProto.WARNING)
self.assertEqual(
c.body,
"Warning: NumberInput value below has type float, but format %d displays as integer.",
)

def test_warns_on_int_type_with_float_format(self):
st.number_input("the label", value=5, format="%0.2f")

c = self.get_delta_from_queue(-2).new_element.alert
self.assertEqual(c.format, AlertProto.WARNING)
self.assertEqual(
c.body,
"Warning: NumberInput value below has type int so is displayed as int despite format string %0.2f.",
)

def test_error_on_unsupported_formatters(self):
UNSUPPORTED = "pAn"
for char in UNSUPPORTED:
Expand Down