Repository: streamlit/streamlit

Issue:
Add a config option to disable warning for setting both a widget default and its key in session_state
We currently print a warning as shown below when a user sets both a widget default value in the function defining the widget as well as a widget value via the widget's key in `st.session_state`

![warning screenshot](https://raw.githubusercontent.com/streamlit/docs/main/public/images/state_value_api_exception.png)

While we certainly want to do this by default since doing both is not recommended, we should provide a config option allowing users to disable the warning in case there's a good reason a user might want to do this.

---

Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.

**If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.**


Discussion:
@vdonato would you be able to re-upload the warning screenshot? I think the link expired or is not available anymore.

Also, can you provide a reproducible example?
@HenryRocha -- sure, I've updated the link to the warning screenshot so that it's working again. It seems to have broken when we rolled out a new docs website and deprecated the old one.

As for a reproducible example, the following small snippet of code should do the trick:
```python
import streamlit as st

st.session_state.my_checkbox = False
st.checkbox("checkbox", value=True, key="my_checkbox")
```

Note that the warning only appears a single time we detect that the user has done this, so after the first time it's displayed, you'll need to restart your streamlit server to get it to be printed again. 
I think I'd be able to handle this, are you still looking for a PR on it? @vdonato is this still confirmed / worth working on?
any news on this feature?
I would like to take this issue if it is still open, any news on this?
Any news on this feature?
I also would need this feature
@vdonato, is this feature still relevant? If it is, I'd like to try implementing this one
@antonAce for me it is. Thanks a lot

Resolving patch:
diff --git a/lib/streamlit/config.py b/lib/streamlit/config.py
--- a/lib/streamlit/config.py
+++ b/lib/streamlit/config.py
@@ -285,6 +285,20 @@ def _delete_option(key: str) -> None:
 )
 
 
+_create_option(
+    "global.disableWidgetStateDuplicationWarning",
+    description="""
+        By default, Streamlit displays a warning when a user sets both a widget
+        default value in the function defining the widget and a widget value via
+        the widget's key in `st.session_state`.
+
+        If you'd like to turn off this warning, set this to True.
+        """,
+    default_val=False,
+    type_=bool,
+)
+
+
 _create_option(
     "global.showWarningOnDirectExecution",
     description="""
diff --git a/lib/streamlit/elements/utils.py b/lib/streamlit/elements/utils.py
--- a/lib/streamlit/elements/utils.py
+++ b/lib/streamlit/elements/utils.py
@@ -15,7 +15,7 @@
 from typing import TYPE_CHECKING, Any, Hashable, Optional, Union, cast
 
 import streamlit
-from streamlit import runtime, type_util
+from streamlit import config, runtime, type_util
 from streamlit.elements.form import is_in_form
 from streamlit.errors import StreamlitAPIException
 from streamlit.proto.LabelVisibilityMessage_pb2 import LabelVisibilityMessage
@@ -69,7 +69,11 @@ def check_session_state_rules(
             "st.form cannot be set using st.session_state."
         )
 
-    if default_value is not None and not _shown_default_value_warning:
+    if (
+        default_value is not None
+        and not _shown_default_value_warning
+        and not config.get_option("global.disableWidgetStateDuplicationWarning")
+    ):
         streamlit.warning(
             f'The widget with key "{key}" was created with a default value but'
             " also had its value set via the Session State API."


Test patch:
diff --git a/lib/tests/streamlit/config_test.py b/lib/tests/streamlit/config_test.py
--- a/lib/tests/streamlit/config_test.py
+++ b/lib/tests/streamlit/config_test.py
@@ -351,6 +351,7 @@ def test_config_option_keys(self):
                 "deprecation.showPyplotGlobalUse",
                 "global.developmentMode",
                 "global.disableWatchdogWarning",
+                "global.disableWidgetStateDuplicationWarning",
                 "global.logLevel",
                 "global.maxCachedMessageAge",
                 "global.minCachedMessageSize",
diff --git a/lib/tests/streamlit/elements/element_utils_test.py b/lib/tests/streamlit/elements/element_utils_test.py
--- a/lib/tests/streamlit/elements/element_utils_test.py
+++ b/lib/tests/streamlit/elements/element_utils_test.py
@@ -12,16 +12,40 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import copy
+import os
 import unittest
 from unittest.mock import MagicMock, patch
 
 import pytest
 
+from streamlit import config
 from streamlit.elements.utils import check_callback_rules, check_session_state_rules
 from streamlit.errors import StreamlitAPIException
 
+SECTION_DESCRIPTIONS = copy.deepcopy(config._section_descriptions)
+CONFIG_OPTIONS = copy.deepcopy(config._config_options)
+
 
 class ElementUtilsTest(unittest.TestCase):
+    def setUp(self):
+        self.patches = [
+            patch.object(
+                config, "_section_descriptions", new=copy.deepcopy(SECTION_DESCRIPTIONS)
+            ),
+            patch.object(config, "_config_options", new=copy.deepcopy(CONFIG_OPTIONS)),
+            patch.dict(os.environ),
+        ]
+
+        for p in self.patches:
+            p.start()
+
+    def tearDown(self):
+        for p in self.patches:
+            p.stop()
+
+        config._delete_option("_test.tomlTest")
+
     @patch("streamlit.elements.utils.is_in_form", MagicMock(return_value=False))
     @patch("streamlit.runtime.Runtime.exists", MagicMock(return_value=True))
     def test_check_callback_rules_not_in_form(self):
@@ -91,6 +115,22 @@ def test_check_session_state_rules_prints_warning(
         warning_msg = args[0]
         assert 'The widget with key "the key"' in warning_msg
 
+    @patch("streamlit.runtime.Runtime.exists", MagicMock(return_value=True))
+    @patch("streamlit.elements.utils.get_session_state")
+    @patch("streamlit.warning")
+    def test_check_session_state_rules_hide_warning_if_state_duplication_disabled(
+        self, patched_st_warning, patched_get_session_state
+    ):
+        config._set_option("global.disableWidgetStateDuplicationWarning", True, "test")
+
+        mock_session_state = MagicMock()
+        mock_session_state.is_new_state_value.return_value = True
+        patched_get_session_state.return_value = mock_session_state
+
+        check_session_state_rules(5, key="the key")
+
+        patched_st_warning.assert_not_called()
+
     @patch("streamlit.runtime.Runtime.exists", MagicMock(return_value=True))
     @patch("streamlit.elements.utils.get_session_state")
     def test_check_session_state_rules_writes_not_allowed(