Skip to content

Commit

Permalink
tests: use zoneinfo instead of pytz (#1304)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed May 28, 2024
1 parent 5228721 commit fd26293
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 22 deletions.
3 changes: 2 additions & 1 deletion tests/emscripten_runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async function main() {
FS.mkdir('/test_dir');
FS.mount(FS.filesystems.NODEFS, {root: path.join(root_dir, 'tests')}, '/test_dir');
FS.chdir('/test_dir');
await pyodide.loadPackage(['micropip', 'pytest', 'pytz']);
await pyodide.loadPackage(['micropip', 'pytest']);
// language=python
errcode = await pyodide.runPythonAsync(`
import micropip
Expand All @@ -101,6 +101,7 @@ await micropip.install([
'hypothesis',
'pytest-speed',
'pytest-mock',
'tzdata',
'file:${wheel_path}',
'typing-extensions',
])
Expand Down
3 changes: 2 additions & 1 deletion tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
backports.zoneinfo==0.2.1;python_version<"3.9"
coverage==7.5.0
dirty-equals==0.7.1.post0
hypothesis==6.100.2
Expand All @@ -16,7 +17,7 @@ pytest-speed==0.3.5
pytest-mock==3.14.0
pytest-pretty==1.2.0
pytest-timeout==2.3.1
pytz==2024.1
# numpy doesn't offer prebuilt wheels for all versions and platforms we test in CI e.g. aarch64 musllinux
numpy==1.26.2; python_version >= "3.9" and python_version < "3.13" and implementation_name == "cpython" and platform_machine == 'x86_64'
exceptiongroup==1.1; python_version < "3.11"
tzdata==2024.1
41 changes: 23 additions & 18 deletions tests/validators/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
from typing import Dict

import pytest
import pytz

try:
import zoneinfo
except ImportError:
# TODO: can remove this once we drop support for python 3.8
from backports import zoneinfo

This comment has been minimized.

Copy link
@kloczek

kloczek May 28, 2024

Contributor

I think that instead try: except ImportError: better would be use

if sys.version_info >= (3, 9):
    import zoneinfo
else
    from backports import zoneinfo

With that it will be possible to drop legacy part of the code using pyupgrade --py39-plus

This comment has been minimized.

Copy link
@davidhewitt

davidhewitt May 28, 2024

Author Contributor

Fair suggestion, though I'm not bothered enough to go back and improve it now.

I got the try/except suggestion directly from the backports README: https://github.com/pganssle/zoneinfo?tab=readme-ov-file#use


from pydantic_core import SchemaError, SchemaValidator, ValidationError, core_schema, validate_core_schema

Expand Down Expand Up @@ -81,8 +86,8 @@ def test_datetime_strict(input_value, expected):


def test_keep_tz():
tz = pytz.timezone('Europe/London')
dt = tz.localize(datetime(2022, 6, 14, 12, 13, 14))
tz = zoneinfo.ZoneInfo('Europe/London')
dt = datetime(2022, 6, 14, 12, 13, 14, tzinfo=tz)
v = SchemaValidator({'type': 'datetime'})

output = v.validate_python(dt)
Expand All @@ -94,8 +99,8 @@ def test_keep_tz():


def test_keep_tz_bound():
tz = pytz.timezone('Europe/London')
dt = tz.localize(datetime(2022, 6, 14, 12, 13, 14))
tz = zoneinfo.ZoneInfo('Europe/London')
dt = datetime(2022, 6, 14, 12, 13, 14, tzinfo=tz)
v = SchemaValidator({'type': 'datetime', 'gt': datetime(2022, 1, 1)})

output = v.validate_python(dt)
Expand All @@ -106,7 +111,7 @@ def test_keep_tz_bound():
assert output.tzinfo.dst(datetime(2022, 1, 1)) == timedelta(0)

with pytest.raises(ValidationError, match=r'Input should be greater than 2022-01-01T00:00:00 \[type=greater_than'):
v.validate_python(tz.localize(datetime(2021, 6, 14)))
v.validate_python(datetime(2021, 6, 14, tzinfo=tz))


@pytest.mark.parametrize(
Expand Down Expand Up @@ -186,8 +191,8 @@ def test_custom_timezone_utc_repr():


def test_tz_comparison():
tz = pytz.timezone('Europe/London')
uk_3pm = tz.localize(datetime(2022, 1, 1, 15, 0, 0))
tz = zoneinfo.ZoneInfo('Europe/London')
uk_3pm = datetime(2022, 1, 1, 15, 0, 0, tzinfo=tz)

# two times are the same instant, therefore le and ge are both ok
v = SchemaValidator({'type': 'datetime', 'le': uk_3pm}).validate_python('2022-01-01T16:00:00+01:00')
Expand Down Expand Up @@ -322,22 +327,22 @@ def test_datetime_past_timezone():
now_utc = datetime.now(timezone.utc) - timedelta(seconds=1)
assert v.isinstance_python(now_utc)
# "later" in the day
assert v.isinstance_python(now_utc.astimezone(pytz.timezone('Europe/Istanbul')))
assert v.isinstance_python(now_utc.astimezone(zoneinfo.ZoneInfo('Europe/Istanbul')))
# "earlier" in the day
assert v.isinstance_python(now_utc.astimezone(pytz.timezone('America/Los_Angeles')))
assert v.isinstance_python(now_utc.astimezone(zoneinfo.ZoneInfo('America/Los_Angeles')))

soon_utc = now_utc + timedelta(minutes=1)
assert not v.isinstance_python(soon_utc)

# "later" in the day
assert not v.isinstance_python(soon_utc.astimezone(pytz.timezone('Europe/Istanbul')))
assert not v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('Europe/Istanbul')))
# "earlier" in the day
assert not v.isinstance_python(soon_utc.astimezone(pytz.timezone('America/Los_Angeles')))
assert not v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('America/Los_Angeles')))

# input value is timezone naive, so we do a dumb comparison in these terms the istanbul time is later so fails
# wile the LA time is earlier so passes
assert not v.isinstance_python(soon_utc.astimezone(pytz.timezone('Europe/Istanbul')).replace(tzinfo=None))
assert v.isinstance_python(soon_utc.astimezone(pytz.timezone('America/Los_Angeles')).replace(tzinfo=None))
assert not v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('Europe/Istanbul')).replace(tzinfo=None))
assert v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('America/Los_Angeles')).replace(tzinfo=None))


@pytest.mark.parametrize(
Expand Down Expand Up @@ -368,17 +373,17 @@ def test_datetime_future_timezone():
assert v.isinstance_python(soon_utc)

# "later" in the day
assert v.isinstance_python(soon_utc.astimezone(pytz.timezone('Europe/Istanbul')))
assert v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('Europe/Istanbul')))
# "earlier" in the day
assert v.isinstance_python(soon_utc.astimezone(pytz.timezone('America/Los_Angeles')))
assert v.isinstance_python(soon_utc.astimezone(zoneinfo.ZoneInfo('America/Los_Angeles')))

past_utc = now_utc - timedelta(minutes=1)
assert not v.isinstance_python(past_utc)

# "later" in the day
assert not v.isinstance_python(past_utc.astimezone(pytz.timezone('Europe/Istanbul')))
assert not v.isinstance_python(past_utc.astimezone(zoneinfo.ZoneInfo('Europe/Istanbul')))
# "earlier" in the day
assert not v.isinstance_python(past_utc.astimezone(pytz.timezone('America/Los_Angeles')))
assert not v.isinstance_python(past_utc.astimezone(zoneinfo.ZoneInfo('America/Los_Angeles')))


def test_mock_utc_offset_8_hours(mocker):
Expand Down
2 changes: 1 addition & 1 deletion wasm-preview/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async def main(tests_zip: str, tag_name: str):

print(f'Mounted {count} test files, installing dependencies...')

await micropip.install(['dirty-equals', 'hypothesis', 'pytest-speed', 'pytest-mock', pydantic_core_wheel])
await micropip.install(['dirty-equals', 'hypothesis', 'pytest-speed', 'pytest-mock', pydantic_core_wheel, 'tzdata'])
importlib.invalidate_caches()

# print('installed packages:')
Expand Down
2 changes: 1 addition & 1 deletion wasm-preview/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async function main() {
setupStreams(FS, pyodide._module.TTY);
FS.mkdir('/test_dir');
FS.chdir('/test_dir');
await pyodide.loadPackage(['micropip', 'pytest', 'pytz', 'numpy']);
await pyodide.loadPackage(['micropip', 'pytest', 'numpy']);
if (pydantic_core_version < '2.0.0') await pyodide.loadPackage(['typing-extensions']);
await pyodide.runPythonAsync(python_code, {globals: pyodide.toPy({pydantic_core_version, tests_zip})});
post();
Expand Down

0 comments on commit fd26293

Please sign in to comment.