mirror of
				https://github.com/astral-sh/ruff.git
				synced 2025-10-31 03:54:57 +00:00 
			
		
		
		
	[SIM115] Allow open followed by close (#7916)
				
					
				
			This commit is contained in:
		
							parent
							
								
									7a072cc2ea
								
							
						
					
					
						commit
						f670f9b22c
					
				
					 2 changed files with 33 additions and 0 deletions
				
			
		|  | @ -42,3 +42,7 @@ with contextlib.ExitStack(): | ||||||
| with contextlib.ExitStack() as exit_stack: | with contextlib.ExitStack() as exit_stack: | ||||||
|     exit_stack_ = exit_stack |     exit_stack_ = exit_stack | ||||||
|     f = exit_stack_.enter_context(open("filename")) |     f = exit_stack_.enter_context(open("filename")) | ||||||
|  | 
 | ||||||
|  | # OK (quick one-liner to clear file contents) | ||||||
|  | open("filename", "w").close() | ||||||
|  | pathlib.Path("filename").open("w").close() | ||||||
|  |  | ||||||
|  | @ -127,12 +127,41 @@ fn is_open(checker: &mut Checker, func: &Expr) -> bool { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /// Return `true` if the current expression is followed by a `close` call.
 | ||||||
|  | fn is_closed(semantic: &SemanticModel) -> bool { | ||||||
|  |     let Some(expr) = semantic.current_expression_grandparent() else { | ||||||
|  |         return false; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     let Expr::Call(ast::ExprCall { | ||||||
|  |         func, arguments, .. | ||||||
|  |     }) = expr | ||||||
|  |     else { | ||||||
|  |         return false; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     if !arguments.is_empty() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() else { | ||||||
|  |         return false; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     attr.as_str() == "close" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// SIM115
 | /// SIM115
 | ||||||
| pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) { | pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) { | ||||||
|     if !is_open(checker, func) { |     if !is_open(checker, func) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Ex) `open("foo.txt").close()`
 | ||||||
|  |     if is_closed(checker.semantic()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // Ex) `with open("foo.txt") as f: ...`
 |     // Ex) `with open("foo.txt") as f: ...`
 | ||||||
|     if checker.semantic().current_statement().is_with_stmt() { |     if checker.semantic().current_statement().is_with_stmt() { | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Harutaka Kawamura
						Harutaka Kawamura