Skip to content

Commit 3be40b8

Browse files
committed
Introspection: make __new__ return the type and not None
1 parent d15a14a commit 3be40b8

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

pyo3-macros-backend/src/pyimpl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ use crate::{
1818
};
1919
use proc_macro2::TokenStream;
2020
use quote::{format_ident, quote};
21-
#[cfg(feature = "experimental-inspect")]
22-
use syn::Ident;
2321
use syn::{
2422
parse::{Parse, ParseStream},
2523
spanned::Spanned,
2624
ImplItemFn, Result,
2725
};
26+
#[cfg(feature = "experimental-inspect")]
27+
use syn::{parse_quote, Ident};
2828

2929
/// The mechanism used to collect `#[pymethods]` into the type object
3030
#[derive(Copy, Clone)]
@@ -411,7 +411,7 @@ fn method_introspection_code(spec: &FnSpec<'_>, parent: &syn::Type, ctx: &Ctx) -
411411
}
412412
FnType::FnNew | FnType::FnNewClass(_) => {
413413
first_argument = Some("cls");
414-
output = syn::ReturnType::Default; // The __new__ Python function return type is None
414+
output = parse_quote!(-> #pyo3_path::PyRef<Self>); // Hack to return Self while implementing IntoPyObject
415415
}
416416
FnType::FnClass(_) => {
417417
first_argument = Some("cls");

pytests/stubs/comparisons.pyi

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
class Eq:
22
def __eq__(self, /, other: Eq) -> bool: ...
33
def __ne__(self, /, other: Eq) -> bool: ...
4-
def __new__(cls, /, value: int) -> None: ...
4+
def __new__(cls, /, value: int) -> Eq: ...
55

66
class EqDefaultNe:
77
def __eq__(self, /, other: EqDefaultNe) -> bool: ...
8-
def __new__(cls, /, value: int) -> None: ...
8+
def __new__(cls, /, value: int) -> EqDefaultNe: ...
99

1010
class EqDerived:
1111
def __eq__(self, /, other: EqDerived) -> bool: ...
1212
def __ne__(self, /, other: EqDerived) -> bool: ...
13-
def __new__(cls, /, value: int) -> None: ...
13+
def __new__(cls, /, value: int) -> EqDerived: ...
1414

1515
class Ordered:
1616
def __eq__(self, /, other: Ordered) -> bool: ...
@@ -19,15 +19,15 @@ class Ordered:
1919
def __le__(self, /, other: Ordered) -> bool: ...
2020
def __lt__(self, /, other: Ordered) -> bool: ...
2121
def __ne__(self, /, other: Ordered) -> bool: ...
22-
def __new__(cls, /, value: int) -> None: ...
22+
def __new__(cls, /, value: int) -> Ordered: ...
2323

2424
class OrderedDefaultNe:
2525
def __eq__(self, /, other: OrderedDefaultNe) -> bool: ...
2626
def __ge__(self, /, other: OrderedDefaultNe) -> bool: ...
2727
def __gt__(self, /, other: OrderedDefaultNe) -> bool: ...
2828
def __le__(self, /, other: OrderedDefaultNe) -> bool: ...
2929
def __lt__(self, /, other: OrderedDefaultNe) -> bool: ...
30-
def __new__(cls, /, value: int) -> None: ...
30+
def __new__(cls, /, value: int) -> OrderedDefaultNe: ...
3131

3232
class OrderedDerived:
3333
def __eq__(self, /, other: OrderedDerived) -> bool: ...
@@ -37,7 +37,7 @@ class OrderedDerived:
3737
def __le__(self, /, other: OrderedDerived) -> bool: ...
3838
def __lt__(self, /, other: OrderedDerived) -> bool: ...
3939
def __ne__(self, /, other: OrderedDerived) -> bool: ...
40-
def __new__(cls, /, value: int) -> None: ...
40+
def __new__(cls, /, value: int) -> OrderedDerived: ...
4141
def __str__(self, /) -> str: ...
4242

4343
class OrderedRichCmp:
@@ -47,4 +47,4 @@ class OrderedRichCmp:
4747
def __le__(self, /, other: OrderedRichCmp) -> bool: ...
4848
def __lt__(self, /, other: OrderedRichCmp) -> bool: ...
4949
def __ne__(self, /, other: OrderedRichCmp) -> bool: ...
50-
def __new__(cls, /, value: int) -> None: ...
50+
def __new__(cls, /, value: int) -> OrderedRichCmp: ...

pytests/stubs/pyclasses.pyi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ from _typeshed import Incomplete
22
from typing import Any
33

44
class AssertingBaseClass:
5-
def __new__(cls, /, expected_type: Any) -> None: ...
5+
def __new__(cls, /, expected_type: Any) -> AssertingBaseClass: ...
66

77
class ClassWithDecorators:
8-
def __new__(cls, /) -> None: ...
8+
def __new__(cls, /) -> ClassWithDecorators: ...
99
@property
1010
def attr(self, /) -> int: ...
1111
@attr.setter
@@ -19,13 +19,13 @@ class ClassWithDecorators:
1919
def static_method() -> int: ...
2020

2121
class ClassWithDict:
22-
def __new__(cls, /) -> None: ...
22+
def __new__(cls, /) -> ClassWithDict: ...
2323

2424
class ClassWithoutConstructor: ...
2525

2626
class EmptyClass:
2727
def __len__(self, /) -> int: ...
28-
def __new__(cls, /) -> None: ...
28+
def __new__(cls, /) -> EmptyClass: ...
2929
def method(self, /) -> None: ...
3030

3131
class PlainObject:
@@ -39,11 +39,11 @@ class PlainObject:
3939
def foo(self, /, value: str) -> None: ...
4040

4141
class PyClassIter:
42-
def __new__(cls, /) -> None: ...
42+
def __new__(cls, /) -> PyClassIter: ...
4343
def __next__(self, /) -> int: ...
4444

4545
class PyClassThreadIter:
46-
def __new__(cls, /) -> None: ...
46+
def __new__(cls, /) -> PyClassThreadIter: ...
4747
def __next__(self, /) -> int: ...
4848

4949
def map_a_class(

0 commit comments

Comments
 (0)