| 
									
										
										
										
											2023-02-18 16:29:22 -05:00
										 |  |  | # from more_itertools 9.0 | 
					
						
							|  |  |  | def only(iterable, default=None, too_long=None): | 
					
						
							|  |  |  |     """If *iterable* has only one item, return it.
 | 
					
						
							|  |  |  |     If it has zero items, return *default*. | 
					
						
							|  |  |  |     If it has more than one item, raise the exception given by *too_long*, | 
					
						
							|  |  |  |     which is ``ValueError`` by default. | 
					
						
							|  |  |  |     >>> only([], default='missing') | 
					
						
							|  |  |  |     'missing' | 
					
						
							|  |  |  |     >>> only([1]) | 
					
						
							|  |  |  |     1 | 
					
						
							|  |  |  |     >>> only([1, 2])  # doctest: +IGNORE_EXCEPTION_DETAIL | 
					
						
							|  |  |  |     Traceback (most recent call last): | 
					
						
							|  |  |  |     ... | 
					
						
							|  |  |  |     ValueError: Expected exactly one item in iterable, but got 1, 2, | 
					
						
							|  |  |  |      and perhaps more.' | 
					
						
							|  |  |  |     >>> only([1, 2], too_long=TypeError)  # doctest: +IGNORE_EXCEPTION_DETAIL | 
					
						
							|  |  |  |     Traceback (most recent call last): | 
					
						
							|  |  |  |     ... | 
					
						
							|  |  |  |     TypeError | 
					
						
							|  |  |  |     Note that :func:`only` attempts to advance *iterable* twice to ensure there | 
					
						
							|  |  |  |     is only one item.  See :func:`spy` or :func:`peekable` to check | 
					
						
							|  |  |  |     iterable contents less destructively. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     it = iter(iterable) | 
					
						
							|  |  |  |     first_value = next(it, default) | 
					
						
							| 
									
										
										
										
											2021-07-29 21:05:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-18 16:29:22 -05:00
										 |  |  |     try: | 
					
						
							|  |  |  |         second_value = next(it) | 
					
						
							|  |  |  |     except StopIteration: | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2021-07-29 21:05:05 -04:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2023-02-18 16:29:22 -05:00
										 |  |  |         msg = ( | 
					
						
							|  |  |  |             'Expected exactly one item in iterable, but got {!r}, {!r}, ' | 
					
						
							|  |  |  |             'and perhaps more.'.format(first_value, second_value) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         raise too_long or ValueError(msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return first_value |