has2k1 / mizani

A scales package for python
https://mizani.readthedocs.io
BSD 3-Clause "New" or "Revised" License
49 stars 14 forks source link

Unable to load mizani.transforms on some platforms due to lack of system tzdata on some platforms #27

Closed wch closed 1 year ago

wch commented 1 year ago

On some platforms, the system does not provide tzdata, and this causes import mizani.transforms to result in an error.

For example, on recent versions of Pyodide, tzdata is not included. If you run the following in the pyodide web console, it will result in an error.

>>> import micropip
>>> await micropip.install("mizani")
>>> import mizani
>>> mizani.__version__
'0.8.1'
>>> import mizani.transforms
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 995, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1053, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1030, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'tzdata'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/lib/python3.10/site-packages/mizani/transforms.py", line 54, in <module>
    UTC = ZoneInfo('UTC')
  File "/lib/python3.10/zoneinfo/_zoneinfo.py", line 43, in __new__
    instance = cls._weak_cache.setdefault(key, cls._new_instance(key))
  File "/lib/python3.10/zoneinfo/_zoneinfo.py", line 70, in _new_instance
    file_obj = _common.load_tzdata(key)
  File "/lib/python3.10/zoneinfo/_common.py", line 24, in load_tzdata
    raise ZoneInfoNotFoundError(f"No time zone found with key {key}")
zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key UTC'

The error comes from this line: https://github.com/has2k1/mizani/blob/eb780650a0c9105e466ca03053bd9fe2c06cfd0a/mizani/transforms.py#L54

I believe that Windows also does not include tzdata by default, but I don't know for sure. PEP 615 has something to say about this.

It is possible to make it work, by installing the tzdata module from PyPI. Running this in the pyodide web console will work:

>>> import micropip
>>> await micropip.install("mizani")
>>> await micropip.install("tzdata")
>>> import mizani
>>> mizani.__version__
'0.8.1'
>>> import mizani.transforms

I don't know what the best way is to specify a dependency on the tzdata module -- it doesn't seem like it should be a hard dependency, because it is only necessary if the system doesn't provide tzdata.

has2k1 commented 1 year ago

tzdata is a required dependency on windows. That specification is enabled by PEP 508 which makes it possible to condition requirements based on different markers in the installation environment.

I suspect it is pyodide/micropip not being fully compliant with these environment markers. But then there is this function in micropip dedicated to pep508 without any caveats!

I don't know what to make of it, something is not quite right.

has2k1 commented 1 year ago

Got it. pyodide is not Windows.

Welcome to the Pyodide terminal emulator 🐍
Python 3.10.2 (main, Jan 25 2023 18:32:53) on WebAssembly/Emscripten
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.system()
'Emscripten'
>>> 
has2k1 commented 1 year ago

Testing that micropip respects environment markers

Welcome to the Pyodide terminal emulator 🐍
Python 3.10.2 (main, Jan 25 2023 18:32:53) on WebAssembly/Emscripten
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.system()
'Emscripten'
>>> platform.system = lambda: "Windows"
>>> platform.system()
'Windows'
>>> import micropip
>>> await micropip.install("mizani")
>>> import mizani.transforms
>>> 
skupr-anaconda commented 1 year ago

Here is a comment about tzdata on Windows:

  # There is no Windows port available and porting to Windows is not trivial.
  # However, the compiled package can be used on Windows