Squachen / micloud

Library for connecting to xiaomi cloud.
MIT License
156 stars 20 forks source link

SystemError: null argument to internal routine on python 3.8 #5

Closed rytilahti closed 2 years ago

rytilahti commented 2 years ago

Looks like something has changed in tzlocal, which is breaking python 3.8 usage (https://github.com/home-assistant/core/runs/4371559292?check_suite_focus=true). Any ideas?

tests/components/xiaomi_miio/test_config_flow.py:964: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
homeassistant/data_entry_flow.py:252: in async_configure
    result = await self._async_handle_step(flow, cur_step["step_id"], user_input)
homeassistant/data_entry_flow.py:325: in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
homeassistant/components/xiaomi_miio/config_flow.py:238: in async_step_cloud
    miio_cloud = MiCloud(cloud_username, cloud_password)
venv/lib/python3.8/site-packages/micloud/micloud.py:38: in __init__
    timezone = datetime.datetime.now(tzlocal.get_localzone()).strftime('%z')
venv/lib/python3.8/site-packages/tzlocal/unix.py:171: in get_localzone
    _cache_tz = _get_localzone()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_root = '/'

    def _get_localzone(_root='/'):
        """Tries to find the local timezone configuration.

        This method prefers finding the timezone name and passing that to pytz,
        over passing in the localtime file, as in the later case the zoneinfo
        name is unknown.

        The parameter _root makes the function look for files like /etc/localtime
        beneath the _root directory. This is primarily used by the tests.
        In normal usage you call the function without parameters."""

        tzenv = _try_tz_from_env()
        if tzenv:
            return tzenv

        # Are we under Termux on Android?
        if os.path.exists('/system/bin/getprop'):
            import subprocess
            androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode()
            return ZoneInfo(androidtz)

        # Now look for distribution specific configuration files
        # that contain the timezone name.
        for configfile in ('etc/timezone', 'var/db/zoneinfo'):
            tzpath = os.path.join(_root, configfile)
            try:
                with open(tzpath, 'rb') as tzfile:
                    data = tzfile.read()

                    # Issue #3 was that /etc/timezone was a zoneinfo file.
                    # That's a misconfiguration, but we need to handle it gracefully:
                    if data[:5] == b'TZif2':
                        continue

                    etctz = data.strip().decode()
                    if not etctz:
                        # Empty file, skip
                        continue
                    for etctz in data.decode().splitlines():
                        # Get rid of host definitions and comments:
                        if ' ' in etctz:
                            etctz, dummy = etctz.split(' ', 1)
                        if '#' in etctz:
                            etctz, dummy = etctz.split('#', 1)
                        if not etctz:
                            continue
>                       tz = ZoneInfo(etctz.replace(' ', '_'))
E                       SystemError: null argument to internal routine
Squachen commented 2 years ago

I can not reproduce this on python 3.8.12 (or 3.10.0).

from micloud import MiCloud
mc = MiCloud("user", "password")

This does not produce any errors in my tests.

rytilahti commented 2 years ago

Looks like others are having problems to reproduce it outside the CI system too (https://github.com/home-assistant/core/pull/60650#issuecomment-983263414), so maybe this can be closed?