#28911: Add support for the Msft time zone required on Windows Subsystem for 
Linux
running openSUSE
--------------------------------------+------------------------------------
     Reporter:  El'endia Starman      |                    Owner:  nobody
         Type:  Cleanup/optimization  |                   Status:  new
    Component:  Utilities             |                  Version:  1.11
     Severity:  Normal                |               Resolution:
     Keywords:  timezone              |             Triage Stage:  Accepted
    Has patch:  0                     |      Needs documentation:  0
  Needs tests:  0                     |  Patch needs improvement:  0
Easy pickings:  0                     |                    UI/UX:  0
--------------------------------------+------------------------------------
Changes (by Stephen James):

 * cc: Stephen James (added)


Old description:

> Under Windows Subsystem for Linux (I was using openSUSE), the only
> available time zone is `Msft`, which uses settings that are set on the
> Windows side. This is not a valid time zone in pytz. In the process of
> reporting an error thrown by a bug in my code, Django tried to normalize
> the time zone provided in the project settings by passing it through
> pytz. pytz then complains that the time zone is unknown. Somewhat
> amusingly, this error is also caught by Django and goes through the same
> code path, quickly hitting the recursion limit.
>
> See below for a significant part of the stack trace. My temporary
> solution was to change
>
> `return pytz.timezone(settings.TIME_ZONE)`
>
> to
>
> `return pytz.timezone(settings.TIME_ZONE if settings.TIME_ZONE in
> pytz.all_timezones else 'UTC')`
>
> ---
>
> {{{
> pytz.exceptions.UnknownTimeZoneError: 'Msft'
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 41, in inner
>     response = get_response(request)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/deprecation.py", line 140, in __call__
>     response = self.get_response(request)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 43, in inner
>     response = response_for_exception(request, exc)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 93, in
> response_for_exception
>     response = handle_uncaught_exception(request,
> get_resolver(get_urlconf()), sys.exc_info())
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 139, in
> handle_uncaught_exception
>     return debug.technical_500_response(request, *exc_info)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/views/debug.py", line 84, in technical_500_response
>     html = reporter.get_traceback_html()
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/views/debug.py", line 328, in get_traceback_html
>     return t.render(c)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 207, in render
>     return self._render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 199, in _render
>     return self.nodelist.render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 990, in render
>     bit = node.render_annotated(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 957, in render_annotated
>     return self.render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 1040, in render
>     output = self.filter_expression.resolve(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 732, in resolve
>     obj = template_localtime(obj, context.use_tz)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 195, in template_localtime
>     return localtime(value) if should_convert else value
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 213, in localtime
>     timezone = get_current_timezone()
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 97, in get_current_timezone
>     return getattr(_active, "value", get_default_timezone())
>   File
> "/home/elendiastarman/.virtualenvs/django/lib64/python3.4/functools.py",
> line 472, in wrapper
>     result = user_function(*args, **kwds)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 79, in get_default_timezone
>     return pytz.timezone(settings.TIME_ZONE)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/pytz/__init__.py", line 191, in timezone
>     raise UnknownTimeZoneError(zone)
> pytz.exceptions.UnknownTimeZoneError: 'Msft'
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
>   File "/usr/lib64/python3.4/wsgiref/handlers.py", line 137, in run
>     self.result = application(self.environ, self.start_response)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
>     return self.application(environ, start_response)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/wsgi.py", line 157, in __call__
>     response = self.get_response(request)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/base.py", line 124, in get_response
>     response = self._middleware_chain(request)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 43, in inner
>     response = response_for_exception(request, exc)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 93, in
> response_for_exception
>     response = handle_uncaught_exception(request,
> get_resolver(get_urlconf()), sys.exc_info())
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/core/handlers/exception.py", line 139, in
> handle_uncaught_exception
>     return debug.technical_500_response(request, *exc_info)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/views/debug.py", line 84, in technical_500_response
>     html = reporter.get_traceback_html()
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/views/debug.py", line 328, in get_traceback_html
>     return t.render(c)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 207, in render
>     return self._render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 199, in _render
>     return self.nodelist.render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 990, in render
>     bit = node.render_annotated(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 957, in render_annotated
>     return self.render(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 1040, in render
>     output = self.filter_expression.resolve(context)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/template/base.py", line 732, in resolve
>     obj = template_localtime(obj, context.use_tz)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 195, in template_localtime
>     return localtime(value) if should_convert else value
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 213, in localtime
>     timezone = get_current_timezone()
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 97, in get_current_timezone
>     return getattr(_active, "value", get_default_timezone())
>   File
> "/home/elendiastarman/.virtualenvs/django/lib64/python3.4/functools.py",
> line 472, in wrapper
>     result = user_function(*args, **kwds)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/django/utils/timezone.py", line 79, in get_default_timezone
>     return pytz.timezone(settings.TIME_ZONE)
>   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
> packages/pytz/__init__.py", line 191, in timezone
>     raise UnknownTimeZoneError(zone)
> pytz.exceptions.UnknownTimeZoneError: 'Msft'
> }}}

New description:

 Under Windows Subsystem for Linux, the only available time zone on
 openSUSE is `Msft`, which uses settings that are set on the Windows side.
 This is not a valid time zone in pytz. In the process of reporting an
 error thrown by a bug in my code, Django tried to normalize the time zone
 provided in the project settings by passing it through pytz. pytz then
 complains that the time zone is unknown. Somewhat amusingly, this error is
 also caught by Django and goes through the same code path, quickly hitting
 the recursion limit.

 See below for a significant part of the stack trace. My temporary solution
 was to change

 `return pytz.timezone(settings.TIME_ZONE)`

 to

 `return pytz.timezone(settings.TIME_ZONE if settings.TIME_ZONE in
 pytz.all_timezones else 'UTC')`

 ---

 {{{
 pytz.exceptions.UnknownTimeZoneError: 'Msft'

 During handling of the above exception, another exception occurred:

 Traceback (most recent call last):
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 41, in inner
     response = get_response(request)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/deprecation.py", line 140, in __call__
     response = self.get_response(request)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 43, in inner
     response = response_for_exception(request, exc)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 93, in
 response_for_exception
     response = handle_uncaught_exception(request,
 get_resolver(get_urlconf()), sys.exc_info())
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 139, in
 handle_uncaught_exception
     return debug.technical_500_response(request, *exc_info)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/views/debug.py", line 84, in technical_500_response
     html = reporter.get_traceback_html()
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/views/debug.py", line 328, in get_traceback_html
     return t.render(c)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 207, in render
     return self._render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 199, in _render
     return self.nodelist.render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 990, in render
     bit = node.render_annotated(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 957, in render_annotated
     return self.render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 1040, in render
     output = self.filter_expression.resolve(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 732, in resolve
     obj = template_localtime(obj, context.use_tz)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 195, in template_localtime
     return localtime(value) if should_convert else value
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 213, in localtime
     timezone = get_current_timezone()
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 97, in get_current_timezone
     return getattr(_active, "value", get_default_timezone())
   File
 "/home/elendiastarman/.virtualenvs/django/lib64/python3.4/functools.py",
 line 472, in wrapper
     result = user_function(*args, **kwds)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 79, in get_default_timezone
     return pytz.timezone(settings.TIME_ZONE)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/pytz/__init__.py", line 191, in timezone
     raise UnknownTimeZoneError(zone)
 pytz.exceptions.UnknownTimeZoneError: 'Msft'

 During handling of the above exception, another exception occurred:

 Traceback (most recent call last):
   File "/usr/lib64/python3.4/wsgiref/handlers.py", line 137, in run
     self.result = application(self.environ, self.start_response)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
     return self.application(environ, start_response)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/wsgi.py", line 157, in __call__
     response = self.get_response(request)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/base.py", line 124, in get_response
     response = self._middleware_chain(request)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 43, in inner
     response = response_for_exception(request, exc)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 93, in
 response_for_exception
     response = handle_uncaught_exception(request,
 get_resolver(get_urlconf()), sys.exc_info())
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/core/handlers/exception.py", line 139, in
 handle_uncaught_exception
     return debug.technical_500_response(request, *exc_info)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/views/debug.py", line 84, in technical_500_response
     html = reporter.get_traceback_html()
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/views/debug.py", line 328, in get_traceback_html
     return t.render(c)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 207, in render
     return self._render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 199, in _render
     return self.nodelist.render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 990, in render
     bit = node.render_annotated(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 957, in render_annotated
     return self.render(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 1040, in render
     output = self.filter_expression.resolve(context)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/template/base.py", line 732, in resolve
     obj = template_localtime(obj, context.use_tz)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 195, in template_localtime
     return localtime(value) if should_convert else value
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 213, in localtime
     timezone = get_current_timezone()
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 97, in get_current_timezone
     return getattr(_active, "value", get_default_timezone())
   File
 "/home/elendiastarman/.virtualenvs/django/lib64/python3.4/functools.py",
 line 472, in wrapper
     result = user_function(*args, **kwds)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/django/utils/timezone.py", line 79, in get_default_timezone
     return pytz.timezone(settings.TIME_ZONE)
   File "/home/elendiastarman/.virtualenvs/django/lib/python3.4/site-
 packages/pytz/__init__.py", line 191, in timezone
     raise UnknownTimeZoneError(zone)
 pytz.exceptions.UnknownTimeZoneError: 'Msft'
 }}}

--

Comment:

 The three Linux distributions available for WSL at present are Ubuntu
 16.04, openSUSE 42.3, and SUSE Linux Enterprise Server 12. Having tested
 on all three, the issue is only present on WSL when running openSUSE (i.e.
 there doesn't seem to be any issues on Ubuntu and SLES).

 On openSUSE only:
 {{{
 $ ls /usr/share/zoneinfo
 Msft
 }}}
 Msft is in all, but it is the only thing in openSUSE.

 
[https://github.com/django/django/blob/02365d3f38a64a5c2f3e932f23925a381d5bb151/django/conf/__init__.py#L130
 here] is where Django tries to verify the timezone and would raise a
 `ValueError` if `/usr/share/zoneinfo` exists, but doesn't contain anything
 for the specified timezone.

 Upon further investigation, I stumbled across
 [https://trent.utfs.org/wiki/OpenSUSE#Missing_.2Fusr.2Fshare.2Fzoneinfo
 this], specifically:
 > Apparently, `/usr/share/zoneinfo` is missing from a (minimal) openSUSE
 installation...
 I assume this is why none of the other timezones are there (Microsoft
 seemingly still adds theirs regardless, hence why
 `/usr/share/zoneinfo/Msft` and hence `/usr/share/zoneinfo` would still
 exist).

 Installing the `timezone` package (`zypper install timezone`), as the
 aforementioned link suggests, will add them, which would allow Django to
 not fail on other time zones. I would suggest using that as a fix for the
 reporter and anyone else with a similar issue.

 If there is any desire to make any changes to Django itself for this
 issue, then I'd suggest changing the validation attempts to further
 determine if that folder can be relied on.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28911#comment:7>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/072.1f60219e88820545d2cf189d9a6df8a6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to