mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	[3.9] bpo-42517: [Enum] deprecate private name members (GH-23722) (GH-23748)
private names will raise a DeprecationWarning; in 3.10 they will become normal attributes
This commit is contained in:
		
							parent
							
								
									6b2ed38509
								
							
						
					
					
						commit
						aba12b67c1
					
				
					 4 changed files with 51 additions and 0 deletions
				
			
		|  | @ -1121,6 +1121,15 @@ and raise an error if the two do not match:: | |||
|     In Python 2 code the :attr:`_order_` attribute is necessary as definition | ||||
|     order is lost before it can be recorded. | ||||
| 
 | ||||
| 
 | ||||
| _Private__names | ||||
| """"""""""""""" | ||||
| 
 | ||||
| Private names will be normal attributes in Python 3.10 instead of either an error | ||||
| or a member (depending on if the name ends with an underscore). Using these names | ||||
| in 3.9 will issue a :exc:`DeprecationWarning`. | ||||
| 
 | ||||
| 
 | ||||
| ``Enum`` member type | ||||
| """""""""""""""""""" | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										22
									
								
								Lib/enum.py
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								Lib/enum.py
									
										
									
									
									
								
							|  | @ -41,6 +41,19 @@ def _is_sunder(name): | |||
|             name[-2:-1] != '_' | ||||
|             ) | ||||
| 
 | ||||
| def _is_private(cls_name, name): | ||||
|     # do not use `re` as `re` imports `enum` | ||||
|     pattern = '_%s__' % (cls_name, ) | ||||
|     if ( | ||||
|             len(name) >= 5 | ||||
|             and name.startswith(pattern) | ||||
|             and name[len(pattern)] != '_' | ||||
|             and (name[-1] != '_' or name[-2] != '_') | ||||
|         ): | ||||
|         return True | ||||
|     else: | ||||
|         return False | ||||
| 
 | ||||
| def _make_class_unpicklable(cls): | ||||
|     """ | ||||
|     Make the given class un-picklable. | ||||
|  | @ -81,6 +94,14 @@ def __setitem__(self, key, value): | |||
| 
 | ||||
|         Single underscore (sunder) names are reserved. | ||||
|         """ | ||||
|         if _is_private(self._cls_name, key): | ||||
|             import warnings | ||||
|             warnings.warn( | ||||
|                     "private variables, such as %r, will be normal attributes in 3.10" | ||||
|                         % (key, ), | ||||
|                     DeprecationWarning, | ||||
|                     stacklevel=2, | ||||
|                     ) | ||||
|         if _is_sunder(key): | ||||
|             if key not in ( | ||||
|                     '_order_', '_create_pseudo_member_', | ||||
|  | @ -146,6 +167,7 @@ def __prepare__(metacls, cls, bases): | |||
|         metacls._check_for_existing_members(cls, bases) | ||||
|         # create the namespace dict | ||||
|         enum_dict = _EnumDict() | ||||
|         enum_dict._cls_name = cls | ||||
|         # inherit previous flags and _generate_next_value_ function | ||||
|         member_type, first_enum = metacls._get_mixins_(cls, bases) | ||||
|         if first_enum is not None: | ||||
|  |  | |||
|  | @ -1147,6 +1147,7 @@ def test_multiple_mixin_mro(self): | |||
|         class auto_enum(type(Enum)): | ||||
|             def __new__(metacls, cls, bases, classdict): | ||||
|                 temp = type(classdict)() | ||||
|                 temp._cls_name = cls | ||||
|                 names = set(classdict._member_names) | ||||
|                 i = 0 | ||||
|                 for k in classdict._member_names: | ||||
|  | @ -2049,6 +2050,23 @@ def test_empty_globals(self): | |||
|         exec(code, global_ns, local_ls) | ||||
| 
 | ||||
| 
 | ||||
|     @unittest.skipUnless( | ||||
|             sys.version_info[:2] == (3, 9), | ||||
|             'private variables are now normal attributes', | ||||
|             ) | ||||
|     def test_warning_for_private_variables(self): | ||||
|         with self.assertWarns(DeprecationWarning): | ||||
|             class Private(Enum): | ||||
|                 __corporal = 'Radar' | ||||
|         self.assertEqual(Private._Private__corporal.value, 'Radar') | ||||
|         try: | ||||
|             with self.assertWarns(DeprecationWarning): | ||||
|                 class Private(Enum): | ||||
|                     __major_ = 'Hoolihan' | ||||
|         except ValueError: | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| class TestOrder(unittest.TestCase): | ||||
| 
 | ||||
|     def test_same_members(self): | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| Enum: private names will raise a DeprecationWarning; in 3.10 they will | ||||
| become normal attributes | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)