feat: add when-then-otherwise expression
What type of PR is this? (check all applicable)
- [ ] 💾 Refactor
- [x] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔧 Optimization
- [ ] 📝 Documentation
- [ ] ✅ Test
- [ ] 🐳 Other
Related issues
- Related issue #47
Checklist
- [x] Code follows style guide (ruff)
- [x] Tests added
- [x] Documented the changes
If you have comments or can explain your changes, please do so below.
This PR so far adds a simple when-then-otherwise expression with no chaining
~The PR does not aim to be complete as of now, the current aim is to get an initial review as to if this approach is consistent with the project's quality and style of code~
TODO:
- [x] Allow
Iterable[IntoPandasExpr]to the pandas API forpredicates - [x] ~Allow
when-then-otherwisechaining~ obsolete: see comments below and #668 - [x] Address noqa ignores
~Note: Temporary converted back to draft due to a git rebase issue~ fixed
Note: due to an unfortunate rebase gone wrong, the commit history is a mess, we could open a new pr from a new branch or when merging do a squash merge. Further advice on this would be much appreciated.
@MarcoGorelli can you take another look at this?
@MarcoGorelli
Note that I have added support for users to be able to provide Series or Expr as then and otherwise values, not just scalars, which I think is a crucial behaviour
Currently not all code paths are tested, according to the coverage test, am looking into this
legend, thanks!
cool, once code coverage is complete we can ship it 🚀
@MarcoGorelli
can you take another look at this?
thanks @aivanoved !
looks like there's a warning in the docs build
WARNING - griffe: narwhals/expr.py:3676: Failed to get 'name: description' pair from 'predicates'
and test failures on python 3.8
FAILED tests/expr_and_series/when_test.py::test_no_arg_when_fail[polars_eager_constructor] - ValueError: No predicates or constraints provided to `when`.
FAILED tests/expr_and_series/when_test.py::test_no_arg_when_fail[polars_lazy_constructor] - ValueError: No predicates or constraints provided to `when`.
The doc test I will address
However, for the python 3.8 issue - the issue comes from that starting from polars version 0.20.4 onwards the error thrown when there are no predicates or constraints is a TypeError, for which we test
For versions below this, meaning polars<=0.20.3, the error thrown is a ValueError, in the ci the installed version of polars is 0.20.3
I can change the error type depending on the installed polars version, however this seems unsatisfactory, please advise @MarcoGorelli
For reference here is the error thrown in version 0.20.3
And here is the same error in version 0.20.4
thanks @aivanoved !
looks like there's a warning in the docs build
WARNING - griffe: narwhals/expr.py:3676: Failed to get 'name: description' pair from 'predicates'and test failures on python 3.8
FAILED tests/expr_and_series/when_test.py::test_no_arg_when_fail[polars_eager_constructor] - ValueError: No predicates or constraints provided to `when`. FAILED tests/expr_and_series/when_test.py::test_no_arg_when_fail[polars_lazy_constructor] - ValueError: No predicates or constraints provided to `when`.
I think you can do with pytest.raises((ValueError, TypeError)):
any reason why you closed the PR?
No, I guess I misclicked and canceled it by accident
I think you can do
with pytest.raises((ValueError, TypeError)):any reason why you closed the PR?
As long as we are fine with having narwhals and polars throwing different types of error for polars<=0.20.3 this works, just want to make sure we are happy with the this decision
@MarcoGorelli
Everything should be working now I think
gentle ping @MarcoGorelli
thanks for updating - hoping to merge this soon
I'm currently on vacation will take a closer look into this again, but will be slower to respond, apologies for the delay
thank you both @MarcoGorelli and @FBruzzesi for the close review
hope we can iron everything out soon
cool, no hurry, enjoy your holiday, thanks @aivanoved !
fixed by xfail ~current ci fails with the new zip_with, due to a known issue in modin, here~
fixed ~ci fails because of this if conditioning, which is essentially a pandas version check, so the else condition does not get executed for pandas>=1.*, for me this is a tricky one to fix.failure due to coverage test~
Thank you @aivanoved for working this! This is a great addition