Skip to content

Commit 07da500

Browse files
authored
reintroduce PyTypeInfo methods (#4484)
1 parent 7aa2101 commit 07da500

File tree

15 files changed

+64
-50
lines changed

15 files changed

+64
-50
lines changed

guide/src/class/numeric.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ fn my_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
387387
# fn main() -> PyResult<()> {
388388
# Python::with_gil(|py| -> PyResult<()> {
389389
# let globals = PyModule::import(py, "__main__")?.dict();
390-
# globals.set_item("Number", Number::type_object_bound(py))?;
390+
# globals.set_item("Number", Number::type_object(py))?;
391391
#
392392
# py.run(SCRIPT, Some(&globals), None)?;
393393
# Ok(())

src/err/mod.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl PyErr {
160160
{
161161
PyErr::from_state(PyErrState::Lazy(Box::new(move |py| {
162162
PyErrStateLazyFnOutput {
163-
ptype: T::type_object_bound(py).into(),
163+
ptype: T::type_object(py).into(),
164164
pvalue: args.arguments(py),
165165
}
166166
})))
@@ -215,7 +215,7 @@ impl PyErr {
215215
/// assert_eq!(err.to_string(), "TypeError: some type error");
216216
///
217217
/// // Case #2: Exception type
218-
/// let err = PyErr::from_value(PyTypeError::type_object_bound(py).into_any());
218+
/// let err = PyErr::from_value(PyTypeError::type_object(py).into_any());
219219
/// assert_eq!(err.to_string(), "TypeError: ");
220220
///
221221
/// // Case #3: Invalid exception value
@@ -587,7 +587,7 @@ impl PyErr {
587587
where
588588
T: PyTypeInfo,
589589
{
590-
self.is_instance(py, &T::type_object_bound(py))
590+
self.is_instance(py, &T::type_object(py))
591591
}
592592

593593
/// Writes the error back to the Python interpreter's global state.
@@ -1187,21 +1187,18 @@ mod tests {
11871187
fn test_pyerr_matches() {
11881188
Python::with_gil(|py| {
11891189
let err = PyErr::new::<PyValueError, _>("foo");
1190-
assert!(err.matches(py, PyValueError::type_object_bound(py)));
1190+
assert!(err.matches(py, PyValueError::type_object(py)));
11911191

11921192
assert!(err.matches(
11931193
py,
1194-
(
1195-
PyValueError::type_object_bound(py),
1196-
PyTypeError::type_object_bound(py)
1197-
)
1194+
(PyValueError::type_object(py), PyTypeError::type_object(py))
11981195
));
11991196

1200-
assert!(!err.matches(py, PyTypeError::type_object_bound(py)));
1197+
assert!(!err.matches(py, PyTypeError::type_object(py)));
12011198

12021199
// String is not a valid exception class, so we should get a TypeError
1203-
let err: PyErr = PyErr::from_type(crate::types::PyString::type_object_bound(py), "foo");
1204-
assert!(err.matches(py, PyTypeError::type_object_bound(py)));
1200+
let err: PyErr = PyErr::from_type(crate::types::PyString::type_object(py), "foo");
1201+
assert!(err.matches(py, PyTypeError::type_object(py)));
12051202
})
12061203
}
12071204

src/impl_/pymodule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl<T> AddTypeToModule<T> {
176176

177177
impl<T: PyTypeInfo> PyAddToModule for AddTypeToModule<T> {
178178
fn add_to_module(&'static self, module: &Bound<'_, PyModule>) -> PyResult<()> {
179-
module.add(T::NAME, T::type_object_bound(module.py()))
179+
module.add(T::NAME, T::type_object(module.py()))
180180
}
181181
}
182182

src/marker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ impl<'py> Python<'py> {
685685
where
686686
T: PyTypeInfo,
687687
{
688-
T::type_object_bound(self)
688+
T::type_object(self)
689689
}
690690

691691
/// Deprecated name for [`Python::get_type`].

src/tests/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ mod inner {
144144
$crate::tests::common::CatchWarnings::enter($py, |w| {
145145
use $crate::types::{PyListMethods, PyStringMethods};
146146
$body;
147-
let expected_warnings = [$((<$category as $crate::type_object::PyTypeInfo>::type_object_bound($py), $message)),+];
147+
let expected_warnings = [$((<$category as $crate::type_object::PyTypeInfo>::type_object($py), $message)),+];
148148
assert_eq!(w.len(), expected_warnings.len());
149149
for (warning, (category, message)) in w.iter().zip(expected_warnings) {
150150

src/type_object.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub unsafe trait PyTypeInfo: Sized {
4646

4747
/// Returns the safe abstraction over the type object.
4848
#[inline]
49-
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType> {
49+
fn type_object(py: Python<'_>) -> Bound<'_, PyType> {
5050
// Making the borrowed object `Bound` is necessary for soundness reasons. It's an extreme
5151
// edge case, but arbitrary Python code _could_ change the __class__ of an object and cause
5252
// the type object to be freed.
@@ -61,17 +61,38 @@ pub unsafe trait PyTypeInfo: Sized {
6161
}
6262
}
6363

64+
/// Deprecated name for [`PyTypeInfo::type_object`].
65+
#[deprecated(since = "0.23.0", note = "renamed to `PyTypeInfo::type_object`")]
66+
#[inline]
67+
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType> {
68+
Self::type_object(py)
69+
}
70+
6471
/// Checks if `object` is an instance of this type or a subclass of this type.
6572
#[inline]
66-
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
73+
fn is_type_of(object: &Bound<'_, PyAny>) -> bool {
6774
unsafe { ffi::PyObject_TypeCheck(object.as_ptr(), Self::type_object_raw(object.py())) != 0 }
6875
}
6976

77+
/// Deprecated name for [`PyTypeInfo::is_type_of`].
78+
#[deprecated(since = "0.23.0", note = "renamed to `PyTypeInfo::is_type_of`")]
79+
#[inline]
80+
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
81+
Self::is_type_of(object)
82+
}
83+
7084
/// Checks if `object` is an instance of this type.
7185
#[inline]
72-
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
86+
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool {
7387
unsafe { ffi::Py_TYPE(object.as_ptr()) == Self::type_object_raw(object.py()) }
7488
}
89+
90+
/// Deprecated name for [`PyTypeInfo::is_exact_type_of`].
91+
#[deprecated(since = "0.23.0", note = "renamed to `PyTypeInfo::is_exact_type_of`")]
92+
#[inline]
93+
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
94+
Self::is_exact_type_of(object)
95+
}
7596
}
7697

7798
/// Implemented by types which can be used as a concrete Python type inside `Py<T>` smart pointers.
@@ -93,7 +114,7 @@ where
93114

94115
#[inline]
95116
fn type_check(object: &Bound<'_, PyAny>) -> bool {
96-
T::is_type_of_bound(object)
117+
T::is_type_of(object)
97118
}
98119
}
99120

src/types/any.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,12 +1430,12 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
14301430

14311431
#[inline]
14321432
fn is_instance_of<T: PyTypeInfo>(&self) -> bool {
1433-
T::is_type_of_bound(self)
1433+
T::is_type_of(self)
14341434
}
14351435

14361436
#[inline]
14371437
fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
1438-
T::is_exact_type_of_bound(self)
1438+
T::is_exact_type_of(self)
14391439
}
14401440

14411441
fn contains<V>(&self, value: V) -> PyResult<bool>
@@ -1917,7 +1917,7 @@ class SimpleClass:
19171917
#[test]
19181918
fn test_is_callable() {
19191919
Python::with_gil(|py| {
1920-
assert!(PyList::type_object_bound(py).is_callable());
1920+
assert!(PyList::type_object(py).is_callable());
19211921

19221922
let not_callable = 5.to_object(py).into_bound(py);
19231923
assert!(!not_callable.is_callable());

src/types/code.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mod tests {
2323
#[test]
2424
fn test_type_object() {
2525
Python::with_gil(|py| {
26-
assert_eq!(PyCode::type_object_bound(py).name().unwrap(), "code");
26+
assert_eq!(PyCode::type_object(py).name().unwrap(), "code");
2727
})
2828
}
2929
}

src/types/ellipsis.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ unsafe impl PyTypeInfo for PyEllipsis {
3737
}
3838

3939
#[inline]
40-
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
40+
fn is_type_of(object: &Bound<'_, PyAny>) -> bool {
4141
// ellipsis is not usable as a base type
42-
Self::is_exact_type_of_bound(object)
42+
Self::is_exact_type_of(object)
4343
}
4444

4545
#[inline]
46-
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
46+
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool {
4747
object.is(&**Self::get(object.py()))
4848
}
4949
}
@@ -67,7 +67,7 @@ mod tests {
6767
Python::with_gil(|py| {
6868
assert!(PyEllipsis::get(py)
6969
.get_type()
70-
.is(&PyEllipsis::type_object_bound(py)));
70+
.is(&PyEllipsis::type_object(py)));
7171
})
7272
}
7373

src/types/mapping.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl PyMapping {
2424
/// library). This is equivalent to `collections.abc.Mapping.register(T)` in Python.
2525
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PyMapping`.
2626
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
27-
let ty = T::type_object_bound(py);
27+
let ty = T::type_object(py);
2828
get_mapping_abc(py)?.call_method1("register", (ty,))?;
2929
Ok(())
3030
}
@@ -172,7 +172,7 @@ impl PyTypeCheck for PyMapping {
172172
fn type_check(object: &Bound<'_, PyAny>) -> bool {
173173
// Using `is_instance` for `collections.abc.Mapping` is slow, so provide
174174
// optimized case dict as a well-known mapping
175-
PyDict::is_type_of_bound(object)
175+
PyDict::is_type_of(object)
176176
|| get_mapping_abc(object.py())
177177
.and_then(|abc| object.is_instance(abc))
178178
.unwrap_or_else(|err| {

src/types/none.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ unsafe impl PyTypeInfo for PyNone {
3838
}
3939

4040
#[inline]
41-
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
41+
fn is_type_of(object: &Bound<'_, PyAny>) -> bool {
4242
// NoneType is not usable as a base type
43-
Self::is_exact_type_of_bound(object)
43+
Self::is_exact_type_of(object)
4444
}
4545

4646
#[inline]
47-
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
47+
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool {
4848
object.is(&**Self::get(object.py()))
4949
}
5050
}
@@ -79,9 +79,7 @@ mod tests {
7979
#[test]
8080
fn test_none_type_object_consistent() {
8181
Python::with_gil(|py| {
82-
assert!(PyNone::get(py)
83-
.get_type()
84-
.is(&PyNone::type_object_bound(py)));
82+
assert!(PyNone::get(py).get_type().is(&PyNone::type_object(py)));
8583
})
8684
}
8785

src/types/notimplemented.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ unsafe impl PyTypeInfo for PyNotImplemented {
4040
}
4141

4242
#[inline]
43-
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
43+
fn is_type_of(object: &Bound<'_, PyAny>) -> bool {
4444
// NotImplementedType is not usable as a base type
45-
Self::is_exact_type_of_bound(object)
45+
Self::is_exact_type_of(object)
4646
}
4747

4848
#[inline]
49-
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
49+
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool {
5050
object.is(&**Self::get(object.py()))
5151
}
5252
}
@@ -70,7 +70,7 @@ mod tests {
7070
Python::with_gil(|py| {
7171
assert!(PyNotImplemented::get(py)
7272
.get_type()
73-
.is(&PyNotImplemented::type_object_bound(py)));
73+
.is(&PyNotImplemented::type_object(py)));
7474
})
7575
}
7676

src/types/pysuper.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,10 @@ impl PySuper {
6161
ty: &Bound<'py, PyType>,
6262
obj: &Bound<'py, PyAny>,
6363
) -> PyResult<Bound<'py, PySuper>> {
64-
PySuper::type_object_bound(ty.py())
65-
.call1((ty, obj))
66-
.map(|any| {
67-
// Safety: super() always returns instance of super
68-
unsafe { any.downcast_into_unchecked() }
69-
})
64+
PySuper::type_object(ty.py()).call1((ty, obj)).map(|any| {
65+
// Safety: super() always returns instance of super
66+
unsafe { any.downcast_into_unchecked() }
67+
})
7068
}
7169

7270
/// Deprecated name for [`PySuper::new`].

src/types/sequence.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl PySequence {
2727
/// library). This is equivalent to `collections.abc.Sequence.register(T)` in Python.
2828
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PySequence`.
2929
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
30-
let ty = T::type_object_bound(py);
30+
let ty = T::type_object(py);
3131
get_sequence_abc(py)?.call_method1("register", (ty,))?;
3232
Ok(())
3333
}
@@ -362,8 +362,8 @@ impl PyTypeCheck for PySequence {
362362
fn type_check(object: &Bound<'_, PyAny>) -> bool {
363363
// Using `is_instance` for `collections.abc.Sequence` is slow, so provide
364364
// optimized cases for list and tuples as common well-known sequences
365-
PyList::is_type_of_bound(object)
366-
|| PyTuple::is_type_of_bound(object)
365+
PyList::is_type_of(object)
366+
|| PyTuple::is_type_of(object)
367367
|| get_sequence_abc(object.py())
368368
.and_then(|abc| object.is_instance(abc))
369369
.unwrap_or_else(|err| {

src/types/typeobject.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl PyType {
2424
/// Creates a new type object.
2525
#[inline]
2626
pub fn new<T: PyTypeInfo>(py: Python<'_>) -> Bound<'_, PyType> {
27-
T::type_object_bound(py)
27+
T::type_object(py)
2828
}
2929

3030
/// Deprecated name for [`PyType::new`].
@@ -202,7 +202,7 @@ impl<'py> PyTypeMethods<'py> for Bound<'py, PyType> {
202202
where
203203
T: PyTypeInfo,
204204
{
205-
self.is_subclass(&T::type_object_bound(self.py()))
205+
self.is_subclass(&T::type_object(self.py()))
206206
}
207207

208208
fn mro(&self) -> Bound<'py, PyTuple> {

0 commit comments

Comments
 (0)