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

Fix leap second update when using a non english locale #11062

Merged
merged 2 commits into from Nov 26, 2020

Conversation

saimn
Copy link
Contributor

@saimn saimn commented Nov 19, 2020

I'm working on a documentation, and for every build I see the leap second update with an expiration warning:

Downloading https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
|==========================================================| 1.3k/1.3k (100.00%)         0s
Downloading https://www.ietf.org/timezones/data/leap-seconds.list [Done]
WARNING: IERSStaleWarning: leap-second file is expired. [astropy.utils.iers.iers]

I already saw this in the past, so this is not new, but I never took the time to investigate... I can reproduce with various documentations (1, 2, 3), but the weird thing is that there is no warning when importing directly astropy.

Putting some prints in LeapSeconds.auto_open gives this for a normal import:

❯ python -c "import astropy.coordinates.earth_orientation"
open erfa
expires: 2017-06-30 00:00:00.000
open /home/simon/dev/astropy/astropy/utils/iers/data/Leap_Second.dat
expires: 2021-06-28

which is fine. And this for a Sphinx build:

open erfa
expires: 2017-06-30 00:00:00.000
open /home/simon/dev/astropy/astropy/utils/iers/data/Leap_Second.dat
ERROR: time data '28 June 2021' does not match format '%d %B %Y'
open https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
ERROR: time data '28 June 2021' does not match format '%d %B %Y'
open https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
Downloading https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
|==========================================================| 1.3k/1.3k (100.00%)         0s
ERROR: time data '28 June 2021' does not match format '%d %B %Y'
open https://www.ietf.org/timezones/data/leap-seconds.list
Downloading https://www.ietf.org/timezones/data/leap-seconds.list [Done]
ERROR: time data '28 June 2021' does not match format '%d %B %Y'
WARNING: IERSStaleWarning: leap-second file is expired. [astropy.utils.iers.iers]

So when running with Sphinx, there is a parsing error with the Leap_Second.dat file, which lead to this:

ipdb> Time.strptime('28 June 2021', '%d %B %Y', scale='tai', format='iso', out_subfmt='date')
*** ValueError: time data '28 June 2021' does not match format '%d %B %Y'

%B is the Locale's full month name, but in both case my locale if fr_FR.
Diving deeper leads to _strptime.py where _getlang returns None in one case and fr_FR in the other, the latter resulting in a regex with French month names 🎉
And I guess Sphinx is setting LC_TIME to the default locale, which triggers the error in _strptime.py.

@saimn saimn added the Bug label Nov 19, 2020
@saimn saimn added this to the v4.0.4 milestone Nov 19, 2020
@saimn saimn requested a review from mhvk November 19, 2020 22:39
@github-actions github-actions bot removed the utils label Nov 19, 2020
@pllim
Copy link
Member

pllim commented Nov 19, 2020

How interesting! There should be a change log. Not sure about a test, I'll let @mhvk decide.

@saimn
Copy link
Contributor Author

saimn commented Nov 19, 2020

Hmm, this is not yet done... Putting _set_locale in _read_leap_seconds as I did initially causes a race condition somewhere 😱 (the leap second tests get stuck). And moving it to Time.strptime works, but I don't know why and don't think we want this here, though having an option to force the locale in Time.strptime could be an option ?

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, sorry to have caused what must have been a hard bug to track down! I wish one could just tell strptime to use a given locale, but for some reason that is not possible.

I think we need to be a bit careful about the solution (though perhaps the worry about threading problems is overblown in this case...)

