GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `#[vm::pyclass]` / `#[vm::pymethod]` causes infinite loop in macro expansion · Issue #8097 · RustPython/RustPython

#[vm::pyclass] / #[vm::pymethod] causes infinite loop in macro expansion #8097

New issue
Copy link
New issue
Copy link
Open
Open
#[vm::pyclass] / #[vm::pymethod] causes infinite loop in macro expansion#8097
Copy link
Assignees
youknowonecopilot-swe-agent
Labels
C-bugSomething isn't workingSomething isn't working

Description

@mapf0000
mapf0000
opened on Jun 13, 2026
Issue body actions

Summary

cargo check hangs indefinitely — no error, just a rustc process pegged at 100% CPU —
when any #[pyclass] or #[pymethod] attribute is written with a path prefix such as
#[vm::pymethod].

Affected: rustpython-derive-impl 0.5.0 on rustc 1.96.0 / aarch64-apple-darwin

Root cause

attrs_to_content_items (crates/derive-impl/src/pyclass.rs ~line 1986) scans the
attribute list of each impl item with a Peekable iterator. peek() reads the current
element without advancing; only next() moves forward. The loop places iter.next()
after an early continue, so it is skipped whenever get_ident() returns None:

while let Some((_, attr)) = iter.peek() {
    let attr_name = if let Some(ident) = attr.get_ident() {
        ident.to_string()
    } else {
        continue;   // ← iter.next() skipped; same attribute peeked forever
    };
    // ...
    iter.next();    // ← never reached when get_ident() returns None
}

syn::Attribute::get_ident() only returns Some(name) for single-word attribute names
like pymethod. For a prefixed name like vm::pymethod it returns None, because
vm::pymethod is two path segments, not one. That None triggers continue, the
iterator never advances, and the loop spins forever.

Writing #[pymethod] (no prefix) works fine because get_ident() returns
Some("pymethod"), which hits the break in ALL_ALLOWED_NAMES.

Minimal reproduction

Cargo.toml:

[package]
name = "reproduce-pyclass-hang"
version = "0.1.0"
edition = "2021"

[dependencies]
rustpython-vm = { version = "0.5", default-features = false, features = ["compiler", "gc"] }

src/lib.rs:

use rustpython_vm as vm;

#[derive(Debug, vm::PyPayload)]
struct Item { value: i64 }

#[vm::pyclass]
impl Item {
    #[vm::pymethod]         // ← qualified path triggers the hang
    fn value(&self) -> i64 { self.value }
}

Run cargo check — rustc pegs a CPU core indefinitely with no output.

Fix

Move iter.next() outside the if let so it always fires, even when get_ident()
returns None. Unrecognised attribute paths are then simply skipped over.

// crates/derive-impl/src/pyclass.rs  (~line 1986)
while let Some((_, attr)) = iter.peek() {
    // Wrap in if-let so multi-segment paths (e.g. vm::pymethod) that return
    // None from get_ident() are skipped instead of looping forever.
    if let Some(ident) = attr.get_ident() {
        let attr_name = ident.to_string();
        if attr_name == "cfg" {
            cfgs.push(attr.clone());
        } else if ALL_ALLOWED_NAMES.contains(&attr_name.as_str()) {
            break;
        }
    }
    iter.next();
}
Reacted by Copilot

Activity

  1. mapf0000
    added
    C-bugSomething isn't workingSomething isn't working
    on Jun 13, 2026
  2. youknowone
    assigned
    Copilot
    and
    youknowone
    on Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • Copilot
  • @youknowone
    youknowone

Labels

C-bugSomething isn't workingSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.