locust 2.29.0__py3-none-any.whl → 2.29.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- locust/__init__.py +2 -1
- locust/_version.py +2 -2
- locust/clients.py +150 -25
- locust/contrib/fasthttp.py +8 -0
- locust/event.py +3 -1
- locust/web.py +3 -0
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/METADATA +2 -1
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/RECORD +12 -12
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/WHEEL +1 -1
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/LICENSE +0 -0
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/entry_points.txt +0 -0
- {locust-2.29.0.dist-info → locust-2.29.1.dist-info}/top_level.txt +0 -0
locust/__init__.py
CHANGED
@@ -12,7 +12,8 @@ if os.getenv("LOCUST_PLAYWRIGHT", None):
|
|
12
12
|
|
13
13
|
from gevent import monkey
|
14
14
|
|
15
|
-
|
15
|
+
if not os.getenv("LOCUST_SKIP_MONKEY_PATCH", None):
|
16
|
+
monkey.patch_all()
|
16
17
|
|
17
18
|
from ._version import version as __version__
|
18
19
|
from .contrib.fasthttp import FastHttpUser
|
locust/_version.py
CHANGED
locust/clients.py
CHANGED
@@ -2,12 +2,12 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import re
|
4
4
|
import time
|
5
|
-
from collections.abc import Generator
|
6
5
|
from contextlib import contextmanager
|
6
|
+
from typing import TYPE_CHECKING
|
7
7
|
from urllib.parse import urlparse, urlunparse
|
8
8
|
|
9
9
|
import requests
|
10
|
-
from requests import
|
10
|
+
from requests import Response
|
11
11
|
from requests.adapters import HTTPAdapter
|
12
12
|
from requests.auth import HTTPBasicAuth
|
13
13
|
from requests.exceptions import InvalidSchema, InvalidURL, MissingSchema, RequestException
|
@@ -15,12 +15,49 @@ from urllib3 import PoolManager
|
|
15
15
|
|
16
16
|
from .exception import CatchResponseError, LocustError, ResponseError
|
17
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
import sys
|
20
|
+
from collections.abc import Callable, Generator, Iterable, Mapping, MutableMapping
|
21
|
+
from typing import Any, TypedDict
|
22
|
+
|
23
|
+
from requests.cookies import RequestsCookieJar
|
24
|
+
|
25
|
+
if sys.version_info >= (3, 11):
|
26
|
+
from typing import Unpack
|
27
|
+
else:
|
28
|
+
from typing_extensions import Unpack
|
29
|
+
|
30
|
+
# Annotations below were generated using output from mypy.
|
31
|
+
# Mypy underneath uses information from the https://github.com/python/typeshed repo.
|
32
|
+
|
33
|
+
class RequestKwargs(TypedDict, total=False):
|
34
|
+
params: Any | None # simplified signature
|
35
|
+
headers: Mapping[str, str | bytes | None] | None
|
36
|
+
cookies: RequestsCookieJar | MutableMapping[str, str] | None
|
37
|
+
files: Any | None # simplified signature
|
38
|
+
auth: Any | None # simplified signature
|
39
|
+
timeout: float | tuple[float, float] | tuple[float, None] | None
|
40
|
+
allow_redirects: bool
|
41
|
+
proxies: MutableMapping[str, str] | None
|
42
|
+
hooks: Mapping[str, Iterable[Callable[[Response], Any]] | Callable[[Response], Any]] | None
|
43
|
+
stream: bool | None
|
44
|
+
verify: bool | str | None
|
45
|
+
cert: str | tuple[str, str] | None
|
46
|
+
|
47
|
+
class RESTKwargs(RequestKwargs, total=False):
|
48
|
+
name: str | None
|
49
|
+
catch_response: bool
|
50
|
+
context: dict
|
51
|
+
|
52
|
+
|
18
53
|
absolute_http_url_regexp = re.compile(r"^https?://", re.I)
|
19
54
|
|
20
55
|
|
21
56
|
class LocustResponse(Response):
|
22
|
-
|
23
|
-
|
57
|
+
error: Exception | None = None
|
58
|
+
|
59
|
+
def raise_for_status(self) -> None:
|
60
|
+
if self.error:
|
24
61
|
raise self.error
|
25
62
|
Response.raise_for_status(self)
|
26
63
|
|
@@ -77,7 +114,7 @@ class HttpSession(requests.Session):
|
|
77
114
|
self.mount("https://", LocustHttpAdapter(pool_manager=pool_manager))
|
78
115
|
self.mount("http://", LocustHttpAdapter(pool_manager=pool_manager))
|
79
116
|
|
80
|
-
def _build_url(self, path):
|
117
|
+
def _build_url(self, path) -> str:
|
81
118
|
"""prepend url with hostname unless it's already an absolute URL"""
|
82
119
|
if absolute_http_url_regexp.match(path):
|
83
120
|
return path
|
@@ -94,7 +131,18 @@ class HttpSession(requests.Session):
|
|
94
131
|
finally:
|
95
132
|
self.request_name = None
|
96
133
|
|
97
|
-
def request(
|
134
|
+
def request( # type: ignore[override]
|
135
|
+
self,
|
136
|
+
method: str | bytes,
|
137
|
+
url: str | bytes,
|
138
|
+
name: str | None = None,
|
139
|
+
catch_response: bool = False,
|
140
|
+
context: dict = {},
|
141
|
+
*,
|
142
|
+
data: Any | None = None,
|
143
|
+
json: Any | None = None,
|
144
|
+
**kwargs: Unpack[RequestKwargs],
|
145
|
+
):
|
98
146
|
"""
|
99
147
|
Constructs and sends a :py:class:`requests.Request`.
|
100
148
|
Returns :py:class:`requests.Response` object.
|
@@ -108,7 +156,8 @@ class HttpSession(requests.Session):
|
|
108
156
|
response, even if the response code is ok (2xx). The opposite also works, one can use catch_response to catch a request
|
109
157
|
and then mark it as successful even if the response code was not (i.e 500 or 404).
|
110
158
|
:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
|
111
|
-
:param data: (optional) Dictionary
|
159
|
+
:param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`.
|
160
|
+
:param json: (optional) json to send in the body of the :class:`Request`.
|
112
161
|
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
|
113
162
|
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
|
114
163
|
:param files: (optional) Dictionary of ``'filename': file-like-objects`` for multipart encoding upload.
|
@@ -117,9 +166,17 @@ class HttpSession(requests.Session):
|
|
117
166
|
:type timeout: float or tuple
|
118
167
|
:param allow_redirects: (optional) Set to True by default.
|
119
168
|
:type allow_redirects: bool
|
120
|
-
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
|
169
|
+
:param proxies: (optional) Dictionary mapping protocol or protocol and hostname to the URL of the proxy.
|
170
|
+
:param hooks: (optional) Dictionary mapping hook name to one event or list of events, event must be callable.
|
121
171
|
:param stream: (optional) whether to immediately download the response content. Defaults to ``False``.
|
122
|
-
:param verify: (optional)
|
172
|
+
:param verify: (optional) Either a boolean, in which case it controls whether we verify
|
173
|
+
the server's TLS certificate, or a string, in which case it must be a path
|
174
|
+
to a CA bundle to use. Defaults to ``True``. When set to
|
175
|
+
``False``, requests will accept any TLS certificate presented by
|
176
|
+
the server, and will ignore hostname mismatches and/or expired
|
177
|
+
certificates, which will make your application vulnerable to
|
178
|
+
man-in-the-middle (MitM) attacks. Setting verify to ``False``
|
179
|
+
may be useful during local development or testing.
|
123
180
|
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
|
124
181
|
"""
|
125
182
|
|
@@ -132,11 +189,11 @@ class HttpSession(requests.Session):
|
|
132
189
|
|
133
190
|
start_time = time.time()
|
134
191
|
start_perf_counter = time.perf_counter()
|
135
|
-
response = self._send_request_safe_mode(method, url, **kwargs)
|
192
|
+
response = self._send_request_safe_mode(method, url, data=data, json=json, **kwargs)
|
136
193
|
response_time = (time.perf_counter() - start_perf_counter) * 1000
|
137
194
|
|
138
195
|
request_before_redirect = (response.history and response.history[0] or response).request
|
139
|
-
url = request_before_redirect.url
|
196
|
+
url = request_before_redirect.url # type: ignore
|
140
197
|
|
141
198
|
if not name:
|
142
199
|
name = request_before_redirect.path_url
|
@@ -170,7 +227,7 @@ class HttpSession(requests.Session):
|
|
170
227
|
pass
|
171
228
|
return response
|
172
229
|
|
173
|
-
def _send_request_safe_mode(self, method, url, **kwargs):
|
230
|
+
def _send_request_safe_mode(self, method, url, **kwargs) -> Response | LocustResponse:
|
174
231
|
"""
|
175
232
|
Send an HTTP request, and catch any exception that might occur due to connection problems.
|
176
233
|
|
@@ -183,10 +240,84 @@ class HttpSession(requests.Session):
|
|
183
240
|
except RequestException as e:
|
184
241
|
r = LocustResponse()
|
185
242
|
r.error = e
|
186
|
-
r.status_code = 0
|
187
|
-
r.request =
|
243
|
+
r.status_code = 0
|
244
|
+
r.request = e.request # type: ignore
|
188
245
|
return r
|
189
246
|
|
247
|
+
def get(
|
248
|
+
self, url: str | bytes, *, data: Any | None = None, json: Any | None = None, **kwargs: Unpack[RESTKwargs]
|
249
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
250
|
+
"""Sends a GET request"""
|
251
|
+
kwargs.setdefault("allow_redirects", True)
|
252
|
+
return self.request("GET", url, data=data, json=json, **kwargs)
|
253
|
+
|
254
|
+
def options(
|
255
|
+
self,
|
256
|
+
url: str | bytes,
|
257
|
+
*,
|
258
|
+
data: Any | None = None,
|
259
|
+
json: Any | None = None,
|
260
|
+
**kwargs: Unpack[RESTKwargs],
|
261
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
262
|
+
"""Sends a OPTIONS request"""
|
263
|
+
kwargs.setdefault("allow_redirects", True)
|
264
|
+
return self.request("OPTIONS", url, data=data, json=json, **kwargs)
|
265
|
+
|
266
|
+
def head(
|
267
|
+
self,
|
268
|
+
url: str | bytes,
|
269
|
+
*,
|
270
|
+
data: Any | None = None,
|
271
|
+
json: Any | None = None,
|
272
|
+
**kwargs: Unpack[RESTKwargs],
|
273
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
274
|
+
"""Sends a HEAD request"""
|
275
|
+
kwargs.setdefault("allow_redirects", False)
|
276
|
+
return self.request("HEAD", url, data=data, json=json, **kwargs)
|
277
|
+
|
278
|
+
def post(
|
279
|
+
self,
|
280
|
+
url: str | bytes,
|
281
|
+
data: Any | None = None,
|
282
|
+
json: Any | None = None,
|
283
|
+
**kwargs: Unpack[RESTKwargs],
|
284
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
285
|
+
"""Sends a POST request"""
|
286
|
+
return self.request("POST", url, data=data, json=json, **kwargs)
|
287
|
+
|
288
|
+
def put(
|
289
|
+
self,
|
290
|
+
url: str | bytes,
|
291
|
+
data: Any | None = None,
|
292
|
+
*,
|
293
|
+
json: Any | None = None,
|
294
|
+
**kwargs: Unpack[RESTKwargs],
|
295
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
296
|
+
"""Sends a PUT request"""
|
297
|
+
return self.request("PUT", url, data=data, json=json, **kwargs)
|
298
|
+
|
299
|
+
def patch(
|
300
|
+
self,
|
301
|
+
url: str | bytes,
|
302
|
+
data: Any | None = None,
|
303
|
+
*,
|
304
|
+
json: Any | None = None,
|
305
|
+
**kwargs: Unpack[RESTKwargs],
|
306
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
307
|
+
"""Sends a PATCH request"""
|
308
|
+
return self.request("PATCH", url, data=data, json=json, **kwargs)
|
309
|
+
|
310
|
+
def delete(
|
311
|
+
self,
|
312
|
+
url: str | bytes,
|
313
|
+
*,
|
314
|
+
data: Any | None = None,
|
315
|
+
json: Any | None = None,
|
316
|
+
**kwargs: Unpack[RESTKwargs],
|
317
|
+
) -> ResponseContextManager | Response | LocustResponse:
|
318
|
+
"""Sends a DELETE request"""
|
319
|
+
return self.request("DELETE", url, data=data, json=json, **kwargs)
|
320
|
+
|
190
321
|
|
191
322
|
class ResponseContextManager(LocustResponse):
|
192
323
|
"""
|
@@ -211,7 +342,7 @@ class ResponseContextManager(LocustResponse):
|
|
211
342
|
self._entered = True
|
212
343
|
return self
|
213
344
|
|
214
|
-
def __exit__(self, exc, value, traceback):
|
345
|
+
def __exit__(self, exc, value, traceback): # type: ignore[override]
|
215
346
|
# if the user has already manually marked this response as failure or success
|
216
347
|
# we can ignore the default behaviour of letting the response code determine the outcome
|
217
348
|
if self._manual_result is not None:
|
@@ -311,17 +442,11 @@ class LocustHttpAdapter(HTTPAdapter):
|
|
311
442
|
|
312
443
|
|
313
444
|
# Monkey patch Response class to give some guidance
|
314
|
-
def
|
315
|
-
raise LocustError(
|
316
|
-
"If you want to change the state of the request, you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
|
317
|
-
)
|
318
|
-
|
319
|
-
|
320
|
-
def _failure(self):
|
445
|
+
def _missing_catch_response_True(self, *_args, **_kwargs):
|
321
446
|
raise LocustError(
|
322
|
-
"If you want to change the state of the request, you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
|
447
|
+
"If you want to change the state of the request using .success() or .failure(), you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
|
323
448
|
)
|
324
449
|
|
325
450
|
|
326
|
-
Response.success =
|
327
|
-
Response.failure =
|
451
|
+
Response.success = _missing_catch_response_True # type: ignore[attr-defined]
|
452
|
+
Response.failure = _missing_catch_response_True # type: ignore[attr-defined]
|
locust/contrib/fasthttp.py
CHANGED
@@ -324,6 +324,12 @@ class FastHttpUser(User):
|
|
324
324
|
Note that setting this value has no effect when custom client_pool was given, and you need to spawn a your own gevent pool
|
325
325
|
to use it (as Users only have one greenlet). See test_fasthttp.py / test_client_pool_concurrency for an example."""
|
326
326
|
|
327
|
+
proxy_host: str | None = None
|
328
|
+
"""Parameter passed to FastHttpSession"""
|
329
|
+
|
330
|
+
proxy_port: int | None = None
|
331
|
+
"""Parameter passed to FastHttpSession"""
|
332
|
+
|
327
333
|
client_pool: HTTPClientPool | None = None
|
328
334
|
"""HTTP client pool to use. If not given, a new pool is created per single user."""
|
329
335
|
|
@@ -355,6 +361,8 @@ class FastHttpUser(User):
|
|
355
361
|
client_pool=self.client_pool,
|
356
362
|
ssl_context_factory=self.ssl_context_factory,
|
357
363
|
headers=self.default_headers,
|
364
|
+
proxy_host=self.proxy_host,
|
365
|
+
proxy_port=self.proxy_port,
|
358
366
|
)
|
359
367
|
"""
|
360
368
|
Instance of HttpSession that is created upon instantiation of User.
|
locust/event.py
CHANGED
@@ -61,7 +61,9 @@ class EventHook:
|
|
61
61
|
|
62
62
|
Example usage (in a task):
|
63
63
|
|
64
|
-
|
64
|
+
.. code-block:: python
|
65
|
+
|
66
|
+
with self.environment.events.request.measure("requestType", "requestName") as request_meta:
|
65
67
|
# do the stuff you want to measure
|
66
68
|
|
67
69
|
You can optionally add/overwrite entries in the request_meta dict and they will be passed to the request event.
|
locust/web.py
CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
3
3
|
import csv
|
4
4
|
import json
|
5
5
|
import logging
|
6
|
+
import mimetypes
|
6
7
|
import os.path
|
7
8
|
from functools import wraps
|
8
9
|
from html import escape
|
@@ -132,6 +133,8 @@ class WebUI:
|
|
132
133
|
self.app.template_folder = BUILD_PATH
|
133
134
|
self.app.static_folder = STATIC_PATH
|
134
135
|
self.app.static_url_path = "/assets/"
|
136
|
+
# ensures static js files work on Windows
|
137
|
+
mimetypes.add_type("application/javascript", ".js")
|
135
138
|
|
136
139
|
if self.web_login:
|
137
140
|
self.login_manager = LoginManager()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: locust
|
3
|
-
Version: 2.29.
|
3
|
+
Version: 2.29.1
|
4
4
|
Summary: Developer-friendly load testing framework
|
5
5
|
License: MIT
|
6
6
|
Project-URL: Homepage, https://github.com/locustio/locust
|
@@ -39,6 +39,7 @@ Requires-Dist: Flask-Login >=0.6.3
|
|
39
39
|
Requires-Dist: Flask-Cors >=3.0.10
|
40
40
|
Requires-Dist: pywin32 ; platform_system == "Windows"
|
41
41
|
Requires-Dist: tomli >=1.1.0 ; python_version < "3.11"
|
42
|
+
Requires-Dist: typing-extensions >=4.6.0 ; python_version < "3.11"
|
42
43
|
Requires-Dist: requests >=2.32.2 ; python_version > "3.11"
|
43
44
|
|
44
45
|
# Locust
|
@@ -1,12 +1,12 @@
|
|
1
|
-
locust/__init__.py,sha256=
|
1
|
+
locust/__init__.py,sha256=Hmw2vNf75eLQ1mQIPXAwlQrJ_XFY65MOb92fGsNCukQ,1458
|
2
2
|
locust/__main__.py,sha256=vBQ82334kX06ImDbFlPFgiBRiLIinwNk3z8Khs6hd74,31
|
3
|
-
locust/_version.py,sha256=
|
3
|
+
locust/_version.py,sha256=Htwgi4ogmtDOuhuq2HreknlH3a2T0FdWYBlGTUPcCwU,413
|
4
4
|
locust/argument_parser.py,sha256=sjQoJ1NTac9LdNYT7zn8RajlWqBQs8YFNv6uRExb2gg,28941
|
5
|
-
locust/clients.py,sha256=
|
5
|
+
locust/clients.py,sha256=OHPv6hBAt4gt3HI67yqyT1qrSsF8uMdCwIRu0kIsRWI,19491
|
6
6
|
locust/debug.py,sha256=We6Z9W0btkKSc7PxWmrZx-xMynvOOsKhG6jmDgQin0g,5134
|
7
7
|
locust/dispatch.py,sha256=vYh0QEDFgJ3hY0HgSk-EiNO7IP9ffzXF_Et8wB9JvsI,16995
|
8
8
|
locust/env.py,sha256=sP-fCnZs0e2xodRemLHgTgyyUt5eezwtdA9WsCoqJkQ,12767
|
9
|
-
locust/event.py,sha256=
|
9
|
+
locust/event.py,sha256=H2SuxyadPMsRY-LQ6MuK1okHls9lYsS9GgXIDSxpi50,7864
|
10
10
|
locust/exception.py,sha256=jGgJ32ubuf4pWdlaVOkbh2Y0LlG0_DHi-lv3ib8ppOE,1791
|
11
11
|
locust/html.py,sha256=_n3aB3fxiYzSeE_7RqHF3iiEPjPnbQ3e2Pw9P8AVtPU,3920
|
12
12
|
locust/input_events.py,sha256=ZIyePyAMuA_YFYWg18g_pE4kwuQV3RbEB250MzXRwjY,3314
|
@@ -16,9 +16,9 @@ locust/py.typed,sha256=gkWLl8yD4mIZnNYYAIRM8g9VarLvWmTAFeUfEbxJLBw,65
|
|
16
16
|
locust/runners.py,sha256=wqf9eIPUGrqz7m-EZtXKdMJ43cainHm0bS-3Cj4haBo,69471
|
17
17
|
locust/shape.py,sha256=t-lwBS8LOjWcKXNL7j2U3zroIXJ1b0fazUwpRYQOKXw,1973
|
18
18
|
locust/stats.py,sha256=5jx9aD9Sky-kCZ3E-MjRT3xbwvxo9xyDtfcfP56zclo,45875
|
19
|
-
locust/web.py,sha256=
|
19
|
+
locust/web.py,sha256=rN1NVeZ9LKSEeDwvpRbOJ0bcy8U1U4VjP-7vK7ejlwM,27367
|
20
20
|
locust/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
locust/contrib/fasthttp.py,sha256=
|
21
|
+
locust/contrib/fasthttp.py,sha256=n6arQP1IH3CVP8PUaIhD-X5xWMAOj9F0JEJXPklun0Y,26999
|
22
22
|
locust/rpc/__init__.py,sha256=nVGoHWFQxZjnhCDWjbgXIbmFbN9sizAjkhvSs9_642c,58
|
23
23
|
locust/rpc/protocol.py,sha256=n-rb3GZQcAlldYDj4E4GuFGylYj_26GSS5U29meft5Y,1282
|
24
24
|
locust/rpc/zmqrpc.py,sha256=AAY6w7wSFHsW34qqN28666boHFf6dTSAXPQJnAO6iUI,2707
|
@@ -71,9 +71,9 @@ locust/webui/dist/report.html,sha256=sOdZZVgZbqgu86BBCSQf3uQUYXgmgSnXF32JpnyAII8
|
|
71
71
|
locust/webui/dist/assets/favicon.ico,sha256=IUl-rYqfpHdV38e-s0bkmFIeLS-n3Ug0DQxk-h202hI,8348
|
72
72
|
locust/webui/dist/assets/index-84c63e70.js,sha256=cwyH4ju0OCRvFhg3O-0SYVBTFlN_XQeQ6YkymAO4Hco,1647185
|
73
73
|
locust/webui/dist/assets/logo.png,sha256=EIVPqr6wE_yqguHaqFHIsH0ZACLSrvNWyYO7PbyIj4w,19299
|
74
|
-
locust-2.29.
|
75
|
-
locust-2.29.
|
76
|
-
locust-2.29.
|
77
|
-
locust-2.29.
|
78
|
-
locust-2.29.
|
79
|
-
locust-2.29.
|
74
|
+
locust-2.29.1.dist-info/LICENSE,sha256=78XGpIn3fHVBfaxlPNUfjVufSN7QsdhpJMRJHv2AFpo,1095
|
75
|
+
locust-2.29.1.dist-info/METADATA,sha256=GfouDWwtoDhviRtO3pLKrdi2VYAcocS-ugctam4pmuY,7384
|
76
|
+
locust-2.29.1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
77
|
+
locust-2.29.1.dist-info/entry_points.txt,sha256=RAdt8Ku-56m7bFjmdj-MBhbF6h4NX7tVODR9QNnOg0E,44
|
78
|
+
locust-2.29.1.dist-info/top_level.txt,sha256=XSsjgPA8Ggf9TqKVbkwSqZFuPlZ085X13M9orDycE20,7
|
79
|
+
locust-2.29.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|