Skip to content

Commit 523a0f9

Browse files
authored
Fix union args (RustPython#3864)
1 parent f16fcc6 commit 523a0f9

File tree

4 files changed

+35
-10
lines changed

4 files changed

+35
-10
lines changed

Lib/test/test_types.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,8 +755,6 @@ def test_or_type_operator_with_TypeVar(self):
755755
self.assertIs((int | TV)[int], int)
756756
self.assertIs((TV | int)[int], int)
757757

758-
# TODO: RUSTPYTHON
759-
@unittest.expectedFailure
760758
def test_union_args(self):
761759
def check(arg, expected):
762760
clear_typing_caches()

vm/src/builtins/genericalias.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::type_;
12
use crate::{
23
builtins::{PyList, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef},
34
class::PyClassImpl,
@@ -188,6 +189,16 @@ impl PyGenericAlias {
188189
Err(vm
189190
.new_type_error("issubclass() argument 2 cannot be a parameterized generic".to_owned()))
190191
}
192+
193+
#[pymethod(magic)]
194+
fn ror(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
195+
type_::or_(other, zelf, vm)
196+
}
197+
198+
#[pymethod(magic)]
199+
fn or(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
200+
type_::or_(zelf, other, vm)
201+
}
191202
}
192203

193204
fn is_typevar(obj: &PyObjectRef, vm: &VirtualMachine) -> bool {

vm/src/builtins/type.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -403,15 +403,14 @@ impl PyType {
403403
zelf.iter_mro().map(|cls| cls.clone().into()).collect()
404404
}
405405

406-
#[pymethod(name = "__ror__")]
407406
#[pymethod(magic)]
408-
pub fn or(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
409-
if !union_::is_unionable(zelf.clone(), vm) || !union_::is_unionable(other.clone(), vm) {
410-
return vm.ctx.not_implemented();
411-
}
407+
pub fn ror(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
408+
or_(other, zelf, vm)
409+
}
412410

413-
let tuple = PyTuple::new_ref(vec![zelf, other], &vm.ctx);
414-
union_::make_union(tuple, vm)
411+
#[pymethod(magic)]
412+
pub fn or(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
413+
or_(zelf, other, vm)
415414
}
416415

417416
#[pyslot]
@@ -826,6 +825,15 @@ pub(crate) fn call_slot_new(
826825
unreachable!("Should be able to find a new slot somewhere in the mro")
827826
}
828827

828+
pub(super) fn or_(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
829+
if !union_::is_unionable(zelf.clone(), vm) || !union_::is_unionable(other.clone(), vm) {
830+
return vm.ctx.not_implemented();
831+
}
832+
833+
let tuple = PyTuple::new_ref(vec![zelf, other], &vm.ctx);
834+
union_::make_union(tuple, vm)
835+
}
836+
829837
fn take_next_base(bases: &mut [Vec<PyTypeRef>]) -> Option<PyTypeRef> {
830838
for base in bases.iter() {
831839
let head = base[0].clone();

vm/src/builtins/union.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::genericalias;
1+
use super::{genericalias, type_};
22
use crate::{
33
builtins::{PyFrozenSet, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef},
44
class::PyClassImpl,
@@ -100,6 +100,12 @@ impl PyUnion {
100100
Err(vm
101101
.new_type_error("issubclass() argument 2 cannot be a parameterized generic".to_owned()))
102102
}
103+
104+
#[pymethod(name = "__ror__")]
105+
#[pymethod(magic)]
106+
fn or(zelf: PyObjectRef, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
107+
type_::or_(zelf, other, vm)
108+
}
103109
}
104110

105111
pub fn is_unionable(obj: PyObjectRef, vm: &VirtualMachine) -> bool {
@@ -156,6 +162,8 @@ fn flatten_args(args: PyTupleRef, vm: &VirtualMachine) -> PyTupleRef {
156162
for arg in &args {
157163
if let Some(pyref) = arg.downcast_ref::<PyUnion>() {
158164
flattened_args.extend(pyref.args.iter().cloned());
165+
} else if vm.is_none(arg) {
166+
flattened_args.push(vm.ctx.types.none_type.to_owned().into());
159167
} else {
160168
flattened_args.push(arg.clone());
161169
};

0 commit comments

Comments
 (0)