Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsADirectoryError while getting local timezone #256

Closed
aczapszys opened this issue Jul 23, 2018 · 5 comments · Fixed by #594 · May be fixed by sdispater/pytzdata#11
Closed

IsADirectoryError while getting local timezone #256

aczapszys opened this issue Jul 23, 2018 · 5 comments · Fixed by #594 · May be fixed by sdispater/pytzdata#11

Comments

@aczapszys
Copy link

Maybe related to 6ee68b9

I'm seeing an error with this test.py:

import pendulum
pendulum.now()
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    pendulum.now()
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/__init__.py", line 207, in now
    dt = _datetime.datetime.now(local_timezone())
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/__init__.py", line 59, in local_timezone
    return get_local_timezone()
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/local_timezone.py", line 31, in get_local_timezone
    tz = _get_system_timezone()
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/local_timezone.py", line 59, in _get_system_timezone
    return _get_unix_timezone()
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/local_timezone.py", line 210, in _get_unix_timezone
    return Timezone('/'.join(tzpath))
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/timezone.py", line 30, in __init__
    tz = read(name, extend=extended)
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/zoneinfo/__init__.py", line 9, in read
    return Reader(extend=extend).read_for(name)
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/zoneinfo/reader.py", line 52, in read_for
    return self.read(file_path)
  File "/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pendulum/tz/zoneinfo/reader.py", line 63, in read
    with open(file_path, 'rb') as fd:
IsADirectoryError: [Errno 21] Is a directory: '/mnt/iscsi/10_web_cem_dev/work/axc/cem-one-times/env/lib64/python3.6/site-packages/pytzdata/zoneinfo/Pacific'

This is the content of my /etc/sysconfig/clock:

ZONE="US/Pacific"

I think it should be trying to read env/lib64/python3.6/site-packages/pytzdata/zoneinfo/US/Pacific

@aczapszys
Copy link
Author

aczapszys commented Jul 23, 2018

I can confirm test.py works w/ pendulum 2.0.0, but not with 2.0.1 - 2.0.4

@leric
Copy link

leric commented Aug 7, 2019

I just got a similar error: IsADirectoryError: [Errno 21] Is a directory: '/etc/timezone'
and found an empty directory at /etc/timezone/ which shouldn't be there, I deleted the directory to handle the error, but pendulum should be more careful with files.

@lsh-0
Copy link

lsh-0 commented Sep 2, 2022

The fix looks like it's here: sdispater/pytzdata#11

But it's uncommitted.

Could it be committed please? alternately, could this ticket be re-opened?

I had the same problem as @leric .

update: my mistake, Github reports the fix is here #594 and was merged Jan 7th 2022, however there hasn't been a release since https://github.com/sdispater/pendulum/releases/tag/2.1.2 in July 2020. Could pendulum get a release, please?

@darkfeline
Copy link

darkfeline commented May 23, 2024

I'm seeing this on pendulum-3.0.0 (as a dep for flexget). Was the bug fixed or did this regress?

  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/flexget/utils/template.py", line 49, in extra_vars
    'now': CoercingDateTime.now(),
           │                └ <classmethod(<function DateTime.now at 0x76ec8339e5c0>)>
           └ <class 'flexget.utils.template.CoercingDateTime'>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/datetime.py", line 165, in now
    dt = datetime.datetime.now(local_timezone())
         │        │        │   └ <function local_timezone at 0x76ec8339d3a0>
         │        │        └ <method 'now' of 'datetime.datetime' objects>
         │        └ <class 'datetime.datetime'>
         └ <module 'datetime' from '/usr/lib/python3.12/datetime.py'>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/tz/__init__.py", line 51, in local_timezone
    return get_local_timezone()
           └ <function get_local_timezone at 0x76ec8336fc40>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/tz/local_timezone.py", line 33, in get_local_timezone
    tz = _get_system_timezone()
         └ <function _get_system_timezone at 0x76ec8339d080>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/tz/local_timezone.py", line 61, in _get_system_timezone
    return _get_unix_timezone()
           └ <function _get_unix_timezone at 0x76ec8339d260>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/tz/local_timezone.py", line 232, in _get_unix_timezone
    return Timezone(os.path.join(*tzpath_parts))
           │        │  │    │     └ ['Pacific']
           │        │  │    └ <function join at 0x76ec85918ae0>
           │        │  └ <module 'posixpath' (frozen)>
           │        └ <module 'os' (frozen)>
           └ <class 'pendulum.tz.timezone.Timezone'>
  File "/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/pendulum/tz/timezone.py", line 65, in __new__
    return super().__new__(cls, key)  # type: ignore[call-arg]
                           │    └ 'Pacific'
                           └ <class 'pendulum.tz.timezone.Timezone'>
  File "/usr/lib/python3.12/zoneinfo/_common.py", line 12, in load_tzdata
    return resources.files(package_name).joinpath(resource_name).open("rb")
           │         │     │                      └ 'Pacific'
           │         │     └ 'tzdata.zoneinfo'
           │         └ <function files at 0x76ec848ec360>
           └ <module 'importlib.resources' from '/usr/lib/python3.12/importlib/resources/__init__.py'>
  File "/usr/lib/python3.12/pathlib.py", line 1013, in open
    return io.open(self, mode, buffering, encoding, errors, newline)
           │  │    │     │     │          │         │       └ None
           │  │    │     │     │          │         └ None
           │  │    │     │     │          └ None
           │  │    │     │     └ -1
           │  │    │     └ 'rb'
           │  │    └ PosixPath('/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/tzdata/zoneinfo/Pacific')
           │  └ <built-in function open>
           └ <module 'io' (frozen)>
IsADirectoryError: [Errno 21] Is a directory: '/home/ionasal/.local/share/python-venv/flexget/lib/python3.12/site-packages/tzdata/zoneinfo/Pacific'

@aczapszys
Copy link
Author

aczapszys commented May 24, 2024

@darkfeline
I think what you're seeing is an edge case that was not fixed. You might want to open a new issue with your stack trace / description.

I presume that in your case, /etc/localtime is a symlink to something like /usr/share/zoneinfo/US/Pacific.
In that case, _get_unix_timezone calls Timezone("Pacific") to see if it's valid.
https://github.com/sdispater/pendulum/blob/3.0.0/src/pendulum/tz/local_timezone.py#L232

However, down in Python's zoneinfo.load_tzdata, it does not protect against its resource maybe being a directory (https://github.com/python/tzdata/tree/master/src/tzdata/zoneinfo/Pacific). It throws an IsADirectoryError where it should have thrown a ZoneInfoNotFoundError.
https://github.com/python/cpython/blame/main/Lib/zoneinfo/_common.py#L13

Ideally, this fix would go in zoneinfo. But in the mean time, you could add IsADirectoryError to _get_unix_timezone's contextlib.suppress call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants