Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
215 changes: 97 additions & 118 deletions Lib/test/test_typing.py

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions compiler/codegen/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct Compiler<'src> {
ctx: CompileContext,
class_name: Option<String>,
opts: CompileOpts,
in_annotation: bool,
}

enum DoneWithFuture {
Expand Down Expand Up @@ -335,6 +336,7 @@ impl<'src> Compiler<'src> {
},
class_name: None,
opts,
in_annotation: false,
}
}
}
Expand Down Expand Up @@ -2897,7 +2899,11 @@ impl Compiler<'_> {
.into(),
});
} else {
self.compile_expression(annotation)?;
let was_in_annotation = self.in_annotation;
self.in_annotation = true;
let result = self.compile_expression(annotation);
self.in_annotation = was_in_annotation;
result?;
}
Ok(())
}
Expand Down Expand Up @@ -3504,8 +3510,15 @@ impl Compiler<'_> {
Self::contains_await(elt),
)?;
}
Expr::Starred(_) => {
return Err(self.error(CodegenErrorType::InvalidStarExpr));
Expr::Starred(ExprStarred { value, .. }) => {
if self.in_annotation {
// In annotation context, starred expressions are allowed (PEP 646)
// For now, just compile the inner value without wrapping with Unpack
// This is a temporary solution until we figure out how to properly import typing
self.compile_expression(value)?;
} else {
return Err(self.error(CodegenErrorType::InvalidStarExpr));
}
}
Expr::If(ExprIf {
test, body, orelse, ..
Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/asyncgenerator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl PyAsyncGen {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl PyDict {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Constructor for PyEnumerate {
impl PyEnumerate {
#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
56 changes: 27 additions & 29 deletions vm/src/builtins/genericalias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ impl Constructor for PyGenericAlias {
return Err(vm.new_type_error("GenericAlias() takes no keyword arguments"));
}
let (origin, arguments): (_, PyObjectRef) = args.bind(vm)?;
PyGenericAlias::new(origin, arguments, vm)
let args = if let Ok(tuple) = arguments.try_to_ref::<PyTuple>(vm) {
tuple.to_owned()
} else {
PyTuple::new_ref(vec![arguments], &vm.ctx)
};
PyGenericAlias::new(origin, args, false, vm)
.into_ref_with_type(vm, cls)
.map(Into::into)
}
Expand All @@ -84,35 +89,24 @@ impl Constructor for PyGenericAlias {
flags(BASETYPE)
)]
impl PyGenericAlias {
pub fn new(origin: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> Self {
let args = if let Ok(tuple) = args.try_to_ref::<PyTuple>(vm) {
tuple.to_owned()
} else {
PyTuple::new_ref(vec![args], &vm.ctx)
};

pub fn new(origin: PyTypeRef, args: PyTupleRef, starred: bool, vm: &VirtualMachine) -> Self {
let parameters = make_parameters(&args, vm);
Self {
origin,
args,
parameters,
starred: false, // default to false
starred,
}
}

fn with_tuple_args(
origin: PyTypeRef,
args: PyTupleRef,
starred: bool,
vm: &VirtualMachine,
) -> Self {
let parameters = make_parameters(&args, vm);
Self {
origin,
args,
parameters,
starred,
}
/// Create a GenericAlias from an origin and PyObjectRef arguments (helper for compatibility)
pub fn from_args(origin: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> Self {
let args = if let Ok(tuple) = args.try_to_ref::<PyTuple>(vm) {
tuple.to_owned()
} else {
PyTuple::new_ref(vec![args], &vm.ctx)
};
Self::new(origin, args, false, vm)
}

fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
Expand Down Expand Up @@ -146,7 +140,7 @@ impl PyGenericAlias {
}
}

Ok(format!(
let repr_str = format!(
"{}[{}]",
repr_item(self.origin.clone().into(), vm)?,
if self.args.is_empty() {
Expand All @@ -158,7 +152,14 @@ impl PyGenericAlias {
.collect::<PyResult<Vec<_>>>()?
.join(", ")
}
))
);

// Add * prefix if this is a starred GenericAlias
Ok(if self.starred {
format!("*{repr_str}")
} else {
repr_str
})
}

#[pygetset]
Expand Down Expand Up @@ -200,10 +201,7 @@ impl PyGenericAlias {
vm,
)?;

Ok(
PyGenericAlias::new(zelf.origin.clone(), new_args.to_pyobject(vm), vm)
.into_pyobject(vm),
)
Ok(PyGenericAlias::new(zelf.origin.clone(), new_args, false, vm).into_pyobject(vm))
}

#[pymethod]
Expand Down Expand Up @@ -598,7 +596,7 @@ impl Iterable for PyGenericAlias {
// CPython's ga_iter creates an iterator that yields one starred GenericAlias
// we don't have gaiterobject yet

let starred_alias = PyGenericAlias::with_tuple_args(
let starred_alias = PyGenericAlias::new(
zelf.origin.clone(),
zelf.args.clone(),
true, // starred
Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl PyList {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/mappingproxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl PyMappingProxy {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}

#[pymethod]
Expand Down
4 changes: 2 additions & 2 deletions vm/src/builtins/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ impl PySet {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down Expand Up @@ -1134,7 +1134,7 @@ impl PyFrozenSet {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl PyTuple {

#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/builtins/weakref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl Constructor for PyWeak {
impl PyWeak {
#[pyclassmethod]
fn __class_getitem__(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/protocol/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ impl PyObject {
} else {
if self.class().fast_issubclass(vm.ctx.types.type_type) {
if self.is(vm.ctx.types.type_type) {
return PyGenericAlias::new(self.class().to_owned(), needle, vm)
return PyGenericAlias::from_args(self.class().to_owned(), needle, vm)
.to_pyresult(vm);
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/stdlib/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ mod _collections {
args: PyObjectRef,
vm: &VirtualMachine,
) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
2 changes: 1 addition & 1 deletion vm/src/stdlib/itertools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ mod decl {
args: PyObjectRef,
vm: &VirtualMachine,
) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}

#[pymethod]
Expand Down
2 changes: 1 addition & 1 deletion vm/src/stdlib/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ pub(super) mod _os {
args: PyObjectRef,
vm: &VirtualMachine,
) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down
4 changes: 2 additions & 2 deletions vm/src/stdlib/sre.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ mod _sre {
args: PyObjectRef,
vm: &VirtualMachine,
) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down Expand Up @@ -816,7 +816,7 @@ mod _sre {
args: PyObjectRef,
vm: &VirtualMachine,
) -> PyGenericAlias {
PyGenericAlias::new(cls, args, vm)
PyGenericAlias::from_args(cls, args, vm)
}
}

Expand Down