Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/flask/wrappers.py: 68%

56 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-09 07:17 +0000

1from __future__ import annotations 

2 

3import typing as t 

4 

5from werkzeug.exceptions import BadRequest 

6from werkzeug.wrappers import Request as RequestBase 

7from werkzeug.wrappers import Response as ResponseBase 

8 

9from . import json 

10from .globals import current_app 

11from .helpers import _split_blueprint_path 

12 

13if t.TYPE_CHECKING: # pragma: no cover 

14 from werkzeug.routing import Rule 

15 

16 

17class Request(RequestBase): 

18 """The request object used by default in Flask. Remembers the 

19 matched endpoint and view arguments. 

20 

21 It is what ends up as :class:`~flask.request`. If you want to replace 

22 the request object used you can subclass this and set 

23 :attr:`~flask.Flask.request_class` to your subclass. 

24 

25 The request object is a :class:`~werkzeug.wrappers.Request` subclass and 

26 provides all of the attributes Werkzeug defines plus a few Flask 

27 specific ones. 

28 """ 

29 

30 json_module: t.Any = json 

31 

32 #: The internal URL rule that matched the request. This can be 

33 #: useful to inspect which methods are allowed for the URL from 

34 #: a before/after handler (``request.url_rule.methods``) etc. 

35 #: Though if the request's method was invalid for the URL rule, 

36 #: the valid list is available in ``routing_exception.valid_methods`` 

37 #: instead (an attribute of the Werkzeug exception 

38 #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) 

39 #: because the request was never internally bound. 

40 #: 

41 #: .. versionadded:: 0.6 

42 url_rule: Rule | None = None 

43 

44 #: A dict of view arguments that matched the request. If an exception 

45 #: happened when matching, this will be ``None``. 

46 view_args: dict[str, t.Any] | None = None 

47 

48 #: If matching the URL failed, this is the exception that will be 

49 #: raised / was raised as part of the request handling. This is 

50 #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or 

51 #: something similar. 

52 routing_exception: Exception | None = None 

53 

54 @property 

55 def max_content_length(self) -> int | None: # type: ignore 

56 """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" 

57 if current_app: 

58 return current_app.config["MAX_CONTENT_LENGTH"] 

59 else: 

60 return None 

61 

62 @property 

63 def endpoint(self) -> str | None: 

64 """The endpoint that matched the request URL. 

65 

66 This will be ``None`` if matching failed or has not been 

67 performed yet. 

68 

69 This in combination with :attr:`view_args` can be used to 

70 reconstruct the same URL or a modified URL. 

71 """ 

72 if self.url_rule is not None: 

73 return self.url_rule.endpoint 

74 

75 return None 

76 

77 @property 

78 def blueprint(self) -> str | None: 

79 """The registered name of the current blueprint. 

80 

81 This will be ``None`` if the endpoint is not part of a 

82 blueprint, or if URL matching failed or has not been performed 

83 yet. 

84 

85 This does not necessarily match the name the blueprint was 

86 created with. It may have been nested, or registered with a 

87 different name. 

88 """ 

89 endpoint = self.endpoint 

90 

91 if endpoint is not None and "." in endpoint: 

92 return endpoint.rpartition(".")[0] 

93 

94 return None 

95 

96 @property 

97 def blueprints(self) -> list[str]: 

98 """The registered names of the current blueprint upwards through 

99 parent blueprints. 

100 

101 This will be an empty list if there is no current blueprint, or 

102 if URL matching failed. 

103 

104 .. versionadded:: 2.0.1 

105 """ 

106 name = self.blueprint 

107 

108 if name is None: 

109 return [] 

110 

111 return _split_blueprint_path(name) 

112 

113 def _load_form_data(self) -> None: 

114 super()._load_form_data() 

115 

116 # In debug mode we're replacing the files multidict with an ad-hoc 

117 # subclass that raises a different error for key errors. 

118 if ( 

119 current_app 

120 and current_app.debug 

121 and self.mimetype != "multipart/form-data" 

122 and not self.files 

123 ): 

124 from .debughelpers import attach_enctype_error_multidict 

125 

126 attach_enctype_error_multidict(self) 

127 

128 def on_json_loading_failed(self, e: ValueError | None) -> t.Any: 

129 try: 

130 return super().on_json_loading_failed(e) 

131 except BadRequest as e: 

132 if current_app and current_app.debug: 

133 raise 

134 

135 raise BadRequest() from e 

136 

137 

138class Response(ResponseBase): 

139 """The response object that is used by default in Flask. Works like the 

140 response object from Werkzeug but is set to have an HTML mimetype by 

141 default. Quite often you don't have to create this object yourself because 

142 :meth:`~flask.Flask.make_response` will take care of that for you. 

143 

144 If you want to replace the response object used you can subclass this and 

145 set :attr:`~flask.Flask.response_class` to your subclass. 

146 

147 .. versionchanged:: 1.0 

148 JSON support is added to the response, like the request. This is useful 

149 when testing to get the test client response data as JSON. 

150 

151 .. versionchanged:: 1.0 

152 

153 Added :attr:`max_cookie_size`. 

154 """ 

155 

156 default_mimetype: str | None = "text/html" 

157 

158 json_module = json 

159 

160 autocorrect_location_header = False 

161 

162 @property 

163 def max_cookie_size(self) -> int: # type: ignore 

164 """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. 

165 

166 See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in 

167 Werkzeug's docs. 

168 """ 

169 if current_app: 

170 return current_app.config["MAX_COOKIE_SIZE"] 

171 

172 # return Werkzeug's default when not in an app context 

173 return super().max_cookie_size