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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

57 statements  

1from __future__ import annotations 

2 

3import typing as t 

4 

5from werkzeug.exceptions import BadRequest 

6from werkzeug.exceptions import HTTPException 

7from werkzeug.wrappers import Request as RequestBase 

8from werkzeug.wrappers import Response as ResponseBase 

9 

10from . import json 

11from .globals import current_app 

12from .helpers import _split_blueprint_path 

13 

14if t.TYPE_CHECKING: # pragma: no cover 

15 from werkzeug.routing import Rule 

16 

17 

18class Request(RequestBase): 

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

20 matched endpoint and view arguments. 

21 

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

23 the request object used you can subclass this and set 

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

25 

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

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

28 specific ones. 

29 """ 

30 

31 json_module: t.Any = json 

32 

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

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

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

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

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

38 #: instead (an attribute of the Werkzeug exception 

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

40 #: because the request was never internally bound. 

41 #: 

42 #: .. versionadded:: 0.6 

43 url_rule: Rule | None = None 

44 

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

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

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

48 

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

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

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

52 #: something similar. 

53 routing_exception: HTTPException | None = None 

54 

55 @property 

56 def max_content_length(self) -> int | None: # type: ignore[override] 

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

58 if current_app: 

59 return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] 

60 else: 

61 return None 

62 

63 @property 

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

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

66 

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

68 performed yet. 

69 

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

71 reconstruct the same URL or a modified URL. 

72 """ 

73 if self.url_rule is not None: 

74 return self.url_rule.endpoint 

75 

76 return None 

77 

78 @property 

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

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

81 

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

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

84 yet. 

85 

86 This does not necessarily match the name the blueprint was 

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

88 different name. 

89 """ 

90 endpoint = self.endpoint 

91 

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

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

94 

95 return None 

96 

97 @property 

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

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

100 parent blueprints. 

101 

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

103 if URL matching failed. 

104 

105 .. versionadded:: 2.0.1 

106 """ 

107 name = self.blueprint 

108 

109 if name is None: 

110 return [] 

111 

112 return _split_blueprint_path(name) 

113 

114 def _load_form_data(self) -> None: 

115 super()._load_form_data() 

116 

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

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

119 if ( 

120 current_app 

121 and current_app.debug 

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

123 and not self.files 

124 ): 

125 from .debughelpers import attach_enctype_error_multidict 

126 

127 attach_enctype_error_multidict(self) 

128 

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

130 try: 

131 return super().on_json_loading_failed(e) 

132 except BadRequest as e: 

133 if current_app and current_app.debug: 

134 raise 

135 

136 raise BadRequest() from e 

137 

138 

139class Response(ResponseBase): 

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

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

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

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

144 

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

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

147 

148 .. versionchanged:: 1.0 

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

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

151 

152 .. versionchanged:: 1.0 

153 

154 Added :attr:`max_cookie_size`. 

155 """ 

156 

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

158 

159 json_module = json 

160 

161 autocorrect_location_header = False 

162 

163 @property 

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

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

166 

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

168 Werkzeug's docs. 

169 """ 

170 if current_app: 

171 return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return] 

172 

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

174 return super().max_cookie_size