mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #2715 from DimitrisJim/frozenset_singleton
Make `frozenset(empty_iterable)` return a singleton.
This commit is contained in:
@@ -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(''),
|
||||
|
||||
@@ -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};
|
||||
@@ -554,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<Item = PyObjectRef>,
|
||||
@@ -573,23 +571,26 @@ impl PyFrozenSet {
|
||||
iterable: OptionalArg<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
let iterable = if let Present(iterable) = iterable {
|
||||
if cls.is(&vm.ctx.types.frozenset_type) {
|
||||
match iterable.downcast_exact::<PyFrozenSet>(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::<Self>(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__")]
|
||||
|
||||
@@ -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<PyFrozenSet>,
|
||||
pub ellipsis: PyRef<PyEllipsis>,
|
||||
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,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user