GeezerVison is showing github.com — [BREAKING CHANGE] Writing magic method names as full name by youknowone · Pull Request #5842 · RustPython/RustPython
[BREAKING CHANGE] Writing magic method names as full name
#5842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement . We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Uh oh!
There was an error while loading. Please reload this page.
Show file tree
Hide file tree
Changes from all commits
Commits
File filter
Filter by extension
.json
(1)
.rs
(89)
.toml
(2)
.txt
(3)
All 4 file types selected
Only manifest files
Viewed files
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Hide whitespace
Diff view
Hide whitespace
There are no files selected for viewing
Original file line number
Diff line number
Diff line change
Expand Up
@@ -45,7 +45,9 @@ SA_ONSTACK
stackdepth
stringlib
structseq
subparams
tok_oldval
tvars
unaryop
unparse
unparser
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -84,6 +84,7 @@ getrandom
getrecursionlimit
getrefcount
getsizeof
getswitchinterval
getweakrefcount
getweakrefs
getwindowsversion
Expand Down
Expand Up
@@ -167,13 +168,17 @@ pycs
pyexpat
PYTHONBREAKPOINT
PYTHONDEBUG
PYTHONDONTWRITEBYTECODE
PYTHONHASHSEED
PYTHONHOME
PYTHONINSPECT
PYTHONINTMAXSTRDIGITS
PYTHONNOUSERSITE
PYTHONOPTIMIZE
PYTHONPATH
PYTHONPATH
PYTHONSAFEPATH
PYTHONUNBUFFERED
PYTHONVERBOSE
PYTHONWARNDEFAULTENCODING
PYTHONWARNINGS
Expand Down
Expand Up
@@ -206,6 +211,7 @@ seennl
setattro
setcomp
setrecursionlimit
setswitchinterval
showwarnmsg
signum
slotnames
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -3,8 +3,10 @@ arrayvec
bidi
biguint
bindgen
bitand
bitflags
bitor
bitxor
bstr
byteorder
byteset
Expand All
@@ -15,6 +17,7 @@ cranelift
cstring
datelike
deserializer
deserializers
fdiv
flamescope
flate2
Expand All
@@ -31,6 +34,7 @@ keccak
lalrpop
lexopt
libc
libcall
libloading
libz
longlong
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -67,6 +67,8 @@
"GetSet",
"groupref",
"internable",
"jitted",
"jitting",
"lossily",
"makeunicodedata",
"miri",
Expand All
@@ -85,6 +87,7 @@
"pygetset",
"pyimpl",
"pylib",
"pymath",
"pymember",
"PyMethod",
"PyModule",
Expand Down
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,4 @@
// cspell:ignore uncomputed
use crate::atomic::{PyAtomic, Radium};
use crate::format::CharLen;
use crate::wtf8::{CodePoint, Wtf8, Wtf8Buf};
Expand Down
Expand Up
@@ -424,7 +425,7 @@ pub fn zfill(bytes: &[u8], width: usize) -> Vec<u8> {
}
}
/// Convert a string to ascii compatible, escaping unicodes into escape
/// Convert a string to ascii compatible, escaping unicode-s into escape
/// sequences.
pub fn to_ascii(value: &str) -> AsciiString {
let mut ascii = Vec::new();
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -2361,7 +2361,7 @@ impl Compiler<'_> {
// self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
// }
// // Check that the number of subpatterns is not absurd.
// // Check that the number of sub-patterns is not absurd.
// if size.saturating_sub(1) > (i32::MAX as usize) {
// panic!("too many sub-patterns in mapping pattern");
// // return self.compiler_error("too many sub-patterns in mapping pattern");
Expand Down
Expand Up
@@ -2469,41 +2469,41 @@ impl Compiler<'_> {
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.compile_pattern(alt, pc)?;
let nstores = pc.stores.len();
let n_stores = pc.stores.len();
if i == 0 {
// Save the captured names from the first alternative.
control = Some(pc.stores.clone());
} else {
let control_vec = control.as_ref().unwrap();
if nstores != control_vec.len() {
if n_stores != control_vec.len() {
return Err(self.error(CodegenErrorType::ConflictingNameBindPattern));
} else if nstores > 0 {
} else if n_stores > 0 {
// Check that the names occur in the same order.
for icontrol in (0..nstores ).rev() {
let name = &control_vec[icontrol ];
for i_control in (0..n_stores ).rev() {
let name = &control_vec[i_control ];
// Find the index of `name` in the current stores.
let istores =
let i_stores =
pc.stores.iter().position(|n| n == name).ok_or_else(|| {
self.error(CodegenErrorType::ConflictingNameBindPattern)
})?;
if icontrol != istores {
if i_control != i_stores {
// The orders differ; we must reorder.
assert!(istores < icontrol , "expected istores < icontrol ");
let rotations = istores + 1;
assert!(i_stores < i_control , "expected i_stores < i_control ");
let rotations = i_stores + 1;
// Rotate pc.stores: take a slice of the first `rotations` items...
let rotated = pc.stores[0..rotations].to_vec();
// Remove those elements.
for _ in 0..rotations {
pc.stores.remove(0);
}
// Insert the rotated slice at the appropriate index.
let insert_pos = icontrol - istores ;
let insert_pos = i_control - i_stores ;
for (j, elem) in rotated.into_iter().enumerate() {
pc.stores.insert(insert_pos + j, elem);
}
// Also perform the same rotation on the evaluation stack.
for _ in 0..(istores + 1) {
self.pattern_helper_rotate(icontrol + 1)?;
for _ in 0..(i_stores + 1) {
self.pattern_helper_rotate(i_control + 1)?;
}
}
}
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -93,7 +93,7 @@ pub fn compile(
source_path: &str,
opts: CompileOpts,
) -> Result<CodeObject, CompileError> {
// TODO: do this less hackily ; ruff's parser should translate a CRLF line
// TODO: do this less hacky ; ruff's parser should translate a CRLF line
// break in a multiline string into just an LF in the parsed value
#[cfg(windows)]
let source = &source.replace("\r\n", "\n");
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -752,6 +752,13 @@ where
let raw = item_meta.raw()?;
let sig_doc = text_signature(func.sig(), &py_name);
// Add #[allow(non_snake_case)] for setter methods like set___name__
let method_name = ident.to_string();
if method_name.starts_with("set_") && method_name.contains("__") {
let allow_attr: Attribute = parse_quote!(#[allow(non_snake_case)]);
args.attrs.push(allow_attr);
}
let doc = args.attrs.doc().map(|doc| format_doc(&sig_doc, &doc));
args.context.method_items.add_item(MethodNurseryItem {
py_name,
Expand Down
Expand Up
@@ -780,6 +787,13 @@ where
let item_meta = GetSetItemMeta::from_attr(ident.clone(), &item_attr)?;
let (py_name, kind) = item_meta.getset_name()?;
// Add #[allow(non_snake_case)] for setter methods
if matches!(kind, GetSetItemKind::Set) {
let allow_attr: Attribute = parse_quote!(#[allow(non_snake_case)]);
args.attrs.push(allow_attr);
}
args.context
.getset_items
.add_item(py_name, args.cfgs.to_vec(), kind, ident.clone())?;
Expand Down
Expand Up
@@ -934,6 +948,12 @@ where
_ => MemberKind::ObjectEx,
};
// Add #[allow(non_snake_case)] for setter methods
if matches!(member_item_kind, MemberItemKind::Set) {
let allow_attr: Attribute = parse_quote!(#[allow(non_snake_case)]);
args.attrs.push(allow_attr);
}
args.context.member_items.add_item(
py_name,
member_item_kind,
Expand Down
Expand Up
@@ -1208,7 +1228,7 @@ impl ToTokens for MemberNursery {
struct MethodItemMeta(ItemMetaInner);
impl ItemMeta for MethodItemMeta {
const ALLOWED_NAMES: &'static [&'static str] = &["name", "magic", " raw"];
const ALLOWED_NAMES: &'static [&'static str] = &["name", "raw"];
fn from_inner(inner: ItemMetaInner) -> Self {
Self(inner)
Expand All
@@ -1225,27 +1245,18 @@ impl MethodItemMeta {
fn method_name(&self) -> Result<String> {
let inner = self.inner();
let name = inner._optional_str("name")?;
let magic = inner._bool("magic")?;
if magic && name.is_some() {
bail_span!(
&inner.meta_ident,
"A #[{}] method cannot be magic and have a specified name, choose one.",
inner.meta_name()
);
}
Ok(if let Some(name) = name {
name
} else {
let name = inner.item_name();
if magic { format!("__{name}__") } else { name }
inner.item_name()
})
}
}
struct GetSetItemMeta(ItemMetaInner);
impl ItemMeta for GetSetItemMeta {
const ALLOWED_NAMES: &'static [&'static str] = &["name", "magic", " setter", "deleter"];
const ALLOWED_NAMES: &'static [&'static str] = &["name", "setter", "deleter"];
fn from_inner(inner: ItemMetaInner) -> Self {
Self(inner)
Expand All
@@ -1258,7 +1269,6 @@ impl ItemMeta for GetSetItemMeta {
impl GetSetItemMeta {
fn getset_name(&self) -> Result<(String, GetSetItemKind)> {
let inner = self.inner();
let magic = inner._bool("magic")?;
let kind = match (inner._bool("setter")?, inner._bool("deleter")?) {
(false, false) => GetSetItemKind::Get,
(true, false) => GetSetItemKind::Set,
Expand Down
Expand Up
@@ -1299,12 +1309,11 @@ impl GetSetItemMeta {
))
}
};
let name = match kind {
match kind {
GetSetItemKind::Get => sig_name,
GetSetItemKind::Set => extract_prefix_name("set_", "setter")?,
GetSetItemKind::Delete => extract_prefix_name("del_", "deleter")?,
};
if magic { format!("__{name}__") } else { name }
}
};
Ok((py_name, kind))
}
Expand Down
Expand Up
@@ -1353,7 +1362,7 @@ impl ItemMeta for SlotItemMeta {
impl SlotItemMeta {
fn slot_name(&self) -> Result<Ident> {
let inner = self.inner();
let slot_name = if let Some((_, meta)) = inner.meta_map.get("name") {
let method_name = if let Some((_, meta)) = inner.meta_map.get("name") {
match meta {
Meta::Path(path) => path.get_ident().cloned(),
_ => None,
Expand All
@@ -1367,19 +1376,32 @@ impl SlotItemMeta {
};
Some(name)
};
slot_name .ok_or_else(|| {
let method_name = method_name .ok_or_else(|| {
err_span!(
inner.meta_ident,
"#[pyslot] must be of the form #[pyslot] or #[pyslot(slot_name)]",
)
})
})?;
// Strip double underscores from slot names like __init__ -> init
let method_name_str = method_name.to_string();
let slot_name = if method_name_str.starts_with("__")
&& method_name_str.ends_with("__")
&& method_name_str.len() > 4
{
&method_name_str[2..method_name_str.len() - 2]
} else {
&method_name_str
};
Ok(proc_macro2::Ident::new(slot_name, slot_name.span()))
}
}
struct MemberItemMeta(ItemMetaInner);
impl ItemMeta for MemberItemMeta {
const ALLOWED_NAMES: &'static [&'static str] = &["magic", " type", "setter"];
const ALLOWED_NAMES: &'static [&'static str] = &["type", "setter"];
fn from_inner(inner: ItemMetaInner) -> Self {
Self(inner)
Expand Down
Expand Up
@@ -1416,7 +1438,6 @@ impl MemberItemMeta {
))
}
};
let magic = inner._bool("magic")?;
let kind = if inner._bool("setter")? {
MemberItemKind::Set
} else {
Expand All
@@ -1426,7 +1447,7 @@ impl MemberItemMeta {
MemberItemKind::Get => sig_name,
MemberItemKind::Set => extract_prefix_name("set_", "setter")?,
};
Ok((if magic { format!("__{ name}__") } else { name } , kind))
Ok((name, kind))
}
fn member_kind(&self) -> Result<Option<String>> {
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -64,17 +64,6 @@ pub fn derive_from_args(input: TokenStream) -> TokenStream {
/// but so does any object that implements `PyValue`.
/// Consider using `OptionalArg` for optional arguments.
/// #### Arguments
/// - `magic`: marks the method as a magic method: the method name is surrounded with double underscores.
/// ```rust, ignore
/// #[pyclass]
/// impl MyStruct {
/// // This will be called as the `__add__` method in Python.
/// #[pymethod(magic)]
/// fn add(&self, other: &Self) -> PyResult<i32> {
/// ...
/// }
/// }
/// ```
/// - `name`: the name of the method in Python,
/// by default it is the same as the Rust method, or surrounded by double underscores if magic is present.
/// This overrides `magic` and the default name and cannot be used with `magic` to prevent ambiguity.
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -7,3 +7,6 @@ edition = "2021"
rustpython-vm = { path = "../../vm", default-features = false }
[workspace]
[patch.crates-io]
radium = { version = "1.1.0", git = "https://github.com/youknowone/ferrilab", branch = "fix-nightly" }
Original file line number
Diff line number
Diff line change
Expand Up
@@ -9,3 +9,6 @@ rustpython-vm = { path = "../../vm", default-features = false, features = ["free
rustpython-pylib = { path = "../../pylib", default-features = false, features = ["freeze-stdlib"] }
[workspace]
[patch.crates-io]
radium = { version = "1.1.0", git = "https://github.com/youknowone/ferrilab", branch = "fix-nightly" }
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,4 @@
// cspell:ignore aheui
/// Setting up a project with a frozen stdlib can be done *either* by using `rustpython::InterpreterConfig` or `rustpython_vm::Interpreter::with_init`.
/// See each function for example.
///
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -56,7 +56,7 @@ fn parse_folder(path: &Path) -> std::io::Result<Vec<ParsedFile>> {
let parsed_file = parse_python_file(&path);
match &parsed_file.result {
Ok(_) => {}
Err(y) => error!("Erreur in file {path:?} {y:?}"),
Err(y) => error!("Error in file {path:?} {y:?}"),
}
res.push(parsed_file);
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -77,9 +77,9 @@ impl StackMachine {
}
pub fn run(&mut self, code: CodeObject) {
let mut oparg_state = OpArgState::default();
let mut op_arg_state = OpArgState::default();
let _ = code.instructions.iter().try_for_each(|&word| {
let (instruction, arg) = oparg_state .get(word);
let (instruction, arg) = op_arg_state .get(word);
self.process_instruction(instruction, arg, &code.constants, &code.names)
});
}
Expand Down
Loading
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.