mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	[3.13] gh-104745: Limit starting a patcher more than once without stopping it (GH-126649) (#126772)
gh-104745: Limit starting a patcher more than once without stopping it (GH-126649)
Previously, this would cause an `AttributeError` if the patch stopped more than once after this, and would also disrupt the original patched object.
---------
(cherry picked from commit 1e40c5ba47)
Co-authored-by: Red4Ru <39802734+Red4Ru@users.noreply.github.com>
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
			
			
This commit is contained in:
		
							parent
							
								
									b03ba54efc
								
							
						
					
					
						commit
						e8dbe7ec57
					
				
					 3 changed files with 62 additions and 2 deletions
				
			
		|  | @ -1357,6 +1357,7 @@ def __init__( | |||
|         self.autospec = autospec | ||||
|         self.kwargs = kwargs | ||||
|         self.additional_patchers = [] | ||||
|         self.is_started = False | ||||
| 
 | ||||
| 
 | ||||
|     def copy(self): | ||||
|  | @ -1469,6 +1470,9 @@ def get_original(self): | |||
| 
 | ||||
|     def __enter__(self): | ||||
|         """Perform the patch.""" | ||||
|         if self.is_started: | ||||
|             raise RuntimeError("Patch is already started") | ||||
| 
 | ||||
|         new, spec, spec_set = self.new, self.spec, self.spec_set | ||||
|         autospec, kwargs = self.autospec, self.kwargs | ||||
|         new_callable = self.new_callable | ||||
|  | @ -1600,6 +1604,7 @@ def __enter__(self): | |||
|         self.temp_original = original | ||||
|         self.is_local = local | ||||
|         self._exit_stack = contextlib.ExitStack() | ||||
|         self.is_started = True | ||||
|         try: | ||||
|             setattr(self.target, self.attribute, new_attr) | ||||
|             if self.attribute_name is not None: | ||||
|  | @ -1619,6 +1624,9 @@ def __enter__(self): | |||
| 
 | ||||
|     def __exit__(self, *exc_info): | ||||
|         """Undo the patch.""" | ||||
|         if not self.is_started: | ||||
|             return | ||||
| 
 | ||||
|         if self.is_local and self.temp_original is not DEFAULT: | ||||
|             setattr(self.target, self.attribute, self.temp_original) | ||||
|         else: | ||||
|  | @ -1635,6 +1643,7 @@ def __exit__(self, *exc_info): | |||
|         del self.target | ||||
|         exit_stack = self._exit_stack | ||||
|         del self._exit_stack | ||||
|         self.is_started = False | ||||
|         return exit_stack.__exit__(*exc_info) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)