From 0ff8f8769cf2fba149ee6a19a10c16577f1c845b Mon Sep 17 00:00:00 2001 From: Peter Lithammer Date: Mon, 21 Dec 2020 09:25:54 +0100 Subject: [PATCH] python@3.5: Port formula fixes from upstream --- Formula/python@3.5.rb | 229 ++++++++++++++++++++++++++++-------------- 1 file changed, 156 insertions(+), 73 deletions(-) diff --git a/Formula/python@3.5.rb b/Formula/python@3.5.rb index 16b9f83..50d5ae7 100644 --- a/Formula/python@3.5.rb +++ b/Formula/python@3.5.rb @@ -3,7 +3,13 @@ class PythonAT35 < Formula homepage "https://www.python.org/" url "https://www.python.org/ftp/python/3.5.10/Python-3.5.10.tar.xz" sha256 "0f0fa8685c1dc1f1dacb0b4e7779796b90aef99dc1fa4967a71b9da7b57d4a28" - revision 1 + license "Python-2.0" + revision 2 + + livecheck do + url "https://www.python.org/ftp/python/" + regex(%r{href=.*?v?(3\.5(?:\.\d+)*)/?["' >]}i) + end bottle do root_url "https://github.com/lithammer/homebrew-deadsnakes/releases/download/python@3.5-3.5.10_1" @@ -14,12 +20,14 @@ class PythonAT35 < Formula # setuptools remembers the build flags python is built with and uses them to # build packages later. Xcode-only systems need different flags. pour_bottle? do - reason <<~EOS - The bottle needs the Apple Command Line Tools to be installed. - You can install them, if desired, with: - xcode-select --install - EOS - satisfy { MacOS::CLT.installed? } + on_macos do + reason <<~EOS + The bottle needs the Apple Command Line Tools to be installed. + You can install them, if desired, with: + xcode-select --install + EOS + satisfy { MacOS::CLT.installed? } + end end keg_only :versioned_formula @@ -37,8 +45,23 @@ class PythonAT35 < Formula uses_from_macos "unzip" uses_from_macos "zlib" - skip_clean "bin/pip3", "bin/pip-3.5" - skip_clean "bin/easy_install3", "bin/easy_install-3.5" + skip_clean "bin/pip3", "bin/pip-3.4" + skip_clean "bin/easy_install3", "bin/easy_install-3.4" + + link_overwrite "bin/2to3" + link_overwrite "bin/idle3" + link_overwrite "bin/pip3" + link_overwrite "bin/pydoc3" + link_overwrite "bin/python3" + link_overwrite "bin/python3-config" + link_overwrite "bin/wheel3" + link_overwrite "share/man/man1/python3.1" + link_overwrite "lib/pkgconfig/python3.pc" + link_overwrite "lib/pkgconfig/python3-embed.pc" + link_overwrite "Frameworks/Python.framework/Headers" + link_overwrite "Frameworks/Python.framework/Python" + link_overwrite "Frameworks/Python.framework/Resources" + link_overwrite "Frameworks/Python.framework/Versions/Current" resource "setuptools" do url "https://files.pythonhosted.org/packages/a7/e0/30642b9c2df516506d40b563b0cbd080c49c6b3f11a70b4c7a670f13a78b/setuptools-50.3.2.zip" @@ -46,13 +69,31 @@ class PythonAT35 < Formula end resource "pip" do - url "https://files.pythonhosted.org/packages/0b/f5/be8e741434a4bf4ce5dbc235aa28ed0666178ea8986ddc10d035023744e6/pip-20.2.4.tar.gz" - sha256 "85c99a857ea0fb0aedf23833d9be5c40cf253fe24443f0829c7b472e23c364a1" + url "https://files.pythonhosted.org/packages/ca/1e/d91d7aae44d00cd5001957a1473e4e4b7d1d0f072d1af7c34b5899c9ccdf/pip-20.3.3.tar.gz" + sha256 "79c1ac8a9dccbec8752761cb5a2df833224263ca661477a2a9ed03ddf4e0e3ba" end resource "wheel" do - url "https://files.pythonhosted.org/packages/d4/cf/732e05dce1e37b63d54d1836160b6e24fb36eeff2313e93315ad047c7d90/wheel-0.36.1.tar.gz" - sha256 "aaef9b8c36db72f8bf7f1e54f85f875c4d466819940863ca0b3f3f77f0a1646f" + url "https://files.pythonhosted.org/packages/ed/46/e298a50dde405e1c202e316fa6a3015ff9288423661d7ea5e8f22f589071/wheel-0.36.2.tar.gz" + sha256 "e11eefd162658ea59a60a0f6c7d493a7190ea4b9a85e335b33489d9f17e0245e" + end + + def lib_cellar + on_macos do + return prefix/"Frameworks/Python.framework/Versions/#{version.major_minor}/lib/python#{version.major_minor}" + end + on_linux do + return prefix/"lib/python#{version.major_minor}" + end + end + + def site_packages_cellar + lib_cellar/"site-packages" + end + + # The HOMEBREW_PREFIX location of site-packages. + def site_packages + HOMEBREW_PREFIX/"lib/python#{version.major_minor}/site-packages" end def install @@ -61,24 +102,29 @@ def install ENV["PYTHONHOME"] = nil ENV["PYTHONPATH"] = nil - xy = (buildpath/"configure.ac").read.slice(/PYTHON_VERSION, (3\.\d)/, 1) - lib_cellar = prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}" - args = %W[ --prefix=#{prefix} --enable-ipv6 --datarootdir=#{share} --datadir=#{share} - --enable-framework=#{frameworks} --enable-loadable-sqlite-extensions - --without-ensurepip - --with-dtrace --with-openssl=#{Formula["openssl@1.1"].opt_prefix} ] - cflags = [] - ldflags = [] - cppflags = [] + on_macos do + args << "--enable-framework=#{frameworks}" + args << "--with-dtrace" + end + on_linux do + args << "--enable-shared" + # Required for the _ctypes module + # see https://github.com/Linuxbrew/homebrew-core/pull/1007#issuecomment-252421573 + args << "--with-system-ffi" + end + + cflags = ["-I#{HOMEBREW_PREFIX}/include"] + ldflags = ["-L#{HOMEBREW_PREFIX}/lib"] + cppflags = ["-I#{HOMEBREW_PREFIX}/include"] if MacOS.sdk_path_if_needed # Help Python's build system (setuptools/pip) to build things on SDK-based systems @@ -128,28 +174,32 @@ def install ENV.deparallelize do # Tell Python not to install into /Applications (default for framework builds) system "make", "install", "PYTHONAPPSDIR=#{prefix}" - system "make", "frameworkinstallextras", "PYTHONAPPSDIR=#{pkgshare}" + on_macos do + system "make", "frameworkinstallextras", "PYTHONAPPSDIR=#{pkgshare}" + end end # Any .app get a " 3" attached, so it does not conflict with python 2.x. Dir.glob("#{prefix}/*.app") { |app| mv app, app.sub(/\.app$/, " 3.app") } - # Prevent third-party packages from building against fragile Cellar paths - inreplace Dir[lib_cellar/"**/_sysconfigdata_m_darwin_darwin.py", - lib_cellar/"config*/Makefile", - frameworks/"Python.framework/Versions/3*/lib/pkgconfig/python-3.?.pc"], - prefix, opt_prefix - - # Help third-party packages find the Python framework - inreplace Dir[lib_cellar/"config*/Makefile"], - /^LINKFORSHARED=(.*)PYTHONFRAMEWORKDIR(.*)/, - "LINKFORSHARED=\\1PYTHONFRAMEWORKINSTALLDIR\\2" + on_macos do + # Prevent third-party packages from building against fragile Cellar paths + inreplace Dir[lib_cellar/"**/_sysconfigdata_m_darwin_darwin.py", + lib_cellar/"config*/Makefile", + frameworks/"Python.framework/Versions/3*/lib/pkgconfig/python-3.?.pc"], + prefix, opt_prefix + + # Help third-party packages find the Python framework + inreplace Dir[lib_cellar/"config*/Makefile"], + /^LINKFORSHARED=(.*)PYTHONFRAMEWORKDIR(.*)/, + "LINKFORSHARED=\\1PYTHONFRAMEWORKINSTALLDIR\\2" + end # Symlink the pkgconfig files into HOMEBREW_PREFIX so they're accessible. - (lib/"pkgconfig").install_symlink Dir["#{frameworks}/Python.framework/Versions/#{xy}/lib/pkgconfig/*"] + (lib/"pkgconfig").install_symlink Dir["#{frameworks}/Python.framework/Versions/#{version.major_minor}/lib/pkgconfig/*"] # Remove the site-packages that Python created in its Cellar. - (prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/site-packages").rmtree + site_packages_cellar.rmtree %w[setuptools pip wheel].each do |r| (libexec/r).install resource(r) @@ -174,14 +224,10 @@ def install def post_install ENV.delete "PYTHONPATH" - xy = (prefix/"Frameworks/Python.framework/Versions").children.min.basename.to_s - site_packages = HOMEBREW_PREFIX/"lib/python#{xy}/site-packages" - site_packages_cellar = prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/site-packages" - # Fix up the site-packages so that user-installed Python software survives # minor updates, such as going from 3.3.2 to 3.3.3: - # Create a site-packages in HOMEBREW_PREFIX/lib/python#{xy}/site-packages + # Create a site-packages in HOMEBREW_PREFIX/lib/python#{version.major_minor}/site-packages site_packages.mkpath # Symlink the prefix site-packages into the cellar. @@ -199,23 +245,58 @@ def post_install rm_rf Dir["#{site_packages}/setuptools*"] rm_rf Dir["#{site_packages}/distribute*"] rm_rf Dir["#{site_packages}/pip[-_.][0-9]*", "#{site_packages}/pip"] - - %w[setuptools pip wheel].each do |pkg| - (libexec/pkg).cd do - system bin/"python3", "-s", "setup.py", "--no-user-cfg", "install", - "--force", "--verbose", "--install-scripts=#{bin}", - "--install-lib=#{site_packages}", - "--single-version-externally-managed", - "--record=installed.txt" + rm_rf Dir["#{site_packages}/wheel*"] + + system bin/"python3", "-m", "ensurepip" + + # Get set of ensurepip-installed files for later cleanup + ensurepip_files = Set.new(Dir["#{site_packages}/setuptools-*"]) + + Set.new(Dir["#{site_packages}/pip-*"]) + + Set.new(Dir["#{site_packages}/wheel-*"]) + + # Remove Homebrew distutils.cfg if it exists, since it prevents the subsequent + # pip install command from succeeding (it will be recreated afterwards anyways) + rm_f lib_cellar/"distutils/distutils.cfg" + + # Install desired versions of setuptools, pip, wheel using the version of + # pip bootstrapped by ensurepip + system bin/"python3", "-m", "pip", "install", "-v", "--global-option=--no-user-cfg", + "--install-option=--force", + "--install-option=--single-version-externally-managed", + "--install-option=--record=installed.txt", + "--upgrade", + "--verbose", + "--target=#{site_packages}", + libexec/"setuptools", + libexec/"pip", + libexec/"wheel" + + # Get set of files installed via pip install + pip_files = Set.new(Dir["#{site_packages}/setuptools-*"]) + + Set.new(Dir["#{site_packages}/pip-*"]) + + Set.new(Dir["#{site_packages}/wheel-*"]) + + # Clean up the bootstrapped copy of setuptools/pip provided by ensurepip. + # Also consider the corner case where our desired version of tools is + # the same as those provisioned via ensurepip. In this case, don't clean + # up, or else we'll have no working setuptools, pip, wheel + if pip_files != ensurepip_files + ensurepip_files.each do |dir| + rm_rf dir end end + # pip install with --target flag will just place the bin folder into the + # target, so move its contents into the appropriate location + mv (site_packages/"bin").children, bin + rmdir site_packages/"bin" + rm_rf [bin/"pip", bin/"easy_install"] mv bin/"wheel", bin/"wheel3" # Install unversioned symlinks in libexec/bin. { - "easy_install" => "easy_install-#{xy}", + "easy_install" => "easy_install-#{version.major_minor}", "pip" => "pip3", "wheel" => "wheel3", }.each do |unversioned_name, versioned_name| @@ -223,7 +304,7 @@ def post_install end # post_install happens after link - %W[python#{xy}].each do |e| + %W[python#{version.major_minor}].each do |e| (HOMEBREW_PREFIX/"bin").install_symlink bin/e end @@ -233,7 +314,7 @@ def post_install library_dirs = [HOMEBREW_PREFIX/"lib", Formula["openssl@1.1"].opt_lib, Formula["sqlite"].opt_lib] - cfg = prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/distutils/distutils.cfg" + cfg = lib_cellar/"distutils/distutils.cfg" cfg.atomic_write <<~EOS [install] @@ -245,8 +326,6 @@ def post_install end def sitecustomize - xy = (prefix/"Frameworks/Python.framework/Versions").children.min.basename.to_s - <<~EOS # This file is created by Homebrew and is executed on each python startup. # Don't print from here, or else python command line scripts may fail! @@ -266,52 +345,56 @@ def sitecustomize # Only do this for a brewed python: if os.path.realpath(sys.executable).startswith('#{rack}'): # Shuffle /Library site-packages to the end of sys.path - library_site = '/Library/Python/#{xy}/site-packages' + library_site = '/Library/Python/#{version.major_minor}/site-packages' library_packages = [p for p in sys.path if p.startswith(library_site)] sys.path = [p for p in sys.path if not p.startswith(library_site)] # .pth files have already been processed so don't use addsitedir sys.path.extend(library_packages) # the Cellar site-packages is a symlink to the HOMEBREW_PREFIX # site_packages; prefer the shorter paths - long_prefix = re.compile(r'#{rack}/[0-9\._abrc]+/Frameworks/Python\.framework/Versions/#{xy}/lib/python#{xy}/site-packages') - sys.path = [long_prefix.sub('#{HOMEBREW_PREFIX/"lib/python#{xy}/site-packages"}', p) for p in sys.path] - # Set the sys.executable to use the opt_prefix, unless explicitly set - # with PYTHONEXECUTABLE: - if 'PYTHONEXECUTABLE' not in os.environ: - sys.executable = '#{opt_bin}/python#{xy}' + long_prefix = re.compile(r'#{rack}/[0-9\._abrc]+/Frameworks/Python\.framework/Versions/#{version.major_minor}/lib/python#{version.major_minor}/site-packages') + sys.path = [long_prefix.sub('#{HOMEBREW_PREFIX/"lib/python#{version.major_minor}/site-packages"}', p) for p in sys.path] + # Set the sys.executable to use the opt_prefix. Only do this if PYTHONEXECUTABLE is not + # explicitly set and we are not in a virtualenv: + if 'PYTHONEXECUTABLE' not in os.environ and sys.prefix == sys.base_prefix: + sys.executable = '#{opt_bin}/python#{version.major_minor}' EOS end def caveats - xy = if prefix.exist? - (prefix/"Frameworks/Python.framework/Versions").children.min.basename.to_s - else - version.to_s.slice(/(3\.\d)/) || "3.5" - end <<~EOS Python has been installed as #{opt_bin}/python3 + Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to + `python3`, `python3-config`, `pip3` etc., respectively, have been installed into + #{opt_libexec}/bin + You can install Python packages with #{opt_bin}/pip3 install They will install into the site-package directory - #{prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/site-packages"} + #{HOMEBREW_PREFIX/"lib/python#{version.major_minor}/site-packages"} See: https://docs.brew.sh/Homebrew-and-Python EOS end test do - xy = (prefix/"Frameworks/Python.framework/Versions").children.min.basename.to_s # Check if sqlite is ok, because we build with --enable-loadable-sqlite-extensions # and it can occur that building sqlite silently fails if OSX's sqlite is used. - system "#{bin}/python#{xy}", "-c", "import sqlite3" + system "#{bin}/python#{version.major_minor}", "-c", "import sqlite3" + # Check if some other modules import. Then the linked libs are working. - system "#{bin}/python#{xy}", "-c", "import tkinter; root = tkinter.Tk()" - system "#{bin}/python#{xy}", "-c", "import _gdbm" - system "#{bin}/python#{xy}", "-c", "import zlib" - system "#{bin}/python#{xy}", "-c", "import hashlib" - system "#{bin}/python#{xy}", "-c", "import ssl" + system "#{bin}/python#{version.major_minor}", "-c", "import _gdbm" + system "#{bin}/python#{version.major_minor}", "-c", "import hashlib" + system "#{bin}/python#{version.major_minor}", "-c", "import ssl" + system "#{bin}/python#{version.major_minor}", "-c", "import zlib" + on_macos do + # Temporary failure on macOS 11.1 due to https://bugs.python.org/issue42480 + # Reenable unconditionnaly once Apple fixes the Tcl/Tk issue + system "#{bin}/python#{version.major_minor}", "-c", "import tkinter; root = tkinter.Tk()" if MacOS.full_version < "11.1" + end + system bin/"pip3", "list", "--format=columns" end end