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        let function_def_statement = module.raw.body[0].clone();
144
145        if let StatementType::FunctionDef(f) = function_def_statement.statement {
146            assert_eq!(f.args.args.len(), 2);
147            assert_eq!(f.args.defaults.len(), 1);
148            //assert_eq!(f.args.defaults[0], Arg::Constant(crate::Constant(Literal::parse(String::from("7")).unwrap())));
149        } else {
150            panic!(
151                "Expected function definition, found {:#?}",
152                function_def_statement
153            );
154        }
155    }
156
157    #[test]
158    fn default_only() {
159        let test_function = "def foo7(a=7):\n    pass\n";
160        let module = setup(test_function).unwrap();
161
162        let function_def_statement = module.raw.body[0].clone();
163
164        if let StatementType::FunctionDef(f) = function_def_statement.statement {
165            assert_eq!(f.args.args.len(), 1);
166            assert_eq!(f.args.defaults.len(), 1);
167            //assert_eq!(f.args.defaults[0], Arg::Constant(crate::Constant(Literal::parse(String::from("7")).unwrap())));
168        } else {
169            panic!(
170                "Expected function definition, found {:#?}",
171                function_def_statement
172            );
173        }
174    }
175
176    #[test]
177    fn kwargs_only() {
178        let test_function = "def foo8(**a):\n    pass\n";
179        let module = setup(test_function).unwrap();
180
181        let function_def_statement = module.raw.body[0].clone();
182
183        if let StatementType::FunctionDef(f) = function_def_statement.statement {
184            assert_eq!(f.args.args.len(), 0);
185            assert_eq!(
186                f.args.kwarg.as_ref().map(|p| &p.arg),
187                Some(&"a".to_string())
188            );
189        } else {
190            panic!(
191                "Expected function definition, found {:#?}",
192                function_def_statement
193            );
194        }
195    }
196
197    #[test]
198    fn named_and_positional() {
199        let test_function = "def foo9(a, *, b):\n    pass\n";
200        let module = setup(test_function).unwrap();
201
202        let function_def_statement = module.raw.body[0].clone();
203
204        if let StatementType::FunctionDef(f) = function_def_statement.statement {
205            assert_eq!(f.args.args.len(), 1);
206            assert_eq!(f.args.vararg, None);
207            assert_eq!(f.args.kwonlyargs.len(), 1);
208            assert_eq!(f.args.kwonlyargs[0].arg, "b".to_string());
209        } else {
210            panic!(
211                "Expected function definition, found {:#?}",
212                function_def_statement
213            );
214        }
215    }
216}