mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Refs #33865 -- Improved implementation of FakePayload.
FakePayload is a wrapper around io.BytesIO and is expected to masquerade as though it is a file-like object. For that reason it makes sense that it should inherit the correct signatures from io.BytesIO methods. Crucially an implementation of .readline() is added which will be necessary for this to behave more like the expected file-like objects as LimitedStream will be changed to defer to the wrapped stream object rather than rolling its own implementation for improved performance. It should be safe to adjust these signatures because FakePayload is only used internally within test client helpers, is undocumented, and thus private.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							95182a8593
						
					
				
				
					commit
					57f5669d23
				
			| @@ -6,7 +6,7 @@ from copy import copy | ||||
| from functools import partial | ||||
| from http import HTTPStatus | ||||
| from importlib import import_module | ||||
| from io import BytesIO | ||||
| from io import BytesIO, IOBase | ||||
| from urllib.parse import unquote_to_bytes, urljoin, urlparse, urlsplit | ||||
|  | ||||
| from asgiref.sync import sync_to_async | ||||
| @@ -55,7 +55,7 @@ class RedirectCycleError(Exception): | ||||
|         self.redirect_chain = last_response.redirect_chain | ||||
|  | ||||
|  | ||||
| class FakePayload: | ||||
| class FakePayload(IOBase): | ||||
|     """ | ||||
|     A wrapper around BytesIO that restricts what can be read since data from | ||||
|     the network can't be sought and cannot be read outside of its content | ||||
| @@ -63,39 +63,49 @@ class FakePayload: | ||||
|     that wouldn't work in real life. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, content=None): | ||||
|     def __init__(self, initial_bytes=None): | ||||
|         self.__content = BytesIO() | ||||
|         self.__len = 0 | ||||
|         self.read_started = False | ||||
|         if content is not None: | ||||
|             self.write(content) | ||||
|         if initial_bytes is not None: | ||||
|             self.write(initial_bytes) | ||||
|  | ||||
|     def __len__(self): | ||||
|         return self.__len | ||||
|  | ||||
|     def read(self, num_bytes=None): | ||||
|     def read(self, size=-1, /): | ||||
|         if not self.read_started: | ||||
|             self.__content.seek(0) | ||||
|             self.read_started = True | ||||
|         if num_bytes is None: | ||||
|             num_bytes = self.__len or 0 | ||||
|         if size == -1 or size is None: | ||||
|             size = self.__len | ||||
|         assert ( | ||||
|             self.__len >= num_bytes | ||||
|             self.__len >= size | ||||
|         ), "Cannot read more than the available bytes from the HTTP incoming data." | ||||
|         content = self.__content.read(num_bytes) | ||||
|         self.__len -= num_bytes | ||||
|         content = self.__content.read(size) | ||||
|         self.__len -= len(content) | ||||
|         return content | ||||
|  | ||||
|     def write(self, content): | ||||
|     def readline(self, size=-1, /): | ||||
|         if not self.read_started: | ||||
|             self.__content.seek(0) | ||||
|             self.read_started = True | ||||
|         if size == -1 or size is None: | ||||
|             size = self.__len | ||||
|         assert ( | ||||
|             self.__len >= size | ||||
|         ), "Cannot read more than the available bytes from the HTTP incoming data." | ||||
|         content = self.__content.readline(size) | ||||
|         self.__len -= len(content) | ||||
|         return content | ||||
|  | ||||
|     def write(self, b, /): | ||||
|         if self.read_started: | ||||
|             raise ValueError("Unable to write a payload after it's been read") | ||||
|         content = force_bytes(content) | ||||
|         content = force_bytes(b) | ||||
|         self.__content.write(content) | ||||
|         self.__len += len(content) | ||||
|  | ||||
|     def close(self): | ||||
|         pass | ||||
|  | ||||
|  | ||||
| def closing_iterator_wrapper(iterable, close): | ||||
|     try: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user