Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Commit

Permalink
[email protected]: Port formula fixes from upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
lithammer committed Dec 28, 2020
1 parent 0b03e1f commit 1ab8420
Showing 1 changed file with 156 additions and 73 deletions.
229 changes: 156 additions & 73 deletions Formula/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]_1"
Expand All @@ -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
Expand All @@ -37,12 +45,27 @@ 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"
sha256 "ed0519d27a243843b05d82a5e9d01b0b083d9934eaa3d02779a23da18077bd3c"
url "https://files.pythonhosted.org/packages/ea/81/a7428efddb7bac2db7969cc02c94d89f57a98acdc0b6f760c7e123234ab5/setuptools-51.1.0.tar.gz"
sha256 "b4f6f2e65bbdb66452f6f94da46a436da962da3ec1f8a412fdba3bcd4fdc4eb7"
end

resource "pip" do
Expand All @@ -51,8 +74,26 @@ class PythonAT35 < Formula
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
Expand All @@ -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["[email protected]"].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
Expand Down Expand Up @@ -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)
Expand All @@ -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.
Expand All @@ -199,31 +245,66 @@ 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|
(libexec/"bin").install_symlink (bin/versioned_name).realpath => unversioned_name
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

Expand All @@ -233,7 +314,7 @@ def post_install
library_dirs = [HOMEBREW_PREFIX/"lib", Formula["[email protected]"].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]
Expand All @@ -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!
Expand All @@ -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 <package>
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

0 comments on commit 1ab8420

Please sign in to comment.