Browse Source

Use Python truthiness in pc.cond (#889)

Nikhil Rao 2 năm trước cách đây
mục cha
commit
e03e5f8033

+ 10 - 0
pynecone/.templates/web/utils/state.js

@@ -246,3 +246,13 @@ export const uploadFiles = async (
 export const E = (name, payload) => {
 export const E = (name, payload) => {
   return { name, payload };
   return { name, payload };
 };
 };
+
+
+/***
+ * Check if a value is truthy in python.
+ * @param val The value to check.
+ * @returns True if the value is truthy, false otherwise.
+ */
+export const isTrue = (val) => {
+    return Array.isArray(val) ? val.length > 0 : !!val
+}

+ 8 - 2
pynecone/compiler/compiler.py

@@ -16,7 +16,13 @@ from pynecone.utils import imports, path_ops
 DEFAULT_IMPORTS: imports.ImportDict = {
 DEFAULT_IMPORTS: imports.ImportDict = {
     "react": {"useEffect", "useRef", "useState"},
     "react": {"useEffect", "useRef", "useState"},
     "next/router": {"useRouter"},
     "next/router": {"useRouter"},
-    f"/{constants.STATE_PATH}": {"connect", "updateState", "uploadFiles", "E"},
+    f"/{constants.STATE_PATH}": {
+        "connect",
+        "updateState",
+        "uploadFiles",
+        "E",
+        "isTrue",
+    },
     "": {"focus-visible/dist/focus-visible"},
     "": {"focus-visible/dist/focus-visible"},
     "@chakra-ui/react": {constants.USE_COLOR_MODE},
     "@chakra-ui/react": {constants.USE_COLOR_MODE},
 }
 }
@@ -86,7 +92,7 @@ def _compile_components(components: Set[CustomComponent]) -> str:
     """
     """
     imports = {
     imports = {
         "react": {"memo"},
         "react": {"memo"},
-        f"/{constants.STATE_PATH}": {"E"},
+        f"/{constants.STATE_PATH}": {"E", "isTrue"},
     }
     }
     component_defs = []
     component_defs = []
 
 

+ 3 - 0
pynecone/utils/format.py

@@ -218,6 +218,9 @@ def format_cond(
     # Import here to avoid circular imports.
     # Import here to avoid circular imports.
     from pynecone.var import Var
     from pynecone.var import Var
 
 
+    # Use Python truthiness.
+    cond = f"isTrue({cond})"
+
     # Format prop conds.
     # Format prop conds.
     if is_prop:
     if is_prop:
         prop1 = Var.create(true_value, is_string=type(true_value) == str)
         prop1 = Var.create(true_value, is_string=type(true_value) == str)

+ 2 - 2
tests/components/layout/test_cond.py

@@ -40,7 +40,7 @@ def test_validate_cond(cond_state: pc.Var):
     )
     )
 
 
     assert str(cond_component) == (
     assert str(cond_component) == (
-        "<Fragment>{cond_state.value ? "
+        "<Fragment>{isTrue(cond_state.value) ? "
         "<Fragment><Text>{`cond is True`}</Text></Fragment> : "
         "<Fragment><Text>{`cond is True`}</Text></Fragment> : "
         "<Fragment><Text>{`cond is False`}</Text></Fragment>}</Fragment>"
         "<Fragment><Text>{`cond is False`}</Text></Fragment>}</Fragment>"
     )
     )
@@ -71,7 +71,7 @@ def test_prop_cond(c1: Any, c2: Any):
     assert isinstance(prop_cond, Var)
     assert isinstance(prop_cond, Var)
     c1 = json.dumps(c1).replace('"', "`")
     c1 = json.dumps(c1).replace('"', "`")
     c2 = json.dumps(c2).replace('"', "`")
     c2 = json.dumps(c2).replace('"', "`")
-    assert str(prop_cond) == f"{{true ? {c1} : {c2}}}"
+    assert str(prop_cond) == f"{{isTrue(true) ? {c1} : {c2}}}"
 
 
 
 
 def test_cond_no_else():
 def test_cond_no_else():

+ 4 - 1
tests/components/test_tag.py

@@ -163,4 +163,7 @@ def test_format_cond_tag():
         false_value=str(Tag(name="h2", contents="False content")),
         false_value=str(Tag(name="h2", contents="False content")),
         cond=BaseVar(name="logged_in", type_=bool),
         cond=BaseVar(name="logged_in", type_=bool),
     )
     )
-    assert str(tag) == "{logged_in ? <h1>True content</h1> : <h2>False content</h2>}"
+    assert (
+        str(tag)
+        == "{isTrue(logged_in) ? <h1>True content</h1> : <h2>False content</h2>}"
+    )

+ 2 - 2
tests/test_utils.py

@@ -163,8 +163,8 @@ def test_indent(text: str, indent_level: int, expected: str, windows_platform: b
 @pytest.mark.parametrize(
 @pytest.mark.parametrize(
     "condition,true_value,false_value,expected",
     "condition,true_value,false_value,expected",
     [
     [
-        ("cond", "<C1>", '""', '{cond ? <C1> : ""}'),
-        ("cond", "<C1>", "<C2>", "{cond ? <C1> : <C2>}"),
+        ("cond", "<C1>", '""', '{isTrue(cond) ? <C1> : ""}'),
+        ("cond", "<C1>", "<C2>", "{isTrue(cond) ? <C1> : <C2>}"),
     ],
     ],
 )
 )
 def test_format_cond(condition: str, true_value: str, false_value: str, expected: str):
 def test_format_cond(condition: str, true_value: str, false_value: str, expected: str):