(
mut args: FuncArgs,
vm: &VirtualMachine,
func_name: &str,
op: PyComparisonOp,
)
| 821 | } |
| 822 | |
| 823 | fn min_or_max( |
| 824 | mut args: FuncArgs, |
| 825 | vm: &VirtualMachine, |
| 826 | func_name: &str, |
| 827 | op: PyComparisonOp, |
| 828 | ) -> PyResult { |
| 829 | let default = args.take_keyword("default"); |
| 830 | let key_func = args.take_keyword("key"); |
| 831 | |
| 832 | if let Some(err) = args.check_kwargs_empty(vm) { |
| 833 | return Err(err); |
| 834 | } |
| 835 | |
| 836 | let candidates = match args.args.len().cmp(&1) { |
| 837 | core::cmp::Ordering::Greater => { |
| 838 | if default.is_some() { |
| 839 | return Err(vm.new_type_error(format!( |
| 840 | "Cannot specify a default for {func_name}() with multiple positional arguments" |
| 841 | ))); |
| 842 | } |
| 843 | args.args |
| 844 | } |
| 845 | core::cmp::Ordering::Equal => args.args[0].try_to_value(vm)?, |
| 846 | core::cmp::Ordering::Less => { |
| 847 | // zero arguments means type error: |
| 848 | return Err( |
| 849 | vm.new_type_error(format!("{func_name} expected at least 1 argument, got 0")) |
| 850 | ); |
| 851 | } |
| 852 | }; |
| 853 | |
| 854 | let mut candidates_iter = candidates.into_iter(); |
| 855 | let mut x = match candidates_iter.next() { |
| 856 | Some(x) => x, |
| 857 | None => { |
| 858 | return default.ok_or_else(|| { |
| 859 | vm.new_value_error(format!("{func_name}() iterable argument is empty")) |
| 860 | }); |
| 861 | } |
| 862 | }; |
| 863 | |
| 864 | let key_func = key_func.filter(|f| !vm.is_none(f)); |
| 865 | if let Some(ref key_func) = key_func { |
| 866 | let mut x_key = key_func.call((x.clone(),), vm)?; |
| 867 | for y in candidates_iter { |
| 868 | let y_key = key_func.call((y.clone(),), vm)?; |
| 869 | if y_key.rich_compare_bool(&x_key, op, vm)? { |
| 870 | x = y; |
| 871 | x_key = y_key; |
| 872 | } |
| 873 | } |
| 874 | } else { |
| 875 | for y in candidates_iter { |
| 876 | if y.rich_compare_bool(&x, op, vm)? { |
| 877 | x = y; |
| 878 | } |
| 879 | } |
| 880 | } |
no test coverage detected