tests: remove libfake time from the tests

libfaketime and python-libfaketime seem to cause our CI to fail when
used in conjunction with `uv`. This changes the way the tests are done
so they don't require libfaketime anymore.
This commit is contained in:
Alexis Métaireau 2024-12-20 01:50:44 +01:00
parent 86eb9b8662
commit e568bb05cc
3 changed files with 228 additions and 317 deletions

View file

@ -1,10 +1,9 @@
from collections import defaultdict from collections import defaultdict
import datetime from datetime import datetime, timedelta, date
import re import re
from urllib.parse import unquote, urlparse, urlunparse from urllib.parse import unquote, urlparse, urlunparse
from flask import session, url_for from flask import session, url_for
from libfaketime import fake_time
import pytest import pytest
from werkzeug.security import check_password_hash from werkzeug.security import check_password_hash
@ -1144,7 +1143,7 @@ class TestBudget(IhatemoneyTestCase):
assert re.search(re.compile(regex2, re.DOTALL), response.data.decode("utf-8")) assert re.search(re.compile(regex2, re.DOTALL), response.data.decode("utf-8"))
# Check monthly expenses again: it should have a single month and the correct amount # Check monthly expenses again: it should have a single month and the correct amount
august = datetime.date(year=2011, month=8, day=1) august = date(year=2011, month=8, day=1)
assert project.active_months_range() == [august] assert project.active_months_range() == [august]
assert dict(project.monthly_stats[2011]) == {8: 40.0} assert dict(project.monthly_stats[2011]) == {8: 40.0}
@ -1161,11 +1160,11 @@ class TestBudget(IhatemoneyTestCase):
}, },
) )
months = [ months = [
datetime.date(year=2011, month=12, day=1), date(year=2011, month=12, day=1),
datetime.date(year=2011, month=11, day=1), date(year=2011, month=11, day=1),
datetime.date(year=2011, month=10, day=1), date(year=2011, month=10, day=1),
datetime.date(year=2011, month=9, day=1), date(year=2011, month=9, day=1),
datetime.date(year=2011, month=8, day=1), date(year=2011, month=8, day=1),
] ]
amounts_2011 = { amounts_2011 = {
12: 30.0, 12: 30.0,
@ -1218,7 +1217,7 @@ class TestBudget(IhatemoneyTestCase):
"amount": "20", "amount": "20",
}, },
) )
months.append(datetime.date(year=2011, month=7, day=1)) months.append(date(year=2011, month=7, day=1))
amounts_2011[7] = 20.0 amounts_2011[7] = 20.0
assert project.active_months_range() == months assert project.active_months_range() == months
assert dict(project.monthly_stats[2011]) == amounts_2011 assert dict(project.monthly_stats[2011]) == amounts_2011
@ -1235,7 +1234,7 @@ class TestBudget(IhatemoneyTestCase):
"amount": "30", "amount": "30",
}, },
) )
months.insert(0, datetime.date(year=2012, month=1, day=1)) months.insert(0, date(year=2012, month=1, day=1))
amounts_2012 = {1: 30.0} amounts_2012 = {1: 30.0}
assert project.active_months_range() == months assert project.active_months_range() == months
assert dict(project.monthly_stats[2011]) == amounts_2011 assert dict(project.monthly_stats[2011]) == amounts_2011
@ -1868,59 +1867,56 @@ class TestBudget(IhatemoneyTestCase):
""" """
Tests that the RSS feed output content is expected. Tests that the RSS feed output content is expected.
""" """
with fake_time("2023-07-25 12:00:00"): self.post_project("raclette", default_currency="EUR")
self.post_project("raclette", default_currency="EUR") self.client.post("/raclette/members/add", data={"name": "george"})
self.client.post("/raclette/members/add", data={"name": "george"}) self.client.post("/raclette/members/add", data={"name": "peter"})
self.client.post("/raclette/members/add", data={"name": "peter"}) self.client.post("/raclette/members/add", data={"name": "steven"})
self.client.post("/raclette/members/add", data={"name": "steven"})
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-31", "date": "2016-12-31",
"what": "fromage à raclette", "what": "fromage à raclette",
"payer": 1, "payer": 1,
"payed_for": [1, 2, 3], "payed_for": [1, 2, 3],
"amount": "12", "amount": "12",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-30", "date": "2016-12-30",
"what": "charcuterie", "what": "charcuterie",
"payer": 2, "payer": 2,
"payed_for": [1, 2], "payed_for": [1, 2],
"amount": "15", "amount": "15",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-29", "date": "2016-12-29",
"what": "vin blanc", "what": "vin blanc",
"payer": 2, "payer": 2,
"payed_for": [1, 2], "payed_for": [1, 2],
"amount": "10", "amount": "10",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
project = self.get_project("raclette") project = self.get_project("raclette")
token = project.generate_token("feed") token = project.generate_token("feed")
resp = self.client.get(f"/raclette/feed/{token}.xml") resp = self.client.get(f"/raclette/feed/{token}.xml")
expected_rss_content = f"""<?xml version="1.0" encoding="utf-8"?> content = resp.data.decode()
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/" assert (
xmlns:atom="http://www.w3.org/2005/Atom" f"""<channel>
>
<channel>
<title>I Hate Money raclette</title> <title>I Hate Money raclette</title>
<description>Latest bills from raclette</description> <description>Latest bills from raclette</description>
<atom:link href="http://localhost/raclette/feed/{token}.xml" rel="self" type="application/rss+xml" /> <atom:link href="http://localhost/raclette/feed/{token}.xml" rel="self" type="application/rss+xml" />
@ -1930,190 +1926,151 @@ class TestBudget(IhatemoneyTestCase):
<guid isPermaLink="false">1</guid> <guid isPermaLink="false">1</guid>
<dc:creator>george</dc:creator> <dc:creator>george</dc:creator>
<description>December 31, 2016 - george, peter, steven : 4.00</description> <description>December 31, 2016 - george, peter, steven : 4.00</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate> """
</item> in content
<item> )
<title>charcuterie - 15.00</title>
<guid isPermaLink="false">2</guid> assert """<title>charcuterie - €15.00</title>""" in content
<dc:creator>peter</dc:creator> assert """<title>vin blanc - €10.00</title>""" in content
<description>December 30, 2016 - george, peter : 7.50</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
</item>
<item>
<title>vin blanc - 10.00</title>
<guid isPermaLink="false">3</guid>
<dc:creator>peter</dc:creator>
<description>December 29, 2016 - george, peter : 5.00</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
</item>
</channel>
</rss>""" # noqa: E221, E222, E231, E501
assert resp.data.decode() == expected_rss_content
def test_rss_feed_history_disabled(self): def test_rss_feed_history_disabled(self):
""" """
Tests that RSS feeds is correctly rendered even if the project Tests that RSS feeds is correctly rendered even if the project
history is disabled. history is disabled.
""" """
with fake_time("2023-07-25 12:00:00"): self.post_project("raclette", default_currency="EUR", project_history=False)
self.post_project("raclette", default_currency="EUR", project_history=False) self.client.post("/raclette/members/add", data={"name": "george"})
self.client.post("/raclette/members/add", data={"name": "george"}) self.client.post("/raclette/members/add", data={"name": "peter"})
self.client.post("/raclette/members/add", data={"name": "peter"}) self.client.post("/raclette/members/add", data={"name": "steven"})
self.client.post("/raclette/members/add", data={"name": "steven"})
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-31", "date": "2016-12-31",
"what": "fromage à raclette", "what": "fromage à raclette",
"payer": 1, "payer": 1,
"payed_for": [1, 2, 3], "payed_for": [1, 2, 3],
"amount": "12", "amount": "12",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-30", "date": "2016-12-30",
"what": "charcuterie", "what": "charcuterie",
"payer": 2, "payer": 2,
"payed_for": [1, 2], "payed_for": [1, 2],
"amount": "15", "amount": "15",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
data={ data={
"date": "2016-12-29", "date": "2016-12-29",
"what": "vin blanc", "what": "vin blanc",
"payer": 2, "payer": 2,
"payed_for": [1, 2], "payed_for": [1, 2],
"amount": "10", "amount": "10",
"original_currency": "EUR", "original_currency": "EUR",
"bill_type": "Expense", "bill_type": "Expense",
}, },
) )
project = self.get_project("raclette") project = self.get_project("raclette")
token = project.generate_token("feed") token = project.generate_token("feed")
resp = self.client.get(f"/raclette/feed/{token}.xml") resp = self.client.get(f"/raclette/feed/{token}.xml")
expected_rss_content = f"""<?xml version="1.0" encoding="utf-8"?> content = resp.data.decode()
<rss version="2.0" assert """<title>charcuterie - €15.00</title>""" in content
xmlns:dc="http://purl.org/dc/elements/1.1/" assert """<title>vin blanc - €10.00</title>""" in content
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>I Hate Money raclette</title>
<description>Latest bills from raclette</description>
<atom:link href="http://localhost/raclette/feed/{token}.xml" rel="self" type="application/rss+xml" />
<link>http://localhost/raclette/</link>
<item>
<title>fromage à raclette - 12.00</title>
<guid isPermaLink="false">1</guid>
<dc:creator>george</dc:creator>
<description>December 31, 2016 - george, peter, steven : 4.00</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
</item>
<item>
<title>charcuterie - 15.00</title>
<guid isPermaLink="false">2</guid>
<dc:creator>peter</dc:creator>
<description>December 30, 2016 - george, peter : 7.50</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
</item>
<item>
<title>vin blanc - 10.00</title>
<guid isPermaLink="false">3</guid>
<dc:creator>peter</dc:creator>
<description>December 29, 2016 - george, peter : 5.00</description>
<pubDate>Tue, 25 Jul 2023 00:00:00 +0000</pubDate>
</item>
</channel>
</rss>""" # noqa: E221, E222, E231, E501
assert resp.data.decode() == expected_rss_content
def test_rss_if_modified_since_header(self): def test_rss_if_modified_since_header(self):
# Project creation # Project creation
with fake_time("2023-07-26 13:00:00"): self.post_project("raclette")
self.post_project("raclette") self.client.post("/raclette/members/add", data={"name": "george"})
self.client.post("/raclette/members/add", data={"name": "george"}) project = self.get_project("raclette")
project = self.get_project("raclette") token = project.generate_token("feed")
token = project.generate_token("feed")
resp = self.client.get(f"/raclette/feed/{token}.xml") resp = self.client.get(f"/raclette/feed/{token}.xml")
assert resp.status_code == 200 assert resp.status_code == 200
assert resp.headers.get("Last-Modified") == "Wed, 26 Jul 2023 13:00:00 UTC" assert "Last-Modified" in resp.headers.keys()
last_modified = resp.headers.get("Last-Modified")
# Get a date 1 hour before the last modified date
before = datetime.strptime(
last_modified, "%a, %d %b %Y %H:%M:%S %Z"
) - timedelta(hours=1)
before_str = before.strftime("%a, %d %b %Y %H:%M:%S %Z")
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={"If-Modified-Since": "Tue, 26 Jul 2023 12:00:00 UTC"}, headers={"If-Modified-Since": before_str},
) )
assert resp.status_code == 200 assert resp.status_code == 200
after = datetime.strptime(
last_modified, "%a, %d %b %Y %H:%M:%S %Z"
) + timedelta(hours=1)
after_str = after.strftime("%a, %d %b %Y %H:%M:%S %Z")
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={"If-Modified-Since": "Tue, 26 Jul 2023 14:00:00 UTC"}, headers={"If-Modified-Since": after_str},
) )
assert resp.status_code == 304 assert resp.status_code == 304
# Add bill # Add bill
with fake_time("2023-07-27 13:00:00"): self.login("raclette")
self.login("raclette") resp = self.client.post(
resp = self.client.post( "/raclette/add",
"/raclette/add", data={
data={ "date": "2016-12-31",
"date": "2016-12-31", "what": "fromage à raclette",
"what": "fromage à raclette", "payer": 1,
"payer": 1, "payed_for": [1],
"payed_for": [1], "amount": "12",
"amount": "12", "original_currency": "XXX",
"original_currency": "XXX", "bill_type": "Expense",
"bill_type": "Expense", },
}, follow_redirects=True,
follow_redirects=True, )
) assert resp.status_code == 200
assert resp.status_code == 200 assert "The bill has been added" in resp.data.decode()
assert "The bill has been added" in resp.data.decode()
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={"If-Modified-Since": "Tue, 27 Jul 2023 12:00:00 UTC"}, headers={"If-Modified-Since": before_str},
) )
assert resp.headers.get("Last-Modified") == "Thu, 27 Jul 2023 13:00:00 UTC"
assert resp.status_code == 200 assert resp.status_code == 200
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={"If-Modified-Since": "Tue, 27 Jul 2023 14:00:00 UTC"}, headers={"If-Modified-Since": after_str},
) )
assert resp.status_code == 304 assert resp.status_code == 304
def test_rss_etag_headers(self): def test_rss_etag_headers(self):
# Project creation # Project creation
with fake_time("2023-07-26 13:00:00"): self.post_project("raclette")
self.post_project("raclette") self.client.post("/raclette/members/add", data={"name": "george"})
self.client.post("/raclette/members/add", data={"name": "george"}) project = self.get_project("raclette")
project = self.get_project("raclette") token = project.generate_token("feed")
token = project.generate_token("feed")
resp = self.client.get(f"/raclette/feed/{token}.xml") resp = self.client.get(f"/raclette/feed/{token}.xml")
assert resp.headers.get("ETag") == build_etag( etag = resp.headers.get("ETag")
project.id, "2023-07-26T13:00:00" assert resp.status_code == 200
)
assert resp.status_code == 200
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={ headers={
"If-None-Match": build_etag(project.id, "2023-07-26T12:00:00"), "If-None-Match": etag,
}, },
) )
assert resp.status_code == 200 assert resp.status_code == 304
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
@ -2121,40 +2078,38 @@ class TestBudget(IhatemoneyTestCase):
"If-None-Match": build_etag(project.id, "2023-07-26T13:00:00"), "If-None-Match": build_etag(project.id, "2023-07-26T13:00:00"),
}, },
) )
assert resp.status_code == 304
# Add bill
with fake_time("2023-07-27 13:00:00"):
self.login("raclette")
resp = self.client.post(
"/raclette/add",
data={
"date": "2016-12-31",
"what": "fromage à raclette",
"payer": 1,
"payed_for": [1],
"amount": "12",
"bill_type": "Expense",
"original_currency": "XXX",
},
follow_redirects=True,
)
assert resp.status_code == 200
assert "The bill has been added" in resp.data.decode()
resp = self.client.get(
f"/raclette/feed/{token}.xml",
headers={
"If-None-Match": build_etag(project.id, "2023-07-27T12:00:00"),
},
)
assert resp.headers.get("ETag") == build_etag(project.id, "2023-07-27T13:00:00")
assert resp.status_code == 200 assert resp.status_code == 200
# Add bill
self.login("raclette")
resp = self.client.post(
"/raclette/add",
data={
"date": "2016-12-31",
"what": "fromage à raclette",
"payer": 1,
"payed_for": [1],
"amount": "12",
"bill_type": "Expense",
"original_currency": "XXX",
},
follow_redirects=True,
)
assert resp.status_code == 200
assert "The bill has been added" in resp.data.decode()
etag = resp.headers.get("ETag")
resp = self.client.get(
f"/raclette/feed/{token}.xml",
headers={"If-None-Match": etag},
)
assert resp.status_code == 200
new_etag = resp.headers.get("ETag")
resp = self.client.get( resp = self.client.get(
f"/raclette/feed/{token}.xml", f"/raclette/feed/{token}.xml",
headers={ headers={
"If-None-Match": build_etag(project.id, "2023-07-27T13:00:00"), "If-None-Match": new_etag,
}, },
) )
assert resp.status_code == 304 assert resp.status_code == 304

