python_ast/ast/tree/
parameters.rs

1use crate::Arguments;
2
3/// ParameterList is now just an alias to Arguments for compatibility.
4pub type ParameterList = Arguments;
5
6// It's fairly easy to break the automatic parsing of parameter structs, so we need to have fairly sophisticated
7// test coverage for the various types of
8#[cfg(test)]
9mod tests {
10    use test_log::test;
11
12    use crate::parse;
13    use crate::tree::statement::StatementType;
14    use crate::tree::Module;
15    use pyo3::PyResult;
16
17    fn setup(input: &str) -> PyResult<Module> {
18        let ast = parse(input, "__test__.py")?;
19        Ok(ast)
20    }
21
22    #[test]
23    fn no_parameters() {
24        let test_function = "def foo():\n    pass\n";
25        let module = setup(test_function).unwrap();
26
27        let function_def_statement = module.raw.body[0].clone();
28
29        if let StatementType::FunctionDef(f) = function_def_statement.statement {
30            assert_eq!(f.args.args.len(), 0)
31        } else {
32            panic!(
33                "Expected function definition, found {:#?}",
34                function_def_statement
35            );
36        }
37    }
38
39    #[test]
40    fn one_parameter() {
41        let test_function = "def foo1(a):\n    pass\n";
42        let module = setup(test_function).unwrap();
43
44        let function_def_statement = module.raw.body[0].clone();
45
46        if let StatementType::FunctionDef(f) = function_def_statement.statement {
47            assert_eq!(f.args.args.len(), 1)
48        } else {
49            panic!(
50                "Expected function definition, found {:#?}",
51                function_def_statement
52            );
53        }
54    }
55
56    #[test]
57    fn multiple_positional_parameter() {
58        let test_function = "def foo2(a, b, c):\n    pass\n";
59        let module = setup(test_function).unwrap();
60
61        let function_def_statement = module.raw.body[0].clone();
62
63        if let StatementType::FunctionDef(f) = function_def_statement.statement {
64            assert_eq!(f.args.args.len(), 3)
65        } else {
66            panic!(
67                "Expected function definition, found {:#?}",
68                function_def_statement
69            );
70        }
71    }
72
73    #[test]
74    fn vararg_only() {
75        let test_function = "def foo3(*a):\n    pass\n";
76        let module = setup(test_function).unwrap();
77
78        let function_def_statement = module.raw.body[0].clone();
79
80        if let StatementType::FunctionDef(f) = function_def_statement.statement {
81            assert_eq!(f.args.args.len(), 0);
82            assert_eq!(
83                f.args.vararg.as_ref().map(|p| &p.arg),
84                Some(&"a".to_string())
85            );
86        } else {
87            panic!(
88                "Expected function definition, found {:#?}",
89                function_def_statement
90            );
91        }
92    }
93
94    #[test]
95    fn positional_and_vararg() {
96        let test_function = "def foo4(a, *b):\n    pass\n";
97        let module = setup(test_function).unwrap();
98
99        let function_def_statement = module.raw.body[0].clone();
100
101        if let StatementType::FunctionDef(f) = function_def_statement.statement {
102            assert_eq!(f.args.args.len(), 1);
103            assert_eq!(
104                f.args.vararg.as_ref().map(|p| &p.arg),
105                Some(&"b".to_string())
106            );
107        } else {
108            panic!(
109                "Expected function definition, found {:#?}",
110                function_def_statement
111            );
112        }
113    }
114
115    #[test]
116    fn positional_and_vararg_and_kw() {
117        let test_function = "def foo5(a, *b, c=7):\n    pass\n";
118        let module = setup(test_function).unwrap();
119
120        let function_def_statement = module.raw.body[0].clone();
121
122        if let StatementType::FunctionDef(f) = function_def_statement.statement {
123            assert_eq!(f.args.args.len(), 1);
124            assert_eq!(
125                f.args.vararg.as_ref().map(|p| &p.arg),
126                Some(&"b".to_string())
127            );
128            assert_eq!(f.args.kwonlyargs.len(), 1);
129            assert_eq!(f.args.kwonlyargs[0].arg, "c".to_string());
130        } else {
131            panic!(
132                "Expected function definition, found {:#?}",
133                function_def_statement
134            );
135        }
136    }
137
138    #[test]
139    fn positional_and_kw() {
140        let test_function = "def foo6(a, c=7):\n    pass\n";
141        let module = setup(test_function).unwrap();
142
143        println!("module: {:#?}", module);
144        let function_def_statement = module.raw.body[0].clone();
145
146        if let StatementType::FunctionDef(f) = function_def_statement.statement {
147            println!("{:?}", f);
148            assert_eq!(f.args.args.len(), 2);
149            assert_eq!(f.args.defaults.len(), 1);
150            //assert_eq!(f.args.defaults[0], Arg::Constant(crate::Constant(Literal::parse(String::from("7")).unwrap())));
151        } else {
152            panic!(
153                "Expected function definition, found {:#?}",
154                function_def_statement
155            );
156        }
157    }
158
159    #[test]
160    fn default_only() {
161        let test_function = "def foo7(a=7):\n    pass\n";
162        let module = setup(test_function).unwrap();
163
164        let function_def_statement = module.raw.body[0].clone();
165
166        if let StatementType::FunctionDef(f) = function_def_statement.statement {
167            assert_eq!(f.args.args.len(), 1);
168            assert_eq!(f.args.defaults.len(), 1);
169            //assert_eq!(f.args.defaults[0], Arg::Constant(crate::Constant(Literal::parse(String::from("7")).unwrap())));
170        } else {
171            panic!(
172                "Expected function definition, found {:#?}",
173                function_def_statement
174            );
175        }
176    }
177
178    #[test]
179    fn kwargs_only() {
180        let test_function = "def foo8(**a):\n    pass\n";
181        let module = setup(test_function).unwrap();
182
183        let function_def_statement = module.raw.body[0].clone();
184
185        if let StatementType::FunctionDef(f) = function_def_statement.statement {
186            assert_eq!(f.args.args.len(), 0);
187            assert_eq!(
188                f.args.kwarg.as_ref().map(|p| &p.arg),
189                Some(&"a".to_string())
190            );
191        } else {
192            panic!(
193                "Expected function definition, found {:#?}",
194                function_def_statement
195            );
196        }
197    }
198
199    #[test]
200    fn named_and_positional() {
201        let test_function = "def foo9(a, *, b):\n    pass\n";
202        let module = setup(test_function).unwrap();
203
204        let function_def_statement = module.raw.body[0].clone();
205
206        if let StatementType::FunctionDef(f) = function_def_statement.statement {
207            assert_eq!(f.args.args.len(), 1);
208            assert_eq!(f.args.vararg, None);
209            assert_eq!(f.args.kwonlyargs.len(), 1);
210            assert_eq!(f.args.kwonlyargs[0].arg, "b".to_string());
211        } else {
212            panic!(
213                "Expected function definition, found {:#?}",
214                function_def_statement
215            );
216        }
217    }
218}