Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
67a137e
Implement _collections.OrderedDict
moreal Sep 22, 2026
dc8e92d
Add OrderedDict, warnings source lines, and socket sendmsg
youknowone Sep 21, 2026
182ad24
Load marshal via readinto and dump sets in dumps order
youknowone Sep 21, 2026
d8be145
Add classmethod_descriptor and ABC IS_ABSTRACT flags
youknowone Sep 22, 2026
6867000
address review: odict reuse, descr call, new wrapper
youknowone Sep 22, 2026
58791c4
Represent chflags bits with bitflagset
youknowone Sep 22, 2026
1fe22ce
Represent access and mode bits with bitflagset
youknowone Sep 22, 2026
3de8a8f
Continue unfinished REPL suites as incomplete input
youknowone Sep 22, 2026
f63b772
Add pickle and os.stat inspect signatures
youknowone Sep 22, 2026
44a1cf5
Add Unpickler, dump/load, and lstat signatures
youknowone Sep 22, 2026
a3fb270
Complete OrderedDict with insertion-order links
youknowone Sep 22, 2026
ce35d46
address CI: stat casts, HCI_DATA_DIR, passing xfails
youknowone Sep 22, 2026
498dae1
Fix wasm teardown deadlock and bluetooth constants
youknowone Sep 22, 2026
38909e2
Clear process-wide eval breaker bits in STW test
youknowone Sep 22, 2026
fdce5f2
Drop exclusive-held panic that tripped wasm clippy
youknowone Sep 22, 2026
0c38852
Fix OrderedDict contains and export Windows BDADDR
youknowone Sep 22, 2026
fddfe4b
Add cmp_to_key and hash-once LRU cache
youknowone Sep 23, 2026
305a502
Allow subclass keywords on list, tuple, and float
youknowone Sep 23, 2026
56a912f
Fix CI lint, test re-export, and structseq members
youknowone Sep 23, 2026
e47a535
Allow subclass keywords on itertools and filter
youknowone Sep 23, 2026
c7b6022
Remove text_signature derive parameter
youknowone Sep 23, 2026
5976f3a
Rename set contains_method to __contains__
youknowone Sep 23, 2026
207fa0b
Use MonitoringEvent instead of EVENT_* aliases
youknowone Sep 23, 2026
4cfcd7f
Store warnings filters as PyListRef
youknowone Sep 23, 2026
16c6d77
Re-export clear_eval_breaker_for_test after rebase
youknowone Sep 23, 2026
dc10fca
Fix groupby reentrancy and islice arguments
youknowone Sep 23, 2026
0d0c26f
SETREF warnings filters, onceregistry, and defaultaction
youknowone Sep 23, 2026
af31e63
Iterate OrderedDict inner dict via next_entry
youknowone Sep 23, 2026
299879d
Remove expectedFailure from testBluetoothConstants
youknowone Sep 23, 2026
277a5f5
Borrow get_filter arguments as PyObject
youknowone Sep 23, 2026
acd78e7
Fix bool slots and SemHandle safety docs
youknowone Sep 23, 2026
ac2e463
Keep sendmsg errors and drop duplicate linecache
youknowone Sep 24, 2026
1234e88
Nest REPL parse or-patterns for clippy
youknowone Sep 24, 2026
15f3bf4
Mark pydoc os.stat signature test expectedFailure
youknowone Sep 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove text_signature derive parameter
Drop the string override on #[pyfunction] and #[pyclass]. Signatures
are generated from the Rust parameter list only. Restore inspect
expectedFailures that depended on the override.

Assisted-by: Grok:grok-4.6
  • Loading branch information
youknowone committed Sep 24, 2026
commit c7b6022bd35826feddedb5e44b3ba87848398ca9
4 changes: 4 additions & 0 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,10 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase):
if c_functools:
cmp_to_key = c_functools.cmp_to_key

