(vm: &VirtualMachine, pattern: &ast::Pattern, star_ok: bool)
| 157 | } |
| 158 | |
| 159 | fn validate_pattern(vm: &VirtualMachine, pattern: &ast::Pattern, star_ok: bool) -> PyResult<()> { |
| 160 | match pattern { |
| 161 | ast::Pattern::MatchValue(value) => validate_pattern_match_value(vm, &value.value), |
| 162 | ast::Pattern::MatchSingleton(singleton) => match singleton.value { |
| 163 | ast::Singleton::None | ast::Singleton::True | ast::Singleton::False => Ok(()), |
| 164 | }, |
| 165 | ast::Pattern::MatchSequence(seq) => validate_patterns(vm, &seq.patterns, true), |
| 166 | ast::Pattern::MatchMapping(mapping) => { |
| 167 | if mapping.keys.len() != mapping.patterns.len() { |
| 168 | return Err(vm.new_value_error( |
| 169 | "MatchMapping doesn't have the same number of keys as patterns", |
| 170 | )); |
| 171 | } |
| 172 | if let Some(rest) = &mapping.rest { |
| 173 | validate_capture(vm, rest)?; |
| 174 | } |
| 175 | for key in &mapping.keys { |
| 176 | if let ast::Expr::BooleanLiteral(_) | ast::Expr::NoneLiteral(_) = key { |
| 177 | continue; |
| 178 | } |
| 179 | validate_pattern_match_value(vm, key)?; |
| 180 | } |
| 181 | validate_patterns(vm, &mapping.patterns, false) |
| 182 | } |
| 183 | ast::Pattern::MatchClass(match_class) => { |
| 184 | validate_expr(vm, &match_class.cls, ast::ExprContext::Load)?; |
| 185 | let mut cls = match_class.cls.as_ref(); |
| 186 | loop { |
| 187 | match cls { |
| 188 | ast::Expr::Name(_) => break, |
| 189 | ast::Expr::Attribute(attr) => { |
| 190 | cls = &attr.value; |
| 191 | } |
| 192 | _ => { |
| 193 | return Err(vm.new_value_error( |
| 194 | "MatchClass cls field can only contain Name or Attribute nodes.", |
| 195 | )); |
| 196 | } |
| 197 | } |
| 198 | } |
| 199 | for keyword in &match_class.arguments.keywords { |
| 200 | validate_name(vm, keyword.attr.id())?; |
| 201 | } |
| 202 | validate_patterns(vm, &match_class.arguments.patterns, false)?; |
| 203 | for keyword in &match_class.arguments.keywords { |
| 204 | validate_pattern(vm, &keyword.pattern, false)?; |
| 205 | } |
| 206 | Ok(()) |
| 207 | } |
| 208 | ast::Pattern::MatchStar(star) => { |
| 209 | if !star_ok { |
| 210 | return Err(vm.new_value_error("can't use MatchStar here")); |
| 211 | } |
| 212 | if let Some(name) = &star.name { |
| 213 | validate_capture(vm, name)?; |
| 214 | } |
| 215 | Ok(()) |
| 216 | } |
no test coverage detected