Skip to content

Commit bf33203

Browse files
committed
Fix #43
1 parent 6eb605a commit bf33203

3 files changed

Lines changed: 33 additions & 9 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ __pycache__
55
/.coverage
66
/.pytest_cache
77
/htmlcov
8+
/backup

python/tests/mixin.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def test_maxmemory_enforced_base_types(self):
138138
if self.NO_POLICY:
139139
with pytest.raises(OverflowError):
140140
cache[10] = 10
141-
141+
142142
assert 1 in cache
143143
else:
144144
cache[10] = 10
@@ -560,3 +560,11 @@ def test_copy(self):
560560

561561
c2.insert(1, 1)
562562
assert 1 not in c1
563+
564+
def test_cache_type(self):
565+
class AType:
566+
pass
567+
568+
cache = self.CACHE(maxsize=0, **self.KWARGS)
569+
cache[AType] = AType
570+
assert cache[AType] is AType

src/common.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use pyo3::types::PyAnyMethods;
2+
13
macro_rules! non_zero_or {
24
($num:expr, $_else:expr) => {
35
unsafe { core::num::NonZeroUsize::new_unchecked(if $num == 0 { $_else } else { $num }) }
@@ -180,23 +182,36 @@ macro_rules! extract_pickle_tuple {
180182
#[inline]
181183
#[cfg(not(PyPy))]
182184
pub fn pyobject_size(py: pyo3::Python<'_>, obj: &pyo3::Py<pyo3::PyAny>) -> pyo3::PyResult<usize> {
183-
use pyo3::types::PyAnyMethods;
185+
static SIZEOF_METHOD_NAME: &'static std::ffi::CStr = c"__sizeof__";
186+
187+
// PyPy does not support __sizeof__ or sys.getsizeof
188+
let sizeof_method = obj.bind(py).getattr(SIZEOF_METHOD_NAME)?;
184189

185-
obj.bind(py).call_method0("__sizeof__")?.extract::<usize>()
190+
unsafe {
191+
if pyo3::ffi::PyType_Check(obj.as_ptr()) == 1 {
192+
sizeof_method.call1((obj,))?.extract::<usize>()
193+
} else {
194+
sizeof_method.call0()?.extract::<usize>()
195+
}
196+
}
186197
}
187198

188199
#[inline]
189200
#[cfg(PyPy)]
190201
pub fn pyobject_size(py: pyo3::Python<'_>, obj: &pyo3::Py<pyo3::PyAny>) -> pyo3::PyResult<usize> {
191-
use pyo3::types::PyAnyMethods;
192-
193-
static SIZEOF_METHOD_NAME: &'static str = "__sizeof__";
202+
static SIZEOF_METHOD_NAME: &'static std::ffi::CStr = c"__sizeof__";
194203

195204
// PyPy does not support __sizeof__ or sys.getsizeof
196-
let has_sizeof = obj.bind(py).getattr_opt(SIZEOF_METHOD_NAME)?;
205+
let sizeof_method = obj.bind(py).getattr_opt(SIZEOF_METHOD_NAME)?;
197206

198-
match has_sizeof {
199-
Some(x) => x.call0()?.extract::<usize>(),
207+
match sizeof_method {
208+
Some(sizeof_method) => unsafe {
209+
if pyo3::ffi::PyType_Check(obj.as_ptr()) == 1 {
210+
sizeof_method.call1((obj,))?.extract::<usize>()
211+
} else {
212+
sizeof_method.call0()?.extract::<usize>()
213+
}
214+
},
200215
None => Ok(1),
201216
}
202217
}

0 commit comments

Comments
 (0)