| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | __all__ = () | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | import reprlib | 
					
						
							| 
									
										
										
										
											2020-11-10 06:20:52 -08:00
										 |  |  | from _thread import get_ident | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  | from . import format_helpers | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | # States for Future. | 
					
						
							|  |  |  | _PENDING = 'PENDING' | 
					
						
							|  |  |  | _CANCELLED = 'CANCELLED' | 
					
						
							|  |  |  | _FINISHED = 'FINISHED' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def isfuture(obj): | 
					
						
							|  |  |  |     """Check for a Future.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This returns True when obj is a Future instance or is advertising | 
					
						
							|  |  |  |     itself as duck-type compatible by setting _asyncio_future_blocking. | 
					
						
							|  |  |  |     See comment in Future for more details. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2016-11-07 16:07:30 -05:00
										 |  |  |     return (hasattr(obj.__class__, '_asyncio_future_blocking') and | 
					
						
							|  |  |  |             obj._asyncio_future_blocking is not None) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _format_callbacks(cb): | 
					
						
							|  |  |  |     """helper function for Future.__repr__""" | 
					
						
							|  |  |  |     size = len(cb) | 
					
						
							|  |  |  |     if not size: | 
					
						
							|  |  |  |         cb = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def format_cb(callback): | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  |         return format_helpers._format_callback_source(callback, ()) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if size == 1: | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |         cb = format_cb(cb[0][0]) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     elif size == 2: | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |         cb = '{}, {}'.format(format_cb(cb[0][0]), format_cb(cb[1][0])) | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     elif size > 2: | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |         cb = '{}, <{} more>, {}'.format(format_cb(cb[0][0]), | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |                                         size - 2, | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |                                         format_cb(cb[-1][0])) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |     return f'cb=[{cb}]' | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 06:20:52 -08:00
										 |  |  | # bpo-42183: _repr_running is needed for repr protection | 
					
						
							|  |  |  | # when a Future or Task result contains itself directly or indirectly. | 
					
						
							|  |  |  | # The logic is borrowed from @reprlib.recursive_repr decorator. | 
					
						
							|  |  |  | # Unfortunately, the direct decorator usage is impossible because of | 
					
						
							|  |  |  | # AttributeError: '_asyncio.Task' object has no attribute '__module__' error. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # After fixing this thing we can return to the decorator based approach. | 
					
						
							|  |  |  | _repr_running = set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  | def _future_repr_info(future): | 
					
						
							|  |  |  |     # (Future) -> str | 
					
						
							|  |  |  |     """helper function for Future.__repr__""" | 
					
						
							|  |  |  |     info = [future._state.lower()] | 
					
						
							|  |  |  |     if future._state == _FINISHED: | 
					
						
							|  |  |  |         if future._exception is not None: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             info.append(f'exception={future._exception!r}') | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-11-10 06:20:52 -08:00
										 |  |  |             key = id(future), get_ident() | 
					
						
							|  |  |  |             if key in _repr_running: | 
					
						
							|  |  |  |                 result = '...' | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 _repr_running.add(key) | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     # use reprlib to limit the length of the output, especially | 
					
						
							|  |  |  |                     # for very long strings | 
					
						
							|  |  |  |                     result = reprlib.repr(future._result) | 
					
						
							|  |  |  |                 finally: | 
					
						
							|  |  |  |                     _repr_running.discard(key) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             info.append(f'result={result}') | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     if future._callbacks: | 
					
						
							|  |  |  |         info.append(_format_callbacks(future._callbacks)) | 
					
						
							|  |  |  |     if future._source_traceback: | 
					
						
							|  |  |  |         frame = future._source_traceback[-1] | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         info.append(f'created at {frame[0]}:{frame[1]}') | 
					
						
							| 
									
										
										
										
											2016-10-28 12:52:37 -04:00
										 |  |  |     return info |