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
Add hardcoded paths to macOS frameworks for Big Sur compatibility. #1905
Conversation
ctypes.util.find_library is checking for the presence of the framework files, which will fail due to macOS Big Sur's "dynamic linker cache". Since these files really can't be anywhere else, we just hardcode the path and load them. See: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes (relevent excerpt provided below) This update takes the approach of leaving the existing behavior as is for macOS 10.8 (lowest supported version) through 10.15. Allegedly Apple is going to number Big Sur as macOS 11, although right now the beta returns a version of "10.16", so this code handles both as being greater than or equal to "10.16". | New in macOS Big Sur 11 beta, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. (62986286)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, thanks! How did you notice this issue? Are you running Big Sur and can confirm that this change works?
I do a lot with Saltstack's macOS working group, and I have a project for making requests Sessions that use the macOS keychain for mutual TLS and cert verification; there have been a lot of projects that use either PyObjC or ctypes directly to get at the macOS frameworks, and the failures are all pretty much due to checking for the existence of the files (which aren't there). I have a Big Sur 10.16 beta2 machine on my desk that I tested this change out on. I wanted to get this out there; obviously there's some time. If anyone wants to direct me in any way, the version check and importing code could probably be cleaned up a bit. I mostly wanted to at least get a working POC out there. |
Just chiming in to thank you for raising this issue to our attention and for providing a fix. We'll be sure to backport to 1.25-series and get a release out there before Big Sur is released. |
👍🏻 I hate leaving it with a kind of speculative version check... May be 10.16, may be 11... wait until September! |
According to this answer by an Apple engineer, it will be 11. But it's good if it works on the beta too, so we can leave 10.16 until the release. |
@sheagcraig As long as the last released version we know of is 10.15 I'm fine with leaving the version check to be less restrictive. Sometimes with these things you have to cover all your bases. Another way we could go about this is only doing the version lookup after a failed |
Cool @pquentin. And yes @sethmlarson, that sounds like a plan. I'll see if I can cut out some of the repetition. I wasn't sure initially if the linter would be cranky with me for having the version check earlier, so I'll give it a little polish. |
I have a contact at Apple that I'll ask about this; maybe we could use the hardcoded paths back further due to SIP making it very unlikely that those paths are anything but what we expect. |
This should never be anything but these paths. Instead of checking for `os.path.isfile` with `ctypes.util.find_library`, we just try to load with `ctypes.CDLL` and catch the `OSError` if it fails, add context, and reraise.
Well try this on for size. So I looked through But the paths have been the same for all of the versions supported by the existing code (10.8+), and shouldn't be anywhere else. So I just cleaned out a lot of the version conditionals and went straight to trying to load the libraries. If it fails to load for some reason, we catch the I also added a check to make sure we're even on macOS before going any further through the module. I'm super green on urllib3 proper; I've poked around in the secure transport code a fair bit... But I guess I don't know why this was causing tests to fail on non-macOS, as the new code should have had the same behavior as the old? Regardless, this last couple of commits sidesteps that issue. |
If this looks good, I'll yank that new test file too, since it basically does nothing now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thought from me, let me know what you think and if you could give it a test locally :)
@@ -0,0 +1,26 @@ | |||
# -*- coding: utf-8 -*- | |||
import mock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this test script now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIth the changes to retain the pre-Big Sur behavior, do it still make sense to take the test out?
Hah; well I just put your suggested changes in. It's fine like that! |
I went ahead and made some changes myself on the branch:
|
Codecov Report
@@ Coverage Diff @@
## master #1905 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 23 23
Lines 2049 2055 +6
=========================================
+ Hits 2049 2055 +6
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
@sethmlarson can't merge myself until you dismiss your review. Thanks for finishing this! |
Thanks for the review @pquentin :) |
…ity. (urllib3#1905) ctypes.util.find_library is checking for the presence of the framework files, which will fail due to macOS Big Sur's "dynamic linker cache". Since these files really can't be anywhere else, we just hardcode the path and load them. See: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes (relevent excerpt provided below) This update takes the approach of leaving the existing behavior as is for macOS 10.8 (lowest supported version) through 10.15. Allegedly Apple is going to number Big Sur as macOS 11, although right now the beta returns a version of "10.16", so this code handles both as being greater than or equal to "10.16". Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
Big Sur will be both 10.16 and 11.0, depending on context: https://eclecticlight.co/2020/07/21/big-sur-is-both-10-16-and-11-0-its-official/ |
…ity. (#1905) ctypes.util.find_library is checking for the presence of the framework files, which will fail due to macOS Big Sur's "dynamic linker cache". Since these files really can't be anywhere else, we just hardcode the path and load them. See: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes (relevent excerpt provided below) This update takes the approach of leaving the existing behavior as is for macOS 10.8 (lowest supported version) through 10.15. Allegedly Apple is going to number Big Sur as macOS 11, although right now the beta returns a version of "10.16", so this code handles both as being greater than or equal to "10.16". Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
…rllib3#1905) * Add hardcoded paths to macOS frameworks for Big Sur compatibility. ctypes.util.find_library is checking for the presence of the framework files, which will fail due to macOS Big Sur's "dynamic linker cache". Since these files really can't be anywhere else, we just hardcode the path and load them. See: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes (relevent excerpt provided below) This update takes the approach of leaving the existing behavior as is for macOS 10.8 (lowest supported version) through 10.15. Allegedly Apple is going to number Big Sur as macOS 11, although right now the beta returns a version of "10.16", so this code handles both as being greater than or equal to "10.16". | New in macOS Big Sur 11 beta, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. (62986286) * Raise an OSError if not on macOS and trying to import securetransport * Just use hardcoded paths for Security and CoreFoundation libs. This should never be anything but these paths. Instead of checking for `os.path.isfile` with `ctypes.util.find_library`, we just try to load with `ctypes.CDLL` and catch the `OSError` if it fails, add context, and reraise. * Updated to preserve pre-10.16 behavior. * Bail early on non-macOS. * Restore find_library import, OSError -> ImportError * ImportError * OSError * Delete test_securetransport_big_sur.py Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
ctypes.util.find_library is checking for the presence of the framework
files, which will fail due to macOS Big Sur's "dynamic linker cache".
Since these files really can't be anywhere else, we just hardcode the
path and load them. (see #1904 )
See: https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes
(relevent excerpt provided below)
This update takes the approach of leaving the existing behavior as is
for macOS 10.8 (lowest supported version) through 10.15.
Allegedly Apple is going to number Big Sur as macOS 11, although right
now the beta returns a version of "10.16", so this code handles both as
being greater than or equal to "10.16".
| New in macOS Big Sur 11 beta, the system ships with a built-in dynamic
linker cache of all system-provided libraries. As part of this change,
copies of dynamic libraries are no longer present on the filesystem.
Code that attempts to check for dynamic library presence by looking for
a file at a path or enumerating a directory will fail. Instead, check
for library presence by attempting to dlopen() the path, which will
correctly check for the library in the cache. (62986286)