@unittest.expectedFailure # TODO: RUSTPYTHON; inspect.signature reports (args, /) until FromArgs fields generate __text_signature__
def test_cmp_to_signature(self):
super().test_cmp_to_signature()

@support.cpython_only
def test_disallow_instantiation(self):
# Ensure that the type disallows instantiation (bpo-43916)
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,7 @@ def test(): pass
spec = inspect.getfullargspec(test)
self.assertEqual(test.__annotations__, spec.annotations)

@unittest.expectedFailure # TODO: RUSTPYTHON; os.stat signature is generated as (path, dir_fd, follow_symlinks, /)
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_getfullargspec_builtin_methods(self):
Expand Down Expand Up @@ -3511,6 +3512,7 @@ def m1d(*args, **kwargs):
('arg2', 1, ..., "positional_or_keyword")),
int))

@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class 'classmethod'>
def test_signature_on_classmethod(self):
if not support.MISSING_C_DOCSTRINGS:
self.assertEqual(self.signature(classmethod),
Expand All @@ -3534,6 +3536,7 @@ def foo(cls, arg1, *, arg2=1):
('arg2', 1, ..., "keyword_only")),
...))

@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class 'staticmethod'>
def test_signature_on_staticmethod(self):
if not support.MISSING_C_DOCSTRINGS:
self.assertEqual(self.signature(staticmethod),
Expand Down Expand Up @@ -4612,6 +4615,7 @@ class D(C): pass
with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
self.assertEqual(inspect.signature(D), None)

@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class '_pickle.Pickler'>
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_signature_on_builtin_class(self):
Expand Down Expand Up @@ -5153,6 +5157,7 @@ class foo: pass
foo_sig = MySignature.from_callable(foo)
self.assertIsInstance(foo_sig, MySignature)

@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class '_pickle.Pickler'>
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_signature_from_callable_builtin_obj(self):
Expand Down
15 changes: 1 addition & 14 deletions crates/derive-impl/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ fn cpython_attr_doc(rust_type: &str, attr: &str) -> Option<String> {
None
}

#[allow(clippy::too_many_arguments)]
fn generate_class_def(
ident: &Ident,
name: &str,
Expand All @@ -443,22 +442,13 @@ fn generate_class_def(
metaclass: Option<String>,
unhashable: bool,
attrs: &[Attribute],
text_signature: Option<&str>,
) -> Result<TokenStream> {
let doc = attrs.doc().or_else(|| {
let module_name = module_name.unwrap_or("builtins");
DB.get(&format!("{module_name}.{name}"))
.copied()
.map(str::to_owned)
});
let doc = match (text_signature, doc) {
(Some(sig), doc) => Some(format_doc(
&format!("{name}{sig}"),
&doc.unwrap_or_default(),
)),
(None, Some(doc)) => Some(doc),
(None, None) => None,
};
let doc = if let Some(doc) = doc {
quote!(Some(#doc))
} else {
Expand Down Expand Up @@ -598,23 +588,21 @@ pub(crate) fn impl_pyclass(attr: PunctuatedNestedMeta, item: Item) -> Result<Tok
}

let fake_ident = Ident::new("pyclass", item.span());
let (class_meta, class_name, module_name, base, metaclass, unhashable, text_signature) = {
let (class_meta, class_name, module_name, base, metaclass, unhashable) = {
let (ident, _) = pyclass_ident_and_attrs(&item)?;
let class_meta = ClassItemMeta::from_nested(ident.clone(), fake_ident, attr.into_iter())?;
let class_name = class_meta.class_name()?;
let module_name = class_meta.module()?;
let base = class_meta.base()?;
let metaclass = class_meta.metaclass()?;
let unhashable = class_meta.unhashable()?;
let text_signature = class_meta.text_signature()?;
(
class_meta,
class_name,
module_name,
base,
metaclass,
unhashable,
text_signature,
)
};

Expand Down Expand Up @@ -661,7 +649,6 @@ pub(crate) fn impl_pyclass(attr: PunctuatedNestedMeta, item: Item) -> Result<Tok
metaclass,
unhashable,
attrs,
text_signature.as_deref(),
)?;

const ALLOWED_TRAVERSE_OPTS: &[&str] = &["manual"];
Expand Down
9 changes: 3 additions & 6 deletions crates/derive-impl/src/pymodule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::error::Diagnostic;
use crate::pystructseq::PyStructSequenceMeta;
use crate::util::{
ALL_ALLOWED_NAMES, AttrItemMeta, AttributeExt, ClassItemMeta, ContentItem, ContentItemInner,
ErrorVec, FunctionItemMeta, ItemMeta, ItemNursery, ModuleItemMeta, SimpleItemMeta, format_doc,
ErrorVec, ItemMeta, ItemNursery, ModuleItemMeta, SimpleItemMeta, format_doc,
infer_native_call_flags, iter_use_idents, pyclass_ident_and_attrs, text_signature,
};
use core::str::FromStr;
Expand Down Expand Up @@ -661,13 +661,10 @@ impl ModuleItem for FunctionItem {
let ident = &func.sig().ident;

let item_attr = args.attrs.remove(self.index());
let item_meta = FunctionItemMeta::from_attr(ident.clone(), &item_attr)?;
let item_meta = SimpleItemMeta::from_attr(ident.clone(), &item_attr)?;

let py_name = item_meta.simple_name()?;
let sig_doc = match item_meta.text_signature()? {
Some(sig) => Some(format!("{py_name}{sig}")),
None => text_signature(func.sig(), &py_name, None),
};
let sig_doc = text_signature(func.sig(), &py_name, None);

let module = args.module_name();
// TODO: doc must exist at least one of code or CPython
Expand Down
25 changes: 0 additions & 25 deletions crates/derive-impl/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,26 +315,6 @@ impl ItemMeta for SimpleItemMeta {
}
}

pub(crate) struct FunctionItemMeta(pub ItemMetaInner);

impl ItemMeta for FunctionItemMeta {
const ALLOWED_NAMES: &'static [&'static str] = &["name", "text_signature"];

fn from_inner(inner: ItemMetaInner) -> Self {
Self(inner)
}

fn inner(&self) -> &ItemMetaInner {
&self.0
}
}

impl FunctionItemMeta {
pub(crate) fn text_signature(&self) -> Result<Option<String>> {
self.inner()._optional_str("text_signature")
}
}

pub(crate) struct ModuleItemMeta(pub ItemMetaInner);

impl ItemMeta for ModuleItemMeta {
Expand Down Expand Up @@ -383,7 +363,6 @@ impl ItemMeta for ClassItemMeta {
"traverse",
"clear", // tp_clear
"payload",
"text_signature",
];

fn from_inner(inner: ItemMetaInner) -> Self {
Expand Down Expand Up @@ -441,10 +420,6 @@ impl ClassItemMeta {
self.inner()._optional_str("metaclass")
}

pub(crate) fn text_signature(&self) -> Result<Option<String>> {
self.inner()._optional_str("text_signature")
}

pub(crate) fn module(&self) -> Result<Option<String>> {
const KEY: &str = "module";
let inner = self.inner();
Expand Down
28 changes: 6 additions & 22 deletions crates/stdlib/src/pickle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,7 @@ mod _pickle {
}

#[pyattr]
#[pyclass(
module = "_pickle",
name = "Unpickler",
text_signature = "(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=())"
)]
#[pyclass(module = "_pickle", name = "Unpickler")]
#[derive(Debug, PyPayload)]
pub(super) struct PyUnpickler {
read_state: PyMutex<ReadState>,
Expand Down Expand Up @@ -1666,9 +1662,7 @@ mod _pickle {
})
}

#[pyfunction(
text_signature = "(data, /, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=())"
)]
#[pyfunction]
fn loads(args: LoadsArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
if args.data.downcastable::<PyStr>() {
return Err(vm.new_type_error("Can't load pickle from unicode string"));
Expand Down Expand Up @@ -1715,9 +1709,7 @@ mod _pickle {
buffers: OptionalArg<PyObjectRef>,
}

#[pyfunction(
text_signature = "(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=())"
)]
#[pyfunction]
fn load(args: LoadArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let peek = vm.get_attribute_opt(args.file.clone(), "peek")?;
let read = vm.get_attribute_opt(args.file.clone(), "read")?;
Expand Down Expand Up @@ -1939,11 +1931,7 @@ mod _pickle {
}

#[pyattr]
#[pyclass(
module = "_pickle",
name = "Pickler",
text_signature = "(file, protocol=None, fix_imports=True, buffer_callback=None)"
)]
#[pyclass(module = "_pickle", name = "Pickler")]
#[derive(Debug, PyPayload)]
pub(super) struct PyPickler {
out: PyMutex<Output>,
Expand Down Expand Up @@ -3789,9 +3777,7 @@ mod _pickle {
buffer_callback: OptionalArg<PyObjectRef>,
}

#[pyfunction(
text_signature = "(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)"
)]
#[pyfunction]
fn dump(args: DumpArgs, vm: &VirtualMachine) -> PyResult<()> {
let new_args = PicklerNewArgs {
file: args.file,
Expand Down Expand Up @@ -3831,9 +3817,7 @@ mod _pickle {
buffer_callback: OptionalArg<PyObjectRef>,
}

#[pyfunction(
text_signature = "(obj, protocol=None, *, fix_imports=True, buffer_callback=None)"
)]
#[pyfunction]
fn dumps(args: DumpsArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let new_args = PicklerNewArgs {
file: vm.ctx.none(),
Expand Down
7 changes: 1 addition & 6 deletions crates/vm/src/builtins/classmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ use crate::{
///
/// Class methods are different than C++ or Java static methods.
/// If you want those, see the staticmethod builtin.
#[pyclass(
module = false,
name = "classmethod",
text_signature = "(function, /)",
traverse
)]
#[pyclass(module = false, name = "classmethod", traverse)]
#[derive(Debug)]
pub struct PyClassMethod {
callable: PyMutex<PyObjectRef>,
Expand Down
7 changes: 1 addition & 6 deletions crates/vm/src/builtins/staticmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ use crate::{
types::{Callable, Constructor, GetDescriptor, Initializer, Representable},
};

#[pyclass(
module = false,
name = "staticmethod",
text_signature = "(function, /)",
traverse
)]
#[pyclass(module = false, name = "staticmethod", traverse)]
#[derive(Debug)]
pub struct PyStaticMethod {
pub callable: PyMutex<PyObjectRef>,
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/stdlib/_functools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mod _functools {
mycmp: PyObjectRef,
}

#[pyfunction(text_signature = "(mycmp)")]
#[pyfunction]
fn cmp_to_key(args: CmpToKeyArgs) -> PyKeyWrapper {
PyKeyWrapper {
cmp: args.mycmp,
Expand Down
4 changes: 2 additions & 2 deletions crates/vm/src/stdlib/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1457,7 +1457,7 @@ pub(super) mod _os {
}
}

#[pyfunction(text_signature = "(path, *, dir_fd=None, follow_symlinks=True)")]
#[pyfunction]
#[pyfunction(name = "fstat")]
fn stat(
path: OsPathOrFd<'_>,
Expand All @@ -1474,7 +1474,7 @@ pub(super) mod _os {
Ok(StatResultData::from_stat(&stat, vm).to_pyobject(vm))
}

#[pyfunction(text_signature = "(path, *, dir_fd=None)")]
#[pyfunction]
fn lstat(
path: OsPath,
dir_fd: DirFd<'_, { STAT_DIR_FD as usize }>,
Expand Down