Skip to content

bpo-40503: Add compile-time configuration to PEP 615 #20034

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

Closed
wants to merge 28 commits into from

Conversation

pganssle
Copy link
Member

@pganssle pganssle commented May 11, 2020

This is the implementation for PEP 615's support for compile-time configuration of the time zone search path.

The main implementation is in #19909 — at the moment it's not merged so unfortunately the commits are also present in this PR until that one gets merged. I couldn't come up with a good way to both have a neat diff and run the CI, so I went with running the CI.

The relevant changes are the ones starting with the commit "Add --with-tzpath to autoconf"

https://bugs.python.org/issue40503

configure.ac Outdated
validate_tzpath() {
# Check that each element of the tzpath is an absolute path
all_paths=$1
while test "${all_paths#*:}" != "$1"; do
Copy link
Member

Choose a reason for hiding this comment

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

The comparison to "$1" confuses me. $all_paths starts out as $1, and you're only removing things, so surely this loop would never end? It also feels like you could do this with grep instead:

if ( echo $1 | grep -qE '(^|:)([^/]|$)' ); then
AC_MSG_ERROR(...);
return 1;
fi

(There are already other uses of grep -E in configure.ac, so I think it's safe to rely on.)

Copy link
Member Author

Choose a reason for hiding this comment

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

I like it, though it was annoyingly tricky to pull off. It took me forever to realize that autoconf was stripping out the [] characters from the grep string.

configure.ac Outdated
;;
esac
],
[AC_MSG_RESULT(default)])
Copy link
Member

Choose a reason for hiding this comment

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

Add $TZPATH in the message here, so you can see what that default is?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. I originally had it this way, but then I played around with the possibility of using something closer to the previous logic, where if TZPATH is not explicitly set, at runtime the module will order the path based on a hard-coded string where the order is determined by which directories exist at import time. In that case, "default" made more sense than any hard-coded string.

I abandoned that approach as YAGNI — if we want to do something like that, we should probably just do it at build time anyway.

@pganssle pganssle force-pushed the zoneinfo_compile_config branch from 91cb1dd to e3a52c6 Compare May 12, 2020 13:46
pganssle added 3 commits May 12, 2020 10:09
The import machinery can be somewhat fragile, and the "seamlessly falls
back to pure Python" nature of this module makes it so that a problem
building the C extension or a failure to import the pure Python version
might easily go unnoticed.

This adds some "smoke tests" that rely on implementation details of each
module to ensure that we're building the ones we think we are.
This should improve support on Windows, including actually building the C
extension.
Copy link
Member

@Yhg1s Yhg1s left a comment

Choose a reason for hiding this comment

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

LG for the configure changes (for UNIX; not sure if more should be done for Windows).

configure.ac Outdated
TZPATH="/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo"
AC_MSG_CHECKING(for --with-tzpath)
AC_ARG_WITH(tzpath,
AS_HELP_STRING([--with-tzpath=<list of relative paths separated by pathsep>]
Copy link
Member

Choose a reason for hiding this comment

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

Absolute paths, yes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hah, oops! Good catch.

@pganssle pganssle force-pushed the zoneinfo_compile_config branch from e3a52c6 to cb54267 Compare May 12, 2020 16:52
@pganssle pganssle requested a review from a team as a code owner May 12, 2020 16:52
Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

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

Windows build changes look fine, thanks for getting the installer!

- name: Install test dependencies
run: |
.\python.bat -m ensurepip --user
.\python.bat -m pip install --user -r Misc/requirements-test.txt
Copy link
Member

Choose a reason for hiding this comment

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

As we discussed, I don't like relying on pip to install into the source tree before we've run the test suite.

In general, system-wide dependencies are installed using the system package manager, or downloaded using specialised scripts and an existing Python installation (see PCbuild/get-externals.py). This would be a new network dependency, and I'd rather keep us to things that are checked in or directly grabbed from GitHub.

@@ -48,6 +48,7 @@ jobs:
./python -m venv .venv
source ./.venv/bin/activate
python -m pip install -U coverage
python -m pip install -r Misc/requirements-test.txt
Copy link
Member

Choose a reason for hiding this comment

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

Also as discussed, coverage is the one exception, but it's also not a core part of the PR workflow. We already switch CI providers for PRs every time Victor gets annoyed at network instability, so let's try and keep PR clean. We can leave it in the post-merge workflow if you really want.

@@ -546,6 +546,7 @@ def get_config_vars(*args):

if os.name == 'nt':
_init_non_posix(_CONFIG_VARS)
_CONFIG_VARS['TZPATH'] = ''
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we just .get() it rather than assuming it'll be set?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we should be guaranteeing that it's set, and it should be an error condition otherwise. The "reasonable default" varies by platform, and can be configured at build time.

On Windows, the reasonable default is actually an empty string (no tzdata), but also I'd like to add it as a flag at build time.

TZPATH_TEST_LOCK = threading.Lock()


def call_once(f):
Copy link
Member

Choose a reason for hiding this comment

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

:trollface:

from ._common import ZoneInfoNotFoundError

try:
from _czoneinfo import ZoneInfo
Copy link
Member

Choose a reason for hiding this comment

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

We normally just use the underscore prefix to indicate an accelerator module. The c prefix hasn't really been used since 3.0

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a slightly more complicated situation, because _czoneinfo is actually parallel to zoneinfo._zoneinfo. In the reference implementation, the two are zoneinfo._zoneinfo and zoneinfo._czoneinfo, but the limitations of our current build system prevent me from doing that here.

+ day
)

# TODO: These are not actually epoch dates as they are expressed in local time
Copy link
Member

Choose a reason for hiding this comment

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

Does this TODO need to be fixed?

Copy link
Member Author

Choose a reason for hiding this comment

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

At some point, but this is a method on a private class and the only issue is that the name is slightly misleading, so it's not in the critical path to an MVP.

pganssle added 3 commits May 12, 2020 18:03
This is configurable only on POSIX systems at the moment and TZPATH is
initialized to an empty string on Windows.
@pganssle pganssle force-pushed the zoneinfo_compile_config branch from cb54267 to ddb8244 Compare May 12, 2020 22:08
@pganssle
Copy link
Member Author

OK, I expected this to take longer than it actually did, but it looks like this is resolved, so I've gone ahead and cherry-picked the commit back into #19909.

Thanks @zooba and @Yhg1s

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.

5 participants