From fdc08139a5ba3f526f1846a867248d595116b64c Mon Sep 17 00:00:00 2001 From: jfh Date: Thu, 17 Jun 2021 17:30:51 +0300 Subject: [PATCH 1/2] Make empty frozenset a singleton. --- Lib/test/test_set.py | 2 -- vm/src/builtins/set.rs | 26 ++++++++++++++------------ vm/src/pyobject.rs | 6 +++++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index a399d1caf..73a15d1ef 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -715,8 +715,6 @@ class TestFrozenSet(TestJointOps, unittest.TestCase): s.__init__(self.otherword) self.assertEqual(s, set(self.word)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_singleton_empty_frozenset(self): f = frozenset() efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index f322c1f14..0d2f3bff5 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -5,7 +5,6 @@ use super::pytype::PyTypeRef; use crate::common::hash::PyHash; use crate::common::rc::PyRc; use crate::dictdatatype; -use crate::function::OptionalArg::{Missing, Present}; use crate::function::{Args, OptionalArg}; use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable}; use crate::vm::{ReprGuard, VirtualMachine}; @@ -573,23 +572,26 @@ impl PyFrozenSet { iterable: OptionalArg, vm: &VirtualMachine, ) -> PyResult> { - let iterable = if let Present(iterable) = iterable { - if cls.is(&vm.ctx.types.frozenset_type) { - match iterable.downcast_exact::(vm) { - Ok(iter) => return Ok(iter), - Err(iterable) => Present(PyIterable::try_from_object(vm, iterable)?), + let elements = if let OptionalArg::Present(iterable) = iterable { + let iterable = if cls.is(&vm.ctx.types.frozenset_type) { + match iterable.downcast_exact::(vm) { + Ok(fs) => return Ok(fs), + Err(iterable) => iterable, } } else { - Present(PyIterable::try_from_object(vm, iterable)?) - } + iterable + }; + vm.extract_elements(&iterable)? } else { - Missing + vec![] }; - Self { - inner: PySetInner::from_arg(iterable, vm)?, + // Return empty fs if iterable passed is emtpy and only for exact fs types. + if elements.is_empty() && cls.is(&vm.ctx.types.frozenset_type) { + Ok(vm.ctx.empty_frozenset.clone()) + } else { + Self::from_iter(vm, elements).and_then(|o| o.into_ref_with_type(vm, cls)) } - .into_ref_with_type(vm, cls) } #[pymethod(name = "__len__")] diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 2c1d33ee2..df823f1be 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -24,7 +24,7 @@ use crate::builtins::namespace::PyNamespace; use crate::builtins::object; use crate::builtins::pystr; use crate::builtins::pytype::{self, PyType, PyTypeRef}; -use crate::builtins::set; +use crate::builtins::set::{self, PyFrozenSet}; use crate::builtins::singletons::{PyNone, PyNoneRef, PyNotImplemented, PyNotImplementedRef}; use crate::builtins::slice::PyEllipsis; use crate::builtins::staticmethod::PyStaticMethod; @@ -89,6 +89,7 @@ pub struct PyContext { pub false_value: PyIntRef, pub none: PyNoneRef, pub empty_tuple: PyTupleRef, + pub empty_frozenset: PyRef, pub ellipsis: PyRef, pub not_implemented: PyNotImplementedRef, @@ -129,6 +130,8 @@ impl PyContext { PyTuple::_new(Vec::new().into_boxed_slice()), &types.tuple_type, ); + let empty_frozenset = + PyRef::new_ref(PyFrozenSet::default(), types.frozenset_type.clone(), None); let string_cache = Dict::default(); @@ -144,6 +147,7 @@ impl PyContext { false_value, none, empty_tuple, + empty_frozenset, ellipsis, not_implemented, From 712f95036d00abd8ff7dd8036e8ba48e20109d45 Mon Sep 17 00:00:00 2001 From: jfh Date: Mon, 12 Jul 2021 00:25:34 +0300 Subject: [PATCH 2/2] Remove allow_dead_code as it is unecessary now. --- vm/src/builtins/set.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 0d2f3bff5..8d26c5e1a 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -553,8 +553,7 @@ macro_rules! multi_args_frozenset { #[pyimpl(flags(BASETYPE), with(Hashable, Comparable, Iterable))] impl PyFrozenSet { - // used by ssl.rs windows - #[allow(dead_code)] + // Also used by ssl.rs windows. pub(crate) fn from_iter( vm: &VirtualMachine, it: impl IntoIterator,