question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Time zone problems with PyInstaller

See original GitHub issue

I’m trying to compile a project which uses arrow. It works fine when I run it on the command line. But when I run a Windows executable version compiled by PyInstaller, it fails:

C:\Users{username}\AppData\Local\Temp_MEI180~1\dateutil\zoneinfo__init__.py:38: UserWarning: I/O error(2): No such file or directory

This is followed by a parser error, presumably related to its inability to open the dateutil init:

Traceback (most recent call last): File “<string>”, line 524, in <module> File “<string>”, line 473, in getSkeds File “<string>”, line 387, in parseSchedule File “site-packages\arrow\arrow.py”, line 462, in to File “site-packages\arrow\parser.py”, line 303, in parse ParserError: (u’Could not parse timezone expression “{0}”', ‘US/Central’)

I create the executable using this syntax:

pyinstaller scriptname.py --onefile

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:7

github_iconTop GitHub Comments

3reactions
larsyunkercommented, Feb 22, 2021

Apologies for necroing this issue, but I’ve run into this exact situation except I’m on Windows so the easy_installed workaround doesn’t help me. I’m posting this solution in case some other poor soul runs up against this.

I’ve traced back the issue to PyInstaller not including the dateutil.zoneinfo.dateutil-zoneinfo.tar.gz reference information during packaging. When accessed, the getzoneinfofile_stream method cannot find the packaged file and doesn’t load the time zones. Then you end up with errors parsing time zones because there are no defined zones.

The workaround is to:

  1. bundle the dateutil-zoneinfo.tar.gz file as a data source in your installer (i.e. adding ('\Path\To\site-packages\dateutil\zoneinfo\dateutil-zoneinfo.tar.gz', '.')
  2. create a loader method which points to this data file
  3. replace the dateutil.zoneinfo.getzoneinfofile_stream method with this method

Then when the method is accessed by your code, the auto-constructor references the source data you bundled. It’s hacky but it appears to work. I initially tried to pre-construct the ZoneInfo instance, but that wasn’t associated with the get_zonefile_instance cache so it wasn’t referenced when the code tried to parse a time zone.

Here’s the code I used for a workaround:

import sys
import pathlib

# data path reference for script and packaged versions (the default '' lets this work in script-mode) 
data_path = getattr(sys, '_MEIPASS', '')  # _MEIPASS is the path referenced by the executable created by PyInstaller 


def override_getzoneinfofile_stream():
    """
    method for overriding the dateutil.zoneinfo building method

    Assign this to method dateutil.zoneinfo.getzoneinfofile_stream and the ZoneInfo contructor will retrieve the
    information it points to.
    """
    with open(pathlib.Path(data_path, 'dateutil-zoneinfo.tar.gz'), 'rb') as f:
        payload = f.read()
    return BytesIO(payload)


# if there is packaged dateutil info
if pathlib.Path(data_path if data_path != __name__ else '', 'dateutil-zoneinfo.tar.gz').is_file():
    script_logger.info('overriding time zone reference file retrieval')
    import dateutil.zoneinfo
    # override bytes retrieval method
    dateutil.zoneinfo.getzoneinfofile_stream = override_getzoneinfofile_stream

In terms of whether this is a bug, it’s a pretty specific use case so no, but geeze was it difficult to override the loading behaviour. It would have been much easier if there was some way to build the time zone defaults from a user-provided file. So the issue lies on the dateutil side, but maybe there could be some way for arrow to implement something which allows user timezone definition.

3reactions
Kirkmancommented, Aug 28, 2016

Surprisingly, removing my pip-installed dateutil and replacing it with an easy_installed dateutil fixed the problem. As suggested here: http://stackoverflow.com/a/16388845/566307

Read more comments on GitHub >

github_iconTop Results From Across the Web

Time zone problems with PyInstaller · Issue #353 · arrow-py ...
I'm trying to compile a project which uses arrow. It works fine when I run it on the command line. But when I...
Read more >
exchangelib and pyinstaller - zoneinfo - tzdata - UTC issue
Using pyinstaller --onefile I had UTC errors (in general tzdata)- "No timzone in key UTC". Simplifying all and following this issue ...
Read more >
Problems with Pyinstaller & and Common Fixes - YouTube
uite error prone, and many people have run into alot of constant errors and problems while using Pyinstaller. This Video was created for...
Read more >
Possibility to exclude time zone files with pyinstaller? - Reddit
I don't need time zone info anywhere in my script. Is it possible to make my imports more specific so it excludes time...
Read more >
tzlocal - PyPI
This Python module returns a tzinfo object (with a pytz_deprecation_shim, for pytz compatibility) with the local timezone information, under Unix and Windows.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found