Skip to content

bpo-30647: Check nl_langinfo(CODESET) in locale coercion #2374

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

Merged

Conversation

ncoghlan
Copy link
Contributor

  • On some versions of FreeBSD, setting the "UTF-8" locale
    succeeds, but a subsequent "nl_langinfo(CODESET)" fails
  • adding a check for this in the coercion logic means that
    coercion will happen on systems where this check succeeds,
    and will be skipped otherwise
  • that way CPython should automatically adapt to changes in
    platform behaviour, rather than needing a new release to
    enable coercion at build time
  • this also allows UTF-8 to be re-enabled as a coercion
    target, restoring the locale coercion behaviour on Mac OS X

- On some versions of FreeBSD, setting the "UTF-8" locale
  succeeds, but a subsequent "nl_langinfo(CODESET)" fails
- adding a check for this in the coercion logic means that
  coercion will happen on systems where this check succeeds,
  and will be skipped otherwise
- that way CPython should automatically adapt to changes in
  platform behaviour, rather than needing a new release to
  enable coercion at build time
- this also allows UTF-8 to be re-enabled as a coercion
  target, restoring the locale coercion behaviour on Mac OS X
@mention-bot
Copy link

@ncoghlan, thanks for your PR! By analyzing the history of the files in this pull request, we identified @ericsnowcurrently, @vadmium and @zooba to be potential reviewers.

@ncoghlan
Copy link
Contributor Author

@ncoghlan
Copy link
Contributor Author

The test condition aimed at determining whether or not nl_langinfo worked in the candidate locales wasn't right, so I've tweaked it and kicked off a new custom build.

FreeBSD: http://buildbot.python.org/all/builders/AMD64%20FreeBSD%2010.x%20Shared%20custom/builds/16
Mac OS X: http://buildbot.python.org/all/builders/x86%20Tiger%20custom/builds/15

@ncoghlan ncoghlan changed the title bpo-30647: Check nl_langinfo(CODESET) in locale coercion WIP: bpo-30647: Check nl_langinfo(CODESET) in locale coercion Jun 24, 2017
@ncoghlan ncoghlan self-assigned this Jun 24, 2017
@ncoghlan
Copy link
Contributor Author

ncoghlan commented Jun 24, 2017

OK, this is looking reasonably promising now: test_c_locale_coercion passed on both Mac OS X and FreeBSD, and the other custom buildbots remain green. test_readline did fail on FreeBSD, and that may be a real bug and/or change in behaviour.

However, the adaptive nature of the tests mean they're also quite vulnerable to nominally passing without actually testing anything, so I'm going to adjust the test case to skip the nl_langinfo check on Linux and Mac OS X.

ncoghlan added 3 commits June 25, 2017 00:04
The problem with dynamically adaptive tests is that they
can sometimes pass without actually testing anything useful.

On Linux and Mac OS X, if setlocale works, we also expect
nl_langinfo(CODESET) to *always* work for the coercion target
locales. The tests now reflect this by always assuming the
target locale will work if setlocale succeeds when running
on Linux or Mac OS X.
@ncoghlan
Copy link
Contributor Author

This looks good on Mac OS X now, but I'm not going to merge it until the FreeBSD 10 custom builder is back online: https://mail.python.org/pipermail/python-buildbots/2017-June/000121.html

@ncoghlan ncoghlan requested a review from vstinner June 25, 2017 06:31
@ncoghlan
Copy link
Contributor Author

The FreeBSD 10 bot is back, and still showing the test_readline failure, so this isn't mergeable in its current form: http://buildbot.python.org/all/builders/AMD64%20FreeBSD%2010.x%20Shared%20custom/builds/18/steps/test/logs/stdio

@ncoghlan
Copy link
Contributor Author

ncoghlan commented Jun 28, 2017

I'm finally setting up a local FreeBSD 10 box in Vagrant, so hopefully I'll be able to work out a sensible way to handle FreeBSD's current behaviour (and hopefully whatever I come up with generalise reasonably to other BSD variants)

Current status: the unexpectedly failing tests turned out to be due to the VM having neither a hostname nor a local timezone set. The symptoms were a bit cryptic - the former resulted in an empty string from socket.gethostname(), which triggers a "Unknown server name" exception if you pass it to socker.gethostbyname_ex(), while the latter leads to an overflow error in time.mktime() if you pass it a time tuple where the is_dst flag is set to 1.

@ncoghlan
Copy link
Contributor Author

Experimenting locally, I was able to confirm that the following sequence of commands triggers the test_readline failure:

const char *initial_locale = setlocale(LC_CTYPE, NULL);
setlocale(LC_CTYPE, "UTF-8");
setlocale(LC_CTYPE, initial_locale);

The same failure also occurs if the second call uses a normal locale like en_US.UTF-8.

However, I'm also seeing a behaviour where if I print initial_locale before and after the second call to set_locale, the content of the string changes to match the newly set locale...

Saving and restoring the environment when nl_langinfo
fails doesn't work as intended on at least FreeBSD,
and potentially other systems as well.

Configuring the locale from the environment in this
case does the right thing (since we make the exact
same call later on in Py_Initialize anyway)
@ncoghlan
Copy link
Contributor Author

While the save-and-restore approach proved fruitless, it occurred to me that we haven't modified the environment at this point, so we can use that to restore the original locale settings.

Custom FreeBSD buildbot run for the latest variant: http://buildbot.python.org/all/builders/AMD64%20FreeBSD%2010.x%20Shared%20custom/builds/19/steps/test/logs/stdio

@ncoghlan ncoghlan changed the title WIP: bpo-30647: Check nl_langinfo(CODESET) in locale coercion bpo-30647: Check nl_langinfo(CODESET) in locale coercion Jun 29, 2017
@ncoghlan ncoghlan merged commit 18974c3 into python:master Jun 29, 2017
yan12125 added a commit to yan12125/python3-android that referenced this pull request Jun 30, 2017
@ncoghlan ncoghlan deleted the bpo-30647-skip-coercion-if-nl-langinfo-fails branch March 30, 2018 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants