Repository: narwhals-dev/narwhals
Pull request #1393 (2024-11-17 13:13:50)

chore: update `InvalidIntoExprError` to mention `nw.lit`
<!--
# Thanks for contributing a pull request! 
## Please make sure you see our contribution guidelines: https://github.com/narwhals-dev/narwhals/blob/main/CONTRIBUTING.md
-->

## What type of PR is this? (check all applicable)

- [ ] 💾 Refactor
- [ ] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔧 Optimization
- [ ] 📝 Documentation
- [ ] ✅ Test
- [ ] 🐳 Other

## Related issues

- Related comment https://github.com/narwhals-dev/narwhals/issues/1390#issuecomment-2481199944

## Checklist

- [ ] Code follows style guide (ruff)
- [ ] Tests added
- [ ] Documented the changes

## If you have comments or can explain your changes, please do so below



Patch:
diff --git a/docs/backcompat.md b/docs/backcompat.md
index 807d51ed..e44c38eb 100644
--- a/docs/backcompat.md
+++ b/docs/backcompat.md
@@ -134,7 +134,7 @@ before making any change.
     ```
 
     To check if a dtype is a datetime (regardless of `time_unit` or `time_zone`)
-    we recommend using `==` instead, as that works consistenty
+    we recommend using `==` instead, as that works consistently
     across namespaces:
 
     ```python exec="1" source="above" session="backcompat"
diff --git a/docs/pandas_like_concepts/boolean.md b/docs/pandas_like_concepts/boolean.md
index fe60904c..c1b434f5 100644
--- a/docs/pandas_like_concepts/boolean.md
+++ b/docs/pandas_like_concepts/boolean.md
@@ -6,32 +6,49 @@ For example, if you do `nw.col('a')*2`, then:
 - Values which were non-null get multiplied by 2.
 - Null values stay null.
 
-```python exec="1" source="above" session="boolean" result="python"
+```python exec="1" source="above" session="boolean"
 import narwhals as nw
-
-import pandas as pd
-import polars as pl
-import pyarrow as pa
+from narwhals.typing import FrameT
 
 data = {"a": [1.4, None, 4.2]}
-print("pandas output")
-print(nw.from_native(pd.DataFrame(data)).with_columns(b=nw.col("a") * 2).to_native())
-print("\nPolars output")
-print(nw.from_native(pl.DataFrame(data)).with_columns(b=nw.col("a") * 2).to_native())
-print("\nPyArrow output")
-print(nw.from_native(pa.table(data)).with_columns(b=nw.col("a") * 2).to_native())
+
+
+def multiplication(df: FrameT) -> FrameT:
+    return nw.from_native(df).with_columns((nw.col("a") * 2).alias("a*2")).to_native()
 ```
 
+=== "pandas"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import pandas as pd
+
+    df = pd.DataFrame(data)
+    print(multiplication(df))
+    ```
+
+=== "Polars (eager)"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import polars as pl
+
+    df = pl.DataFrame(data)
+    print(multiplication(df))
+    ```
+
+=== "PyArrow"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import pyarrow as pa
+
+    table = pa.table(data)
+    print(multiplication(table))
+    ```
+
 What do we do, however, when the result column is boolean? For
 example, `nw.col('a') > 0`?
 Unfortunately, this is backend-dependent:
 
 - for all backends except pandas, null values are preserved
 - for pandas, this depends on the dtype backend:
-    - for PyArrow dtypes and pandas nullable dtypes, null
-      values are preserved
-    - for the classic NumPy dtypes, null values are typically
-      filled in with `False`.
+    - for PyArrow dtypes and pandas nullable dtypes, null values are preserved
+    - for the classic NumPy dtypes, null values are typically filled in with `False`.
 
 pandas is generally moving towards nullable dtypes, and they
 [may become the default in the future](https://github.com/pandas-dev/pandas/pull/58988),
@@ -39,23 +56,31 @@ so we hope that the classical NumPy dtypes not supporting null values will just
 be a temporary legacy pandas issue which will eventually go
 away anyway.
 
-```python exec="1" source="above" session="boolean" result="python"
-print("pandas output")
-print(nw.from_native(pd.DataFrame(data)).with_columns(b=nw.col("a") > 2).to_native())
-print("\npandas (nullable dtypes) output")
-print(
-    nw.from_native(pd.DataFrame(data, dtype="Float64"))
-    .with_columns(b=nw.col("a") > 2)
-    .to_native()
-)
-print("\npandas (pyarrow dtypes) output")
-print(
-    nw.from_native(pd.DataFrame(data, dtype="Float64[pyarrow]"))
-    .with_columns(b=nw.col("a") > 2)
-    .to_native()
-)
-print("\nPolars output")
-print(nw.from_native(pl.DataFrame(data)).with_columns(b=nw.col("a") > 2).to_native())
-print("\nPyArrow output")
-print(nw.from_native(pa.table(data)).with_columns(b=nw.col("a") > 2).to_native())
-```
\ No newline at end of file
+```python exec="1" source="above" session="boolean"
+def comparison(df: FrameT) -> FrameT:
+    return nw.from_native(df).with_columns((nw.col("a") > 2).alias("a>2")).to_native()
+```
+
+=== "pandas"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import pandas as pd
+
+    df = pd.DataFrame(data)
+    print(comparison(df))
+    ```
+
+=== "Polars (eager)"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import polars as pl
+
+    df = pl.DataFrame(data)
+    print(comparison(df))
+    ```
+
+=== "PyArrow"
+    ```python exec="true" source="material-block" result="python" session="boolean"
+    import pyarrow as pa
+
+    table = pa.table(data)
+    print(comparison(table))
+    ```
diff --git a/narwhals/exceptions.py b/narwhals/exceptions.py
index 6991ea75..26485dfc 100644
--- a/narwhals/exceptions.py
+++ b/narwhals/exceptions.py
@@ -50,8 +50,13 @@ class InvalidIntoExprError(TypeError):
     def from_invalid_type(cls, invalid_type: type) -> InvalidIntoExprError:
         message = (
             f"Expected an object which can be converted into an expression, got {invalid_type}\n\n"
-            "Hint: if you were trying to select a column which does not have a string column name, then "
-            "you should explicitly use `nw.col`.\nFor example, `df.select(nw.col(0))` if you have a column "
-            "named `0`."
+            "Hint:\n"
+            "- if you were trying to select a column which does not have a string\n"
+            "  column name, then you should explicitly use `nw.col`.\n"
+            "  For example, `df.select(nw.col(0))` if you have a column named `0`.\n"
+            "- if you were trying to create a new literal column, then you \n"
+            "  should explicitly use `nw.lit`.\n"
+            "  For example, `df.select(nw.lit(0))` if you want to create a new\n"
+            "  column with literal value `0`."
         )
         return InvalidIntoExprError(message)


Test patch:
diff --git a/tests/frame/select_test.py b/tests/frame/select_test.py
index b2897d83..b06efe00 100644
--- a/tests/frame/select_test.py
+++ b/tests/frame/select_test.py
@@ -40,7 +40,7 @@ def test_non_string_select() -> None:
 
 def test_int_select_pandas() -> None:
     df = nw.from_native(pd.DataFrame({0: [1, 2], "b": [3, 4]}))
-    with pytest.raises(InvalidIntoExprError, match="\n\nHint: if you were trying"):
+    with pytest.raises(InvalidIntoExprError, match="\n\nHint:\n- if you were trying"):
         nw.to_native(df.select(0))  # type: ignore[arg-type]