mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-32226: Implementation of PEP 560 (core components) (#4732)
This part of the PEP implementation adds support for __mro_entries__ and __class_getitem__ by updating __build_class__ and PyObject_GetItem.
This commit is contained in:
		
							parent
							
								
									15a8728415
								
							
						
					
					
						commit
						2b5fd1e9ca
					
				
					 7 changed files with 492 additions and 5 deletions
				
			
		
							
								
								
									
										28
									
								
								Lib/types.py
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								Lib/types.py
									
										
									
									
									
								
							|  | @ -60,10 +60,34 @@ def _m(self): pass | |||
| # Provide a PEP 3115 compliant mechanism for class creation | ||||
| def new_class(name, bases=(), kwds=None, exec_body=None): | ||||
|     """Create a class object dynamically using the appropriate metaclass.""" | ||||
|     meta, ns, kwds = prepare_class(name, bases, kwds) | ||||
|     resolved_bases = resolve_bases(bases) | ||||
|     meta, ns, kwds = prepare_class(name, resolved_bases, kwds) | ||||
|     if exec_body is not None: | ||||
|         exec_body(ns) | ||||
|     return meta(name, bases, ns, **kwds) | ||||
|     if resolved_bases is not bases: | ||||
|         ns['__orig_bases__'] = bases | ||||
|     return meta(name, resolved_bases, ns, **kwds) | ||||
| 
 | ||||
| def resolve_bases(bases): | ||||
|     """Resolve MRO entries dynamically as specified by PEP 560.""" | ||||
|     new_bases = list(bases) | ||||
|     updated = False | ||||
|     shift = 0 | ||||
|     for i, base in enumerate(bases): | ||||
|         if isinstance(base, type): | ||||
|             continue | ||||
|         if not hasattr(base, "__mro_entries__"): | ||||
|             continue | ||||
|         new_base = base.__mro_entries__(bases) | ||||
|         updated = True | ||||
|         if not isinstance(new_base, tuple): | ||||
|             raise TypeError("__mro_entries__ must return a tuple") | ||||
|         else: | ||||
|             new_bases[i+shift:i+shift+1] = new_base | ||||
|             shift += len(new_base) - 1 | ||||
|     if not updated: | ||||
|         return bases | ||||
|     return tuple(new_bases) | ||||
| 
 | ||||
| def prepare_class(name, bases=(), kwds=None): | ||||
|     """Call the __prepare__ method of the appropriate metaclass. | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ivan Levkivskyi
						Ivan Levkivskyi