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

55 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1import typing as t 

2 

3from werkzeug.exceptions import BadRequest 

4from werkzeug.wrappers import Request as RequestBase 

5from werkzeug.wrappers import Response as ResponseBase 

6 

7from . import json 

8from .globals import current_app 

9from .helpers import _split_blueprint_path 

10 

11if t.TYPE_CHECKING: # pragma: no cover 

12 from werkzeug.routing import Rule 

13 

14 

15class Request(RequestBase): 

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

17 matched endpoint and view arguments. 

18 

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

20 the request object used you can subclass this and set 

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

22 

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

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

25 specific ones. 

26 """ 

27 

28 json_module = json 

29 

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

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

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

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

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

35 #: instead (an attribute of the Werkzeug exception 

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

37 #: because the request was never internally bound. 

38 #: 

39 #: .. versionadded:: 0.6 

40 url_rule: t.Optional["Rule"] = None 

41 

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

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

44 view_args: t.Optional[t.Dict[str, t.Any]] = None 

45 

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

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

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

49 #: something similar. 

50 routing_exception: t.Optional[Exception] = None 

51 

52 @property 

53 def max_content_length(self) -> t.Optional[int]: # type: ignore 

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

55 if current_app: 

56 return current_app.config["MAX_CONTENT_LENGTH"] 

57 else: 

58 return None 

59 

60 @property 

61 def endpoint(self) -> t.Optional[str]: 

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

63 

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

65 performed yet. 

66 

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

68 reconstruct the same URL or a modified URL. 

69 """ 

70 if self.url_rule is not None: 

71 return self.url_rule.endpoint 

72 

73 return None 

74 

75 @property 

76 def blueprint(self) -> t.Optional[str]: 

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

78 

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

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

81 yet. 

82 

83 This does not necessarily match the name the blueprint was 

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

85 different name. 

86 """ 

87 endpoint = self.endpoint 

88 

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

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

91 

92 return None 

93 

94 @property 

95 def blueprints(self) -> t.List[str]: 

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

97 parent blueprints. 

98 

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

100 if URL matching failed. 

101 

102 .. versionadded:: 2.0.1 

103 """ 

104 name = self.blueprint 

105 

106 if name is None: 

107 return [] 

108 

109 return _split_blueprint_path(name) 

110 

111 def _load_form_data(self) -> None: 

112 super()._load_form_data() 

113 

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

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

116 if ( 

117 current_app 

118 and current_app.debug 

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

120 and not self.files 

121 ): 

122 from .debughelpers import attach_enctype_error_multidict 

123 

124 attach_enctype_error_multidict(self) 

125 

126 def on_json_loading_failed(self, e: t.Optional[ValueError]) -> t.Any: 

127 try: 

128 return super().on_json_loading_failed(e) 

129 except BadRequest as e: 

130 if current_app and current_app.debug: 

131 raise 

132 

133 raise BadRequest() from e 

134 

135 

136class Response(ResponseBase): 

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

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

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

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

141 

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

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

144 

145 .. versionchanged:: 1.0 

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

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

148 

149 .. versionchanged:: 1.0 

150 

151 Added :attr:`max_cookie_size`. 

152 """ 

153 

154 default_mimetype = "text/html" 

155 

156 json_module = json 

157 

158 autocorrect_location_header = False 

159 

160 @property 

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

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

163 

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

165 Werkzeug's docs. 

166 """ 

167 if current_app: 

168 return current_app.config["MAX_COOKIE_SIZE"] 

169 

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

171 return super().max_cookie_size