python-o365 icon indicating copy to clipboard operation
python-o365 copied to clipboard

AttributeError: 'datetime.timezone' object has no attribute 'key

Open dekiesel opened this issue 1 year ago • 11 comments

Hi,

I am just getting started with this library, but I already ran into a problem.

My code:

credentials_tuple=("myappid", "123454...")
account = Account(credentials_tuple)
if not account.is_authenticated:
          account.authenticate()

Error:

  File "/workspaces/project/o365.py", line 79, in __init__
    account = Account(credentials_tuple)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/O365/account.py", line 23, in __init__
    protocol = protocol(default_resource=main_resource, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/O365/connection.py", line 245, in __init__
    self.keyword_data_store['prefer_timezone_header'] = f'outlook.timezone="{get_windows_tz(self._timezone)}"'
                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/O365/utils/windows_tz.py", line 635, in get_windows_tz
    iana_tz.key if isinstance(iana_tz, tzinfo) else iana_tz)
    ^^^^^^^^^^^
AttributeError: 'datetime.timezone' object has no attribute 'key'

I am working on (alpine) linux, but the code seems to try to get a windows timezone?

Any ideas?

dekiesel avatar May 29 '24 12:05 dekiesel

I had a look at the object iana_tz:

{'dst': <built-in method dst of datetime.timezone object at 0x7f04d4729e10>,
 'fromutc': <built-in method fromutc of datetime.timezone object at 0x7f04d4729e10>,
 'max': datetime.timezone(datetime.timedelta(seconds=86340)),
 'min': datetime.timezone(datetime.timedelta(days=-1, seconds=60)),
 'tzname': <built-in method tzname of datetime.timezone object at 0x7f04d4729e10>,
 'utc': datetime.timezone.utc,
 'utcoffset': <built-in method utcoffset of datetime.timezone object at 0x7f04d4729e10>}

(Pdb) type(iana_tz)
<class 'datetime.timezone'>
(Pdb) isinstance(iana_tz, tzinfo)
True

Unfortunately I have no idea how to fix this.

dekiesel avatar May 29 '24 13:05 dekiesel

A workaround is setting a timezone.

In alpine:

apk add tzdata ln -s /usr/share/zoneinfo/Europe/Copenhagen /etc/localtime

dekiesel avatar May 29 '24 13:05 dekiesel

File "/usr/local/lib/python3.12/site-packages/O365/connection.py", line 245, in init self.keyword_data_store['prefer_timezone_header'] = f'outlook.timezone="{get_windows_tz(self._timezone)}"'

What's self._timezone in this line??

It should be either the timezone you have passed (should be ZoneInfo) or the ZoneInfo returned by get_localzone() from the tzlocal package.

This call only returns ZoneInfo objects:

Version 5.0 removes the pytz_deprecation_shim, and now only returns zoneinfo object

Also as ZoneInfo "key" documentation:

This is a read-only attribute that returns the value of key passed to the constructor, which should be a lookup key in the IANA time zone database (e.g. America/New_York, Europe/Paris or Asia/Tokyo).

For zones constructed from file without specifying a key parameter, this will be set to None.

alejcas avatar May 30 '24 11:05 alejcas

you should be running O365 version 2.0.34 which requires tzlocal >= 5.0

alejcas avatar May 30 '24 11:05 alejcas

What's self._timezone in this line??

Do you mean the type?

(Pdb) type(self._timezone)
<class 'datetime.timezone'>
(Pdb) self._timezone.key
*** AttributeError: 'datetime.timezone' object has no attribute 'key'

I had not passed any timezone nor changed anything when I encountered the issue. All I did was run the code I posted in my first post.

The code failed because no timezone was set. It tried to get an attribute (iana_tz.key) that didn't exist, which is what my pr is supposed to fix.

I am using O365 v2.0.35 and tzlocal v5.2

dekiesel avatar May 30 '24 11:05 dekiesel

Well the code did not fail because no timezone was set.

The timezone is set but appears to not have a "key" property and that's is because it seems the timezone is not a ZoneInfo object but a datetime.timezone object.

Can you please run this on your virtualenv?:

import tzlocal

timezone = tzlocal.get_localzone()

print(timezone)

alejcas avatar May 30 '24 12:05 alejcas

Sure. Btw, I meant no timezone configuration was set on the OS level.

/usr/local/lib/python3.12/site-packages/tzlocal/unix.py:193: UserWarning: Can not find any timezone configuration, defaulting to UTC.
  warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
UTC

dekiesel avatar May 30 '24 12:05 dekiesel

Sorry please print(type(timezone))

UTC doesn't gives that much info

Thanks

alejcas avatar May 30 '24 12:05 alejcas

print(type(timezone))
print(hasattr(timezone, "key"))
<class 'datetime.timezone'>
False

dekiesel avatar May 30 '24 12:05 dekiesel

ok I'll open an issue on tzlocal Thanks

alejcas avatar May 30 '24 12:05 alejcas

My pleasure

Alpine 3.19 (if you need that for the issue)

dekiesel avatar May 30 '24 12:05 dekiesel

This should be fixed. Closing this

alejcas avatar Apr 08 '25 16:04 alejcas