{"record":{"id":"e62b7da35b883aee","repo":"PyO3/pyo3","slug":"set-may-only-be-specified-once","errorCode":null,"errorMessage":"`set` may only be specified once","messagePattern":"`set` may only be specified once","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"pyo3-macros-backend/src/pyclass.rs","lineNumber":407,"sourceCode":"\nimpl FieldPyO3Options {\n    fn take_pyo3_options(attrs: &mut Vec<syn::Attribute>) -> Result<Self> {\n        let mut options = FieldPyO3Options {\n            get: None,\n            set: None,\n            name: None,\n        };\n\n        for option in take_pyo3_options(attrs)? {\n            match option {\n                FieldPyO3Option::Get(kw) => {\n                    if options.get.replace(Annotated::Field(kw)).is_some() {\n                        return Err(syn::Error::new(kw.span(), UNIQUE_GET));\n                    }\n                }\n                FieldPyO3Option::Set(kw) => {\n                    if options.set.replace(Annotated::Field(kw)).is_some() {\n                        return Err(syn::Error::new(kw.span(), UNIQUE_SET));\n                    }\n                }\n                FieldPyO3Option::Name(name) => {\n                    if options.name.replace(name).is_some() {\n                        return Err(syn::Error::new(options.name.span(), UNIQUE_NAME));\n                    }\n                }\n            }\n        }\n\n        Ok(options)\n    }\n}\n\nfn get_class_python_name<'a>(cls: &'a Ident, args: &'a PyClassArgs) -> Cow<'a, Ident> {\n    args.options\n        .name\n        .as_ref()","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/PyO3/pyo3/blob/ac9b6899d348be4d54614d060dea53a645a12e36/pyo3-macros-backend/src/pyclass.rs#L389-L425","documentation":"The pyo3 attribute parser rejects a `set` option specified more than once on the same pyclass field. Like `get`, the option is stored once in an Option slot; a second occurrence triggers this syn::Error at the duplicate keyword's span.","triggerScenarios":"A field annotated with `#[pyo3(set, set)]` or otherwise receiving the `set` keyword twice through merged/concatenated attribute lists.","commonSituations":"Copy-paste duplication when adding setters, refactor conflicts, or code generators appending `set` to attributes that already contain it.","solutions":["Delete the duplicate `set` keyword, keeping a single occurrence per field","If combining attribute fragments, de-duplicate options first","Verify any macro wrappers don't add `set` unconditionally"],"exampleFix":"// before\n#[pyclass]\nstruct Point {\n    #[pyo3(set, set)]\n    x: i32,\n}\n// after\n#[pyclass]\nstruct Point {\n    #[pyo3(set)]\n    x: i32,\n}","handlingStrategy":"validation","validationCode":"// grep-style pre-commit check for duplicated pyo3 options\ncount_occurrences(\"#[pyo3(\") line, \"set\") <= 1 per attribute","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare `set` at most once per field","Review merge-conflict resolutions in attribute lists","Add a lint/CI grep for duplicated pyo3 keywords"],"tags":["rust","pyo3","macro","compile-time"],"backgroundTag":"duplicate-attribute-option","analyzedSha":"ac9b6899d348be4d54614d060dea53a645a12e36","analyzedAt":"2026-09-05T09:20:35.319Z","contentChangedAt":"2026-09-05T09:20:35.319Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}