@@ -70,7 +70,7 @@ jobs:
python-version: ${{ matrix.python }}
- name: Install language-pack-de and tzdata
if: startsWith(matrix.os, 'ubuntu')
run: sudo apt-get install language-pack-de tzdata
run: sudo apt-get install language-pack-de language-pack-fr tzdata
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it make sense to use German for the tests so that we don't have to install another language pack (they're fairly large so this will slow down things).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another test using it (

def test_locale():
try:
with _set_locale('fr_FR'):
header = get_pkg_data_contents('data/locale.hdr',
encoding='binary')
with pytest.warns(FITSFixedWarning):
w = _wcs.Wcsprm(header)
assert re.search("[0-9]+,[0-9]*", w.to_header()) is None
except locale.Error:
pytest.xfail(
"Can't set to 'fr_FR' locale, perhaps because it is not installed "
"on this system")
), an old wcs bug, and it's easier for me to test locally that it works as expected ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can get rid of german instead!

scale='tai', format='iso',
out_subfmt='date')
try:
locale.setlocale(locale.LC_TIME, 'C')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, locale is quite explicit about not being thread safe. There is a suggested solution at https://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale, though I wonder if we are not better off just parsing it ourselves (as also suggested in various places). I think with a bit smarter regex this may just be possible........

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed, the thing is that when using _set_locale here the tests are stuck in a deadlock...
Maybe another soution to parse the date would be better:

If, when coding a module for general use, you need a locale independent version of an operation that is affected by the locale (such as certain formats used with time.strftime()), you will have to find a way to do it without using the standard library routine.
https://docs.python.org/3/library/locale.html#background-details-hints-tips-and-caveats

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that just changing the regex to return the three elements and then doing a simply lookup on the first three characters of the month should do it:

_re_expires = re.compile(r'^#.*File expires on[:\s]+(\d+\s\w+\s\d+)\s*$')

day, month, year = match.groups()[0].split()
month_nb = MONTH_ABBR.index(month[:3]) + 1
expires = Time(f'{year}-{month_nb:02d}-{day}',
scale='tai', out_subfmt='date')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhvk - Something like this ? 🔝

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@saimn
Copy link
Contributor Author

saimn commented Nov 25, 2020

About locale tests, the one in test_misc.py was skipped despite the de locale was installed, should be ok now. And the one in test_wcsprm.py was xfailed on master:

 ../../.tox/py37-test/lib/python3.7/site-packages/astropy/utils/tests/test_misc.py . [ 94%]
.s..s.  
../../.tox/py37-test/lib/python3.7/site-packages/astropy/wcs/tests/test_wcsprm.py . [ 97%]
........................................................................ [ 98%]
...........................x.....................................        [ 98%]

@saimn
Copy link
Contributor Author

saimn commented Nov 25, 2020

With the PR:

../../.tox/py37-test/lib/python3.7/site-packages/astropy/utils/tests/test_misc.py . [ 94%]
.s....                                                                   [ 94%]
../../.tox/py37-test/lib/python3.7/site-packages/astropy/io/ascii/tests/test_read.py . [ 22%]
........................................................................ [ 22%]
.......................................................................  [ 23%]
../../.tox/py37-test/lib/python3.7/site-packages/astropy/utils/iers/tests/test_leap_second.py . [ 92%]
.........ss..s...s.............                                          [ 93%]

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! Does need a changelog entry... And maybe squash the commits?

@bsipocz bsipocz modified the milestones: v4.0.4, v4.0.5 Nov 25, 2020
- A locale test in test_wcsprm already use fr_FR and was not run
- The tests in test_read and test_misc were not run on the CI, probably
  because of the missing encoding

So instead of installing two locales in the CI environment, migrate all
test to use fr_FR.
@saimn
Copy link
Contributor Author

saimn commented Nov 25, 2020

@mhvk - Done!

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, merging...

@mhvk mhvk merged commit b40aa18 into astropy:master Nov 26, 2020
@saimn saimn deleted the leap-second-locale branch November 26, 2020 01:33
astrofrog pushed a commit that referenced this pull request Mar 15, 2021
Fix leap second update when using a non english locale
eteq pushed a commit that referenced this pull request Mar 23, 2021
Fix leap second update when using a non english locale
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants