Check if an AST contains attribute assignments (e.g. self.x = 0).
| 2178 | |
| 2179 | |
| 2180 | class FindAttributeAssign(TraverserVisitor): |
| 2181 | """Check if an AST contains attribute assignments (e.g. self.x = 0).""" |
| 2182 | |
| 2183 | def __init__(self) -> None: |
| 2184 | self.lvalue = False |
| 2185 | self.found = False |
| 2186 | |
| 2187 | def visit_assignment_stmt(self, s: AssignmentStmt) -> None: |
| 2188 | self.lvalue = True |
| 2189 | for lv in s.lvalues: |
| 2190 | lv.accept(self) |
| 2191 | self.lvalue = False |
| 2192 | |
| 2193 | def visit_with_stmt(self, s: WithStmt) -> None: |
| 2194 | self.lvalue = True |
| 2195 | for lv in s.target: |
| 2196 | if lv is not None: |
| 2197 | lv.accept(self) |
| 2198 | self.lvalue = False |
| 2199 | s.body.accept(self) |
| 2200 | |
| 2201 | def visit_for_stmt(self, s: ForStmt) -> None: |
| 2202 | self.lvalue = True |
| 2203 | s.index.accept(self) |
| 2204 | self.lvalue = False |
| 2205 | s.body.accept(self) |
| 2206 | if s.else_body: |
| 2207 | s.else_body.accept(self) |
| 2208 | |
| 2209 | def visit_expression_stmt(self, s: ExpressionStmt) -> None: |
| 2210 | # No need to look inside these |
| 2211 | pass |
| 2212 | |
| 2213 | def visit_call_expr(self, e: CallExpr) -> None: |
| 2214 | # No need to look inside these |
| 2215 | pass |
| 2216 | |
| 2217 | def visit_index_expr(self, e: IndexExpr) -> None: |
| 2218 | # No need to look inside these |
| 2219 | pass |
| 2220 | |
| 2221 | def visit_member_expr(self, e: MemberExpr) -> None: |
| 2222 | if self.lvalue and isinstance(e.expr, NameExpr): |
| 2223 | self.found = True |
| 2224 | |
| 2225 | |
| 2226 | class FindYield(TraverserVisitor): |
no outgoing calls
no test coverage detected
searching dependent graphs…