View file

@ -42,7 +42,6 @@ dependencies = [
"Flask-WTF>=0.14.3,<2", "Flask-WTF>=0.14.3,<2",
"itsdangerous>=2,<3", "itsdangerous>=2,<3",
"Jinja2>=3,<4", "Jinja2>=3,<4",
"pytest-libfaketime[dev]>=0.1.3",
"python-dateutil", "python-dateutil",
"qrcode>=7.1,<8", "qrcode>=7.1,<8",
"requests>=2.25,<3", "requests>=2.25,<3",
@ -65,7 +64,6 @@ dev = [
"pytest>=6.2.5", "pytest>=6.2.5",
"pytest-flask>=1.2.0", "pytest-flask>=1.2.0",
"zest.releaser>=6.20.1", "zest.releaser>=6.20.1",
"libfaketime>=2.1.0",
] ]
doc = [ doc = [
"Sphinx>=7.0.1,<8", "Sphinx>=7.0.1,<8",

144
uv.lock
View file

@ -693,7 +693,6 @@ dependencies = [
{ name = "flask-wtf" }, { name = "flask-wtf" },
{ name = "itsdangerous" }, { name = "itsdangerous" },
{ name = "jinja2" }, { name = "jinja2" },
{ name = "pytest-libfaketime" },
{ name = "python-dateutil" }, { name = "python-dateutil" },
{ name = "qrcode" }, { name = "qrcode" },
{ name = "requests" }, { name = "requests" },
@ -711,7 +710,6 @@ database = [
dev = [ dev = [
{ name = "flake8" }, { name = "flake8" },
{ name = "isort" }, { name = "isort" },
{ name = "libfaketime" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-flask" }, { name = "pytest-flask" },
{ name = "ruff" }, { name = "ruff" },
@ -745,13 +743,11 @@ requires-dist = [
{ name = "isort", marker = "extra == 'dev'", specifier = "==5.11.5" }, { name = "isort", marker = "extra == 'dev'", specifier = "==5.11.5" },
{ name = "itsdangerous", specifier = ">=2,<3" }, { name = "itsdangerous", specifier = ">=2,<3" },
{ name = "jinja2", specifier = ">=3,<4" }, { name = "jinja2", specifier = ">=3,<4" },
{ name = "libfaketime", marker = "extra == 'dev'", specifier = ">=2.1.0" },
{ name = "myst-parser", marker = "extra == 'doc'", specifier = ">=2,<3" }, { name = "myst-parser", marker = "extra == 'doc'", specifier = ">=2,<3" },
{ name = "psycopg2-binary", marker = "extra == 'database'", specifier = ">=2.9.2,<3" }, { name = "psycopg2-binary", marker = "extra == 'database'", specifier = ">=2.9.2,<2.9.9" },
{ name = "pymysql", marker = "extra == 'database'", specifier = ">=0.9,<1.1" }, { name = "pymysql", marker = "extra == 'database'", specifier = ">=0.9,<1.1" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=6.2.5" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=6.2.5" },
{ name = "pytest-flask", marker = "extra == 'dev'", specifier = ">=1.2.0" }, { name = "pytest-flask", marker = "extra == 'dev'", specifier = ">=1.2.0" },
{ name = "pytest-libfaketime", extras = ["dev"], specifier = ">=0.1.3" },
{ name = "python-dateutil" }, { name = "python-dateutil" },
{ name = "qrcode", specifier = ">=7.1,<8" }, { name = "qrcode", specifier = ">=7.1,<8" },
{ name = "requests", specifier = ">=2.25,<3" }, { name = "requests", specifier = ">=2.25,<3" },
@ -901,19 +897,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/83/25/e6d59e5f0a0508d0dca8bb98c7f7fd3772fc943ac3f53d5ab18a218d32c0/keyring-25.4.1-py3-none-any.whl", hash = "sha256:5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", size = 38946 }, { url = "https://files.pythonhosted.org/packages/83/25/e6d59e5f0a0508d0dca8bb98c7f7fd3772fc943ac3f53d5ab18a218d32c0/keyring-25.4.1-py3-none-any.whl", hash = "sha256:5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", size = 38946 },
] ]
[[package]]
name = "libfaketime"
version = "2.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dateutil" },
{ name = "pytz" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c9/ec/a02a79d0254957f340a11c350de2a8ae43cfe2ececc11fc7a951f6f9d263/libfaketime-2.1.0.tar.gz", hash = "sha256:5fecd1770565154f892235a39dfc2388b092864ecca24d05456e4f5a947127a3", size = 75103 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/03/12/c28cdc2834bbd71e9300f97093766dfcd4b8f3c7b7059c1e8543c6f3b14c/libfaketime-2.1.0-py3-none-any.whl", hash = "sha256:df72634f79900e71160f4e3ba4cf8f1d7ba6167e7c9a4f28d67c08e0a4f03ba2", size = 92845 },
]
[[package]] [[package]]
name = "limits" name = "limits"
version = "3.13.0" version = "3.13.0"
@ -1128,70 +1111,58 @@ wheels = [
[[package]] [[package]]
name = "psycopg2-binary" name = "psycopg2-binary"
version = "2.9.9" version = "2.9.8"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fc/07/e720e53bfab016ebcc34241695ccc06a9e3d91ba19b40ca81317afbdc440/psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", size = 384973 } sdist = { url = "https://files.pythonhosted.org/packages/9d/3d/5ddb908d2e5fdeb8678470d3f654e987356c9f981867313489b063fbe814/psycopg2-binary-2.9.8.tar.gz", hash = "sha256:80451e6b6b7c486828d5c7ed50769532bbb04ec3a411f1e833539d5c10eb691c", size = 383854 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/0a/7c/6aaf8c3cb05d86d2c3f407b95bac0c71a43f2718e38c1091972aacb5e1b2/psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202", size = 2822503 }, { url = "https://files.pythonhosted.org/packages/6f/93/7d0777dec397807327ccde617ade579dcb4ccbccd38659e2d9e93d105e1d/psycopg2_binary-2.9.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e271ad6692d50d70ca75db3bd461bfc26316de78de8fe1f504ef16dcea8f2312", size = 2822503 },
{ url = "https://files.pythonhosted.org/packages/72/3d/acab427845198794aafd963dd073ee35810e2c52606e8a28c12db39821fb/psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7", size = 2552645 }, { url = "https://files.pythonhosted.org/packages/2c/e6/344851c4977eded2e7f00991c193afe21403ecfd35a7895c5789a029a66f/psycopg2_binary-2.9.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ae22a0fa5c516b84ddb189157fabfa3f12eded5d630e1ce260a18e1771f8707", size = 2540362 },
{ url = "https://files.pythonhosted.org/packages/ed/be/6c787962d706e55a528ef1693dd7251de657ae60e4d9d767ed61e8e2975c/psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b", size = 2850980 }, { url = "https://files.pythonhosted.org/packages/01/51/bcafe813626422abecf27e5b9d54ef081fd4078f1d918979a013ebc22179/psycopg2_binary-2.9.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a971086db0069aef2fd22ccffb670baac427f4ee2174c4f5c7206254f1e6794", size = 2850985 },
{ url = "https://files.pythonhosted.org/packages/83/50/a054076c6358753661cd1da59f4dabc03e83d51690371f3fd1edb9e2cf72/psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9", size = 3080543 }, { url = "https://files.pythonhosted.org/packages/ab/0b/e5ac6afefd3d3172e47e2625892a8023c7aa8a3b75ea6454fcc61137acb5/psycopg2_binary-2.9.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b6928a502af71ca2ac9aad535e78c8309892ed3bfa7933182d4c760580c8af4", size = 3080553 },
{ url = "https://files.pythonhosted.org/packages/9c/02/826dc5cdfc9515423ec912ba00cc2e4eb09f69e0339b177c9c742f2a09a2/psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84", size = 3264316 }, { url = "https://files.pythonhosted.org/packages/18/a3/e3b8866d5e4ff46d86750e11aef1ae5ca9c8b561c76622def1752e78682b/psycopg2_binary-2.9.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f955fe6301b84b6fd13970a05f3640fbb62ca3a0d19342356585006c830e038", size = 3264319 },
{ url = "https://files.pythonhosted.org/packages/bc/0d/486e3fa27f39a00168abfcf14a3d8444f437f4b755cc34316da1124f293d/psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e", size = 3019508 }, { url = "https://files.pythonhosted.org/packages/a6/59/8145f6b7f82de632e07eec6cf83974e8d8279007ba3b414c29b5124af442/psycopg2_binary-2.9.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3723c3f009e2b2771f2491b330edb7091846f1aad0c08fbbd9a1383d6a0c0841", size = 3019504 },
{ url = "https://files.pythonhosted.org/packages/41/af/bce37630c525d2b9cf93f930110fc98616d6aca308d59b833b83b3a38176/psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98", size = 2355821 }, { url = "https://files.pythonhosted.org/packages/da/e2/b716ec54a62d7453c5c0df81e4cb61c6e8c03cbec3b824236139781ebdc3/psycopg2_binary-2.9.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e3142c7e51b92855cff300580de949e36a94ab3bfa8f353b27fe26535e9b3542", size = 2355825 },
{ url = "https://files.pythonhosted.org/packages/3b/76/e46dae1b2273814ef80231f86d59cadf94ec36fd757045ed713c5b75cde7/psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245", size = 2534855 }, { url = "https://files.pythonhosted.org/packages/a4/5a/ef8c7a38b7d9284be56201d1bfb8a78da1fb20b4866a5a4d5bae638aa6a0/psycopg2_binary-2.9.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:de85105c568dc5f0f0efe793209ba83e4675d53d00faffc7a7c7a8bea9e0e19a", size = 2534856 },
{ url = "https://files.pythonhosted.org/packages/0e/6d/e97245eabff29d7c2de5fc1fc17cf7ef427beee93d20a5ae114c6e6718bd/psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e", size = 2486614 }, { url = "https://files.pythonhosted.org/packages/82/6a/6e7fe0c70cfd634e8dd323c8143bd69b6187b495572c4c52d658ed8b05c6/psycopg2_binary-2.9.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c7ff2b6a79a92b1b169b03bb91b41806843f0cdf6055256554495bffed1d496d", size = 2486613 },
{ url = "https://files.pythonhosted.org/packages/70/a7/2cd2c9d5e23b556c11e3b7da41895808d9b056f8f34f50de4375a35b4951/psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f", size = 2454928 }, { url = "https://files.pythonhosted.org/packages/55/41/7e4a741ddc22c62b7b37460027527b24549a752b6286996d96c7ad7ffbdf/psycopg2_binary-2.9.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59f45cca0765aabb52a5822c72d5ff2ec46a28b1c1702de90dc0d306ec5c2001", size = 2454929 },
{ url = "https://files.pythonhosted.org/packages/63/41/815d19767e2adb1a585213b801c954f46102f305c352c4a4f96287342d44/psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682", size = 1025249 }, { url = "https://files.pythonhosted.org/packages/b6/7d/cc526b6328dbabd01ec5b105c3d765a6fa656e45f3d5ed16e05c590cfe14/psycopg2_binary-2.9.8-cp310-cp310-win32.whl", hash = "sha256:1dbad789ebd1e61201256a19dc2e90fed4706bc966ccad4f374648e5336b1ab4", size = 1025248 },
{ url = "https://files.pythonhosted.org/packages/5e/4c/9233e0e206634a5387f3ab40f334a5325fb8bef2ca4e12ee7dbdeaf96afc/psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0", size = 1163645 }, { url = "https://files.pythonhosted.org/packages/d2/b3/d8471871d031245e514970a686eed8f44a90de348c9b7480773920b7eea1/psycopg2_binary-2.9.8-cp310-cp310-win_amd64.whl", hash = "sha256:15458c81b0d199ab55825007115f697722831656e6477a427783fe75c201c82b", size = 1163646 },
{ url = "https://files.pythonhosted.org/packages/a5/ac/702d300f3df169b9d0cbef0340d9f34a78bc18dc2dbafbcb39ff0f165cf8/psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26", size = 2822581 }, { url = "https://files.pythonhosted.org/packages/ea/5a/b413a72046ac4bd027aa64989a6451cd881c07e1613e5dfd49a15def695c/psycopg2_binary-2.9.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:395c217156723fe21809dfe8f7a433c5bf8e9bce229944668e4ec709c37c5442", size = 2822582 },
{ url = "https://files.pythonhosted.org/packages/7a/1f/a6cf0cdf944253f7c45d90fbc876cc8bed5cc9942349306245715c0d88d6/psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f", size = 2552633 }, { url = "https://files.pythonhosted.org/packages/1b/ee/37ded58732145dc0ca061e9185002ea66c8f172cc20e140cc539e2546eed/psycopg2_binary-2.9.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:14f85ff2d5d826a7ce9e6c31e803281ed5a096789f47f52cb728c88f488de01b", size = 2540348 },
{ url = "https://files.pythonhosted.org/packages/81/0b/3adf561107c865928455891156d1dde5325253f7f4316fe56cd2c3f73570/psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2", size = 2851075 }, { url = "https://files.pythonhosted.org/packages/f4/2c/1d39f0fe4f41ec635388a016918e0742c9ccbdc30860b98361298f60fdb3/psycopg2_binary-2.9.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e11373d8e4f1f46cf3065bf613f0df9854803dc95aa4a35354ffac19f8c52127", size = 2851084 },
{ url = "https://files.pythonhosted.org/packages/f7/98/c2fedcbf0a9607519a010dcf88571138b2251062dbde3610cdba5ba1eee1/psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0", size = 3080509 }, { url = "https://files.pythonhosted.org/packages/a5/20/2e15593e6037b6246536cc70f0c57f41a08f8cd914ddaadb3a4b0be5499e/psycopg2_binary-2.9.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01f9731761f711e42459f87bd2ad5d744b9773b5dd05446f3b579a0f077e78e3", size = 3080501 },
{ url = "https://files.pythonhosted.org/packages/c2/05/81e8bc7fca95574c9323e487d9ce1b58a4cfcc17f89b8fe843af46361211/psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53", size = 3264303 }, { url = "https://files.pythonhosted.org/packages/86/66/661a37f98a805fcaed666e403df28e3c140b05ee4a7ceae8c960a6ef52e8/psycopg2_binary-2.9.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54bf5c27bd5867a5fa5341fad29f0d5838e2fed617ef5346884baf8b8b16dd82", size = 3264303 },
{ url = "https://files.pythonhosted.org/packages/ce/85/62825cabc6aad53104b7b6d12eb2ad74737d268630032d07b74d4444cb72/psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be", size = 3019515 }, { url = "https://files.pythonhosted.org/packages/22/52/a6113ae5fb0fb6b93894dd8487e02cdac6c85d564de7c0529e2571176193/psycopg2_binary-2.9.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfabbd7e70785af726cc0209e8e64b926abf91741eca80678b221aad9e72135", size = 3019507 },
{ url = "https://files.pythonhosted.org/packages/e9/b0/9ca2b8e01a0912c9a14234fd5df7a241a1e44778c5797bf4b8eaa8dc3d3a/psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27", size = 2355892 }, { url = "https://files.pythonhosted.org/packages/41/01/cb27421053c8c1b0148842e562caba6a4d4740fb28bb67073a6160c501ba/psycopg2_binary-2.9.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6369f4bd4d27944498094dccced1ae7ca43376a59dbfe4c8b6a16e9e3dc3ccce", size = 2355894 },
{ url = "https://files.pythonhosted.org/packages/73/17/ba28bb0022db5e2015a82d2df1c4b0d419c37fa07a588b3aff3adc4939f6/psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359", size = 2534903 }, { url = "https://files.pythonhosted.org/packages/93/08/2b8a819089bd8c5b0561b34c002890b20c1d80a23c6c4f8f18101f0bcf2e/psycopg2_binary-2.9.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4879ee1d07a6b2c232ae6a74570f4788cd7a29b3cd38bc39bf60225b1d075c78", size = 2534903 },
{ url = "https://files.pythonhosted.org/packages/3b/92/b463556409cdc12791cd8b1dae0072bf8efe817ef68b7ea3d9cf7d0e5656/psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2", size = 2486597 }, { url = "https://files.pythonhosted.org/packages/d1/e1/0d2da583bce9b5c772160994a14de1de92855938b5fba771cda9653d6ed8/psycopg2_binary-2.9.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4336afc0e81726350bd5863e3c3116d8c12aa7f457d3d0b3b3dc36137fec6feb", size = 2486598 },
{ url = "https://files.pythonhosted.org/packages/92/57/96576e07132d7f7a1ac1df939575e6fdd8951aea337ee152b586bb51a971/psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc", size = 2454908 }, { url = "https://files.pythonhosted.org/packages/4b/bb/eca133578d656111fddfd811866a54ee481959e71044155a3440845def40/psycopg2_binary-2.9.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:63ce1dccfd08d9c5341ac82d62aa04345bc4bf41b5e5b7b2c6c172a28e0eda27", size = 2454909 },
{ url = "https://files.pythonhosted.org/packages/7c/ae/cedd56e1f4a2b0e37213283caf3733a875c4c76f3372241e19c0d2a87355/psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d", size = 1024240 }, { url = "https://files.pythonhosted.org/packages/c1/56/1335979539b8505edcda925eaa4a47c0981e3ddc9546b8b6984cef495ab4/psycopg2_binary-2.9.8-cp311-cp311-win32.whl", hash = "sha256:59421806c1a0803ea7de9ed061d656c041a84db0da7e73266b98db4c7ba263da", size = 1024238 },
{ url = "https://files.pythonhosted.org/packages/25/1f/7ae31759142999a8d06b3e250c1346c4abcdcada8fa884376775dc1de686/psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417", size = 1163655 }, { url = "https://files.pythonhosted.org/packages/bb/3e/9a9d6f6171cfc47a8b4563376a7578ec12682c956985c41533f1687c61c0/psycopg2_binary-2.9.8-cp311-cp311-win_amd64.whl", hash = "sha256:ccaa2ae03990cedde1f618ff11ec89fefa84622da73091a67b44553ca8be6711", size = 1163653 },
{ url = "https://files.pythonhosted.org/packages/a7/d0/5f2db14e7b53552276ab613399a83f83f85b173a862d3f20580bc7231139/psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", size = 2823784 }, { url = "https://files.pythonhosted.org/packages/df/b2/28bb3bb4bf75aaaf58f607de4de6e4c8cbea76cfde72795b744cf137ea0f/psycopg2_binary-2.9.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e46b0f4683539965ce849f2c13fc53e323bb08d84d4ba2e4b3d976f364c84210", size = 2822509 },
{ url = "https://files.pythonhosted.org/packages/18/ca/da384fd47233e300e3e485c90e7aab5d7def896d1281239f75901faf87d4/psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d", size = 2553308 }, { url = "https://files.pythonhosted.org/packages/90/91/10d636ada2073be150ae568a67ce3481b3608c16af89667e0c6f3e6b202b/psycopg2_binary-2.9.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3fd44b52bc9c74c1512662e8da113a1c55127adeeacebaf460babe766517b049", size = 2540381 },
{ url = "https://files.pythonhosted.org/packages/50/66/fa53d2d3d92f6e1ef469d92afc6a4fe3f6e8a9a04b687aa28fb1f1d954ee/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212", size = 2851283 }, { url = "https://files.pythonhosted.org/packages/12/a1/d8396f6d6aa1da39e0d1b98e999c8d836ffc0c269bca6e95873ca33901fa/psycopg2_binary-2.9.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b6c607ecb6a9c245ebe162d63ccd9222d38efa3c858bbe38d32810b08b8f87e", size = 2850943 },
{ url = "https://files.pythonhosted.org/packages/04/37/2429360ac5547378202db14eec0dde76edbe1f6627df5a43c7e164922859/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493", size = 3081839 }, { url = "https://files.pythonhosted.org/packages/de/9e/5a290827e6fe864b1bbb2120b41403f6b38e2af4a20ae90ebfcd07105b93/psycopg2_binary-2.9.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6ef615d48fa60361e57f998327046bd89679c25d06eee9e78156be5a7a76e03", size = 3080618 },
{ url = "https://files.pythonhosted.org/packages/62/2a/c0530b59d7e0d09824bc2102ecdcec0456b8ca4d47c0caa82e86fce3ed4c/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996", size = 3264488 }, { url = "https://files.pythonhosted.org/packages/20/69/776532e8e4da491ba49177cbdb2f41317a63820211c8fc83f1c1d5333297/psycopg2_binary-2.9.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65403113ac3a4813a1409fb6a1e43c658b459cc8ed8afcc5f4baf02ec8be4334", size = 3264448 },
{ url = "https://files.pythonhosted.org/packages/19/57/9f172b900795ea37246c78b5f52e00f4779984370855b3e161600156906d/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", size = 3020700 }, { url = "https://files.pythonhosted.org/packages/0f/ff/df058f6904693e2a76da8809e89f3b4ca23fac9929de7b385184f4c161ed/psycopg2_binary-2.9.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5debcb23a052f3fb4c165789ea513b562b2fac0f0f4f53eaf3cf4dc648907ff8", size = 3019548 },
{ url = "https://files.pythonhosted.org/packages/94/68/1176fc14ea76861b7b8360be5176e87fb20d5091b137c76570eb4e237324/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba", size = 2355968 }, { url = "https://files.pythonhosted.org/packages/a6/9d/bd6c3132d7b439fb346717099566955673ace4870c2a99442d926b092825/psycopg2_binary-2.9.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dc145a241e1f6381efb924bcf3e3462d6020b8a147363f9111eb0a9c89331ad7", size = 2355858 },
{ url = "https://files.pythonhosted.org/packages/70/bb/aec2646a705a09079d008ce88073401cd61fc9b04f92af3eb282caa3a2ec/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07", size = 2536101 }, { url = "https://files.pythonhosted.org/packages/44/09/a655d4f7c049ec2deece57556fcc056c3c458d988a41c6b93f2e89916907/psycopg2_binary-2.9.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1d669887df169a9b0c09e0f5b46891511850a9ddfcde3593408af9d9774c5c3a", size = 2534861 },
{ url = "https://files.pythonhosted.org/packages/14/33/12818c157e333cb9d9e6753d1b2463b6f60dbc1fade115f8e4dc5c52cac4/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb", size = 2487064 }, { url = "https://files.pythonhosted.org/packages/14/f5/fbd3120a44c7518220554019ab5b366171924ecb5246d5a6d2562494f0dc/psycopg2_binary-2.9.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:19d40993701e39c49b50e75cd690a6af796d7e7210941ee0fe49cf12b25840e5", size = 2486634 },
{ url = "https://files.pythonhosted.org/packages/56/a2/7851c68fe8768f3c9c246198b6356ee3e4a8a7f6820cc798443faada3400/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", size = 2456257 }, { url = "https://files.pythonhosted.org/packages/1d/71/a90f741e980d70cfa7c3d570f75a887624e4884277c36918da6c485b1169/psycopg2_binary-2.9.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b8b2cdf3bce4dd91dc035fbff4eb812f5607dda91364dc216b0920b97b521c7", size = 2454934 },
{ url = "https://files.pythonhosted.org/packages/6f/ee/3ba07c6dc7c3294e717e94720da1597aedc82a10b1b180203ce183d4631a/psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93", size = 1024709 }, { url = "https://files.pythonhosted.org/packages/7a/72/6aa663d57d38823cf8931dd876f92be884879f9a6bdecf33f3e83b63d125/psycopg2_binary-2.9.8-cp38-cp38-win32.whl", hash = "sha256:4960c881471ca710b81a67ef148c33ee121c1f8e47a639cf7e06537fe9fee337", size = 1007153 },
{ url = "https://files.pythonhosted.org/packages/7b/08/9c66c269b0d417a0af9fb969535f0371b8c538633535a7a6a5ca3f9231e2/psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab", size = 1163864 }, { url = "https://files.pythonhosted.org/packages/ca/86/b0bee62b74eb64dafcbfb12e1c4f2be12cadd11f35235548aacc1e0d9d87/psycopg2_binary-2.9.8-cp38-cp38-win_amd64.whl", hash = "sha256:aeb09db95f38e75ae04e947d283e07be34d03c4c2ace4f0b73dbb9143d506e67", size = 1155786 },
{ url = "https://files.pythonhosted.org/packages/94/62/6f8d281e279a71f20d1670f4de97d116b1d90948eb16c3c41ac305f94a30/psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980", size = 2822517 }, { url = "https://files.pythonhosted.org/packages/73/3e/f6047de891b22d8ddde889ded5590a51eba5ceb602db56946255230229c3/psycopg2_binary-2.9.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5aef3296d44d05805e634dbbd2972aa8eb7497926dd86047f5e39a79c3ecc086", size = 2822530 },
{ url = "https://files.pythonhosted.org/packages/88/d8/3bbedf39ab90d64d7a6f04e3f3744c74f46f55bd305cc2db3aa12e9c5667/psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6", size = 2552729 }, { url = "https://files.pythonhosted.org/packages/7f/06/b679e3dc280cee93f2d70f15e0ec6d382d6ff9e7e58ea153dc9588d0de5c/psycopg2_binary-2.9.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4d6b592ecc8667e608b9e7344259fbfb428cc053df0062ec3ac75d8270cd5a9f", size = 2540360 },
{ url = "https://files.pythonhosted.org/packages/24/1b/99b948254604838de668d81cc39a294a987721120c67963e00d47a290f7f/psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94", size = 2850949 }, { url = "https://files.pythonhosted.org/packages/99/e0/dc34bcce3c25ec7932a1cbfdad57014a56788ff0f6c905f71e0ac7f2df13/psycopg2_binary-2.9.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:693a4e7641556f0b421a7d6c6a74058aead407d860ac1cb9d0bf25be0ca73de8", size = 2850961 },
{ url = "https://files.pythonhosted.org/packages/5f/e9/115e4f4f86d4aa5c300fdc90ac3d3e74401b4060d782281fe5b47d6c832d/psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152", size = 3080624 }, { url = "https://files.pythonhosted.org/packages/dd/2e/af52a8526ba9ddca03b8d99653464b278a56860439e1e2359dd4e5b9e475/psycopg2_binary-2.9.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf60c599c40c266a01c458e9c71db7132b11760f98f08233f19b3e0a2153cbf1", size = 3080558 },
{ url = "https://files.pythonhosted.org/packages/24/bf/4856c4985823ef094fc5a52eeb194f038dfbc57921f1d091853efc8e01b4/psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55", size = 3264449 }, { url = "https://files.pythonhosted.org/packages/27/39/ec0a7e75510de8f0a414a5303cb93a95d5eaf7a4cbf6dc03617665b86ee6/psycopg2_binary-2.9.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cbe1e19f59950afd66764e3c905ecee9f2aee9f8df2ef35af6f7948ad93f620", size = 3264313 },
{ url = "https://files.pythonhosted.org/packages/19/7a/e806ed82d954b9ec29b62f12ae8929da8910cde5ab7e919ec0983e56672d/psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972", size = 3019558 }, { url = "https://files.pythonhosted.org/packages/6a/cc/a9b6c7b135579f89493dbca86c8c12dece95fc4533d3180a7bc9fe87431f/psycopg2_binary-2.9.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc37de7e3a87f5966965fc874d33c9b68d638e6c3718fdf32a5083de563428b0", size = 3019528 },
{ url = "https://files.pythonhosted.org/packages/da/e0/073f50a65093a0bd087aff95754bdd61e8ef24d6ea29f47ea97575d4a784/psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd", size = 2355857 }, { url = "https://files.pythonhosted.org/packages/49/bc/6ccf62b42ec9e0322b0b5dbe1d10d9c84953151283a9702eae7af9a17d7a/psycopg2_binary-2.9.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6e1bb4eb0d9925d65dabaaabcbb279fab444ba66d73f86d4c07dfd11f0139c06", size = 2355812 },
{ url = "https://files.pythonhosted.org/packages/a3/96/3153069df1378d398dcbd6968d4da89735bb63dccbb13a435bc65291c59c/psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59", size = 2534862 }, { url = "https://files.pythonhosted.org/packages/a2/f5/4a4d2a5ba7e2fc71872227c8c1297ed2773d9834f3ffbba41b853638f42d/psycopg2_binary-2.9.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7bdc94217ae20ad03b375a991e107a31814053bee900ad8c967bf82ef3ff02e", size = 2534820 },
{ url = "https://files.pythonhosted.org/packages/dc/d0/512a73da2253c1904366155fd2c7ddf6d4e04a4eb434c90a18af8ce3d24b/psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3", size = 2486636 }, { url = "https://files.pythonhosted.org/packages/95/27/79c00c70ff8bec8f55cc39d1d9290733582444cf73906767f7ea6d2d216a/psycopg2_binary-2.9.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:565edaf9f691b17a7fdbabd368b5b3e67d0fdc8f7f6b52177c1d3289f4e763fd", size = 2486605 },
{ url = "https://files.pythonhosted.org/packages/ba/69/e38aeaace3a87dda1c152c039c72181fdcbff0787d5d2466944b663c4a57/psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716", size = 2454931 }, { url = "https://files.pythonhosted.org/packages/21/a0/4954e8f217ca572d6d150962893d9dc45449bbb506b010761e13489907e3/psycopg2_binary-2.9.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0e3071c947bda6afc6fe2e7b64ebd64fb2cad1bc0e705a3594cb499291f2dfec", size = 2454910 },
{ url = "https://files.pythonhosted.org/packages/bc/14/76879e83245d8dc72812fb71fb3e710fa7482a05c4b1788b41b22e9fffcc/psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5", size = 1007154 }, { url = "https://files.pythonhosted.org/packages/55/73/06f1f073e732fc54193664f04cf94addb285034a3bd352d534b8a9710e5d/psycopg2_binary-2.9.8-cp39-cp39-win32.whl", hash = "sha256:205cecdd81ff4f1ddd687ce7d06879b9b80cccc428d8d6ebf36fcba08bb6d361", size = 1037893 },
{ url = "https://files.pythonhosted.org/packages/48/10/320b014e2fda509dc16409f76815ad0229e4fcec5ed229e64f7f917cc23f/psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7", size = 1155784 }, { url = "https://files.pythonhosted.org/packages/e7/56/39189b7bf61744a627c18f3a919647f7eac78d849de1f8b2ad1a5c11f824/psycopg2_binary-2.9.8-cp39-cp39-win_amd64.whl", hash = "sha256:1f279ba74f0d6b374526e5976c626d2ac3b8333b6a7b08755c513f4d380d3add", size = 1177351 },
{ url = "https://files.pythonhosted.org/packages/82/69/c25f8bd5c189cee89bc00e16b49a84f930b3b4c2cfec953a26c99076a586/psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472", size = 2822507 },
{ url = "https://files.pythonhosted.org/packages/3e/06/7d0085889cba209185f1a52d646c4dbdbd9075345f4ca685bacf08d30755/psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f", size = 2552664 },
{ url = "https://files.pythonhosted.org/packages/68/a2/67732accfffdb6696dc9523f82e91823e8cb1cc311f1c4ce006d2bb85016/psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e", size = 2850943 },
{ url = "https://files.pythonhosted.org/packages/f0/85/dff2170a1e6748b7068a4523ea9fef8373572c4cd283cffb4802f871a556/psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67", size = 3080551 },
{ url = "https://files.pythonhosted.org/packages/2e/49/9550febcc90105089bb89881b8cba73db227b9685cfddaae2479791a2379/psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876", size = 3264314 },
{ url = "https://files.pythonhosted.org/packages/65/04/d0266fd446cb65384ce5442bc08449fd0b5d3419494574f020275f9e2273/psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7", size = 3019531 },
{ url = "https://files.pythonhosted.org/packages/ba/7e/c91f4c1e364444c8f59e82501f600019717f265ae4092057cece02d2d945/psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291", size = 2355811 },
{ url = "https://files.pythonhosted.org/packages/6b/ae/05d1e52e8535ef3c73fa327e179d982b903e2c08987fa0e2167842c153a7/psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f", size = 2534818 },
{ url = "https://files.pythonhosted.org/packages/cb/bd/e5fb2aa9737e50c0ffb9c3851710055eafedd4c8628c6ef9863bb2e9c434/psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1", size = 2486605 },
{ url = "https://files.pythonhosted.org/packages/c5/22/0b832bc8a83d8fed74c5a45fbacf4a6e6eb66bcb0cd3836fca9a709f25f4/psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860", size = 2454908 },
{ url = "https://files.pythonhosted.org/packages/0a/b7/3046fd37fdf84c1945741d16fa7536ddcf8576bad6d77ee2891c5255dce3/psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90", size = 1037893 },
{ url = "https://files.pythonhosted.org/packages/cb/35/009b43d67a7010b789690a46d49521fd435ce33ce722fe8d7ac7efe35c21/psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957", size = 1177353 },
] ]
[[package]] [[package]]
@ -1288,19 +1259,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/de/03/7a917fda3d0e96b4e80ab1f83a6628ec4ee4a882523b49417d3891bacc9e/pytest_flask-1.3.0-py3-none-any.whl", hash = "sha256:c0e36e6b0fddc3b91c4362661db83fa694d1feb91fa505475be6732b5bc8c253", size = 13105 }, { url = "https://files.pythonhosted.org/packages/de/03/7a917fda3d0e96b4e80ab1f83a6628ec4ee4a882523b49417d3891bacc9e/pytest_flask-1.3.0-py3-none-any.whl", hash = "sha256:c0e36e6b0fddc3b91c4362661db83fa694d1feb91fa505475be6732b5bc8c253", size = 13105 },
] ]
[[package]]
name = "pytest-libfaketime"
version = "0.1.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "libfaketime" },
{ name = "pytest" },
]
sdist = { url = "https://files.pythonhosted.org/packages/7b/eb/3f59bef7dd2a30e4bd16361c70294da9a1b670d0d0881bde60dc6bb1ee0e/pytest_libfaketime-0.1.3.tar.gz", hash = "sha256:113fa5cc364103eb290fb0c189bc2de6f3423c888263788c64dcfd01974a01c6", size = 2318 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b5/c6/8ff351ab29bea0ee577e0d08c3ededf96b50dc2164cb71471b58764ac8e3/pytest_libfaketime-0.1.3-py3-none-any.whl", hash = "sha256:f2b79206f51ad69a7e905b154189dece6396e4a138cebc8897d96e2b999581f6", size = 2820 },
]
[[package]] [[package]]
name = "python-dateutil" name = "python-dateutil"
version = "2.9.0.post0" version = "2.9.0.post0"