{"record":{"id":"23051454f589ce89","repo":"PyO3/pyo3","slug":"useless-get-the-struct-is-already-annotated-wi","errorCode":null,"errorMessage":"useless `get` - the struct is already annotated with `get_all`","messagePattern":"useless `get` - the struct is already annotated with `get_all`","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"pyo3-macros-backend/src/pyclass.rs","lineNumber":332,"sourceCode":"            let mut results = Vec::new();\n\n            if let Some(attr) = args.options.set_all {\n                results.push(Err(syn::Error::new_spanned(attr, UNIT_SET)));\n            };\n            if let Some(attr) = args.options.get_all {\n                results.push(Err(syn::Error::new_spanned(attr, UNIT_GET)));\n            };\n\n            results\n        }\n    }\n    .into_iter()\n    .try_combine_syn_errors()?;\n\n    if let Some(attr) = args.options.get_all {\n        for (_, FieldPyO3Options { get, .. }) in &mut field_options {\n            if let Some(old_get) = get.replace(Annotated::Struct(attr)) {\n                return Err(syn::Error::new(old_get.span(), DUPE_GET));\n            }\n        }\n    }\n\n    if let Some(attr) = args.options.set_all {\n        for (_, FieldPyO3Options { set, .. }) in &mut field_options {\n            if let Some(old_set) = set.replace(Annotated::Struct(attr)) {\n                return Err(syn::Error::new(old_set.span(), DUPE_SET));\n            }\n        }\n    }\n\n    impl_class(&class.ident, &args, doc, field_options, methods_type, ctx)\n}\n\nenum Annotated<X, Y> {\n    Field(X),\n    Struct(Y),","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/PyO3/pyo3/blob/ac9b6899d348be4d54614d060dea53a645a12e36/pyo3-macros-backend/src/pyclass.rs#L314-L350","documentation":"When a #[pyclass] is annotated with get_all, every field is automatically exposed as a getter; a per-field #[pyo3(get)] is then redundant and the macro (build_py_class) reports DUPE_GET at the field's span.","triggerScenarios":"Combining #[pyclass(get_all)] with #[pyo3(get)] on one or more fields of the struct.","commonSituations":"Refactoring a class to get_all without removing old per-field get annotations; copy-pasting field attributes from another struct.","solutions":["Remove the per-field #[pyo3(get)] attributes on fields where get_all already applies","Remove get_all if only some fields should be getters","Convert fields that need different visibility handling to explicit per-field annotations and drop get_all"],"exampleFix":"// before\n#[pyclass(get_all)]\nstruct Point {\n    #[pyo3(get)]\n    x: f64,\n    y: f64,\n}\n// after\n#[pyclass(get_all)]\nstruct Point {\n    x: f64,\n    y: f64,\n}","handlingStrategy":"validation","validationCode":"# CI lint: flag #[pyo3(get)] inside structs whose pyclass has get_all\n# grep -A2 'pyclass(.*get_all' -r src/ | grep 'pyo3(get)' && exit 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When introducing get_all, remove all per-field #[pyo3(get)] in the same change","Keep one visibility convention per struct: all-fields or per-field, not both","Run cargo check/clippy on PRs to catch macro errors early"],"tags":["rust","pyo3-macros","pyclass","duplicate-attribute"],"backgroundTag":"duplicate-attribute","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"}