|
1 | | -use crate::model::{Argument, Class, Const, Function, Module, VariableLengthArgument}; |
| 1 | +use crate::model::{Argument, Arguments, Class, Const, Function, Module, VariableLengthArgument}; |
2 | 2 | use std::collections::{BTreeSet, HashMap}; |
3 | 3 | use std::path::{Path, PathBuf}; |
4 | 4 |
|
@@ -43,6 +43,31 @@ fn module_stubs(module: &Module) -> String { |
43 | 43 | for function in &module.functions { |
44 | 44 | elements.push(function_stubs(function, &mut modules_to_import)); |
45 | 45 | } |
| 46 | + |
| 47 | + // We generate a __getattr__ method to tag incomplete stubs |
| 48 | + // See https://typing.python.org/en/latest/guides/writing_stubs.html#incomplete-stubs |
| 49 | + if module.incomplete && !module.functions.iter().any(|f| f.name == "__getattr__") { |
| 50 | + elements.push(function_stubs( |
| 51 | + &Function { |
| 52 | + name: "__getattr__".into(), |
| 53 | + decorators: Vec::new(), |
| 54 | + arguments: Arguments { |
| 55 | + positional_only_arguments: Vec::new(), |
| 56 | + arguments: vec![Argument { |
| 57 | + name: "name".to_string(), |
| 58 | + default_value: None, |
| 59 | + annotation: Some("str".into()), |
| 60 | + }], |
| 61 | + vararg: None, |
| 62 | + keyword_only_arguments: Vec::new(), |
| 63 | + kwarg: None, |
| 64 | + }, |
| 65 | + returns: Some("_typeshed.Incomplete".into()), |
| 66 | + }, |
| 67 | + &mut modules_to_import, |
| 68 | + )); |
| 69 | + } |
| 70 | + |
46 | 71 | let mut final_elements = Vec::new(); |
47 | 72 | for module_to_import in &modules_to_import { |
48 | 73 | final_elements.push(format!("import {module_to_import}")); |
|
0 commit comments