Skip to content

Instantly share code, notes, and snippets.

@dukechem
Forked from SamuelMarks/python.rb
Last active February 11, 2020 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dukechem/ef5cb77d0b571eb0f794a4be821bd53c to your computer and use it in GitHub Desktop.
Save dukechem/ef5cb77d0b571eb0f794a4be821bd53c to your computer and use it in GitHub Desktop.
python3.6.9 brew formula. Proof of concept that generally fails: brew switch python3 does not really work right: i.e. pip3 fails. Use pyenv/miniconda instead.
class Python < Formula
desc "Interpreted, interactive, object-oriented programming language"
homepage "https://www.python.org/"
url "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz"
sha256 "5e2f5f554e3f8f7f0296f7e73d8600c4e9acbaee6b2555b83206edf5153870da"
revision 1
bottle do
sha256 "1bc5a2d3f0a8602bf2f46de7c43fcb6dde4f110c0f4518d4e802cb1f733a43de" => :high_sierra
sha256 "131d39120ac6ca2f21bf231de7414c08916cea472bc5219e0bcb49541f77cb9f" => :sierra
sha256 "b2584ea6f16c47fe3795745e9cae5a7762f750aa78c15cbe14736dcd2602b755" => :el_capitan
end
devel do
url "https://www.python.org/ftp/python/3.6.9/Python-3.6.9rc1.tar.xz"
sha256 "9fdfe695dda70d84f1e93e0dd285460e9aa3e8120532c933471cfd0dd4a3d382"
end
head do
url "https://github.com/python/cpython.git"
resource "blurb" do
url "https://files.pythonhosted.org/packages/f2/2d/541cf1d8054dbb320aca5e9dcce5d66efb227be9adb75d2697ee45d1f742/blurb-1.0.6.tar.gz"
sha256 "90c7d2e5d141d7d1fc6ca0fe660025317ac81ca078e6045c46b1bc5a675ce5d1"
end
end
option "with-tcl-tk", "Use Homebrew's Tk instead of macOS Tk (has optional Cocoa and threads support)"
deprecated_option "with-brewed-tk" => "with-tcl-tk"
depends_on "pkg-config" => :build
# python 3.6.8 formula from https://gist.github.com/SamuelMarks/0ceaaf6d3de12b6408e3e67aae80ae3b
depends_on "sphinx-doc" => :build # Error: python contains a recursive dependency on itself:
# python depends on sphinx-doc
# sphinx-doc depends on python
depends_on "gdbm"
depends_on "openssl"
depends_on "readline"
depends_on "sqlite"
depends_on "xz"
depends_on "tcl-tk" => :optional
skip_clean "bin/pip3", "bin/pip-3.4", "bin/pip-3.5", "bin/pip-3.6", "bin/pip-3.7"
skip_clean "bin/easy_install3", "bin/easy_install-3.4", "bin/easy_install-3.5", "bin/easy_install-3.6", "bin/easy_install-3.7"
resource "setuptools" do
url "https://files.pythonhosted.org/packages/1a/04/d6f1159feaccdfc508517dba1929eb93a2854de729fa68da9d5c6b48fa00/setuptools-39.2.0.zip"
sha256 "f7cddbb5f5c640311eb00eab6e849f7701fa70bf6a183fc8a2c33dd1d1672fb2"
end
resource "pip" do
url "https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz"
sha256 "f2bd08e0cd1b06e10218feaf6fef299f473ba706582eb3bd9d52203fdbd7ee68"
end
resource "wheel" do
url "https://files.pythonhosted.org/packages/2a/fb/aefe5d5dbc3f4fe1e815bcdb05cbaab19744d201bbc9b59cfa06ec7fc789/wheel-0.31.1.tar.gz"
sha256 "0a2e54558a0628f2145d2fc822137e322412115173e8a2ddbe1c9024338ae83c"
end
fails_with :clang do
build 425
cause "https://bugs.python.org/issue24844"
end
# Homebrew's tcl-tk is built in a standard unix fashion (due to link errors)
# so we have to stop python from searching for frameworks and linking against
# X11.
patch :DATA if build.with? "tcl-tk"
# 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? }
end
def install
# Unset these so that installing pip and setuptools puts them where we want
# and not into some other Python the user has installed.
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
]
args << "--without-gcc" if ENV.compiler == :clang
cflags = []
ldflags = []
cppflags = []
unless MacOS::CLT.installed?
# Help Python's build system (setuptools/pip) to build things on Xcode-only systems
# The setup.py looks at "-isysroot" to get the sysroot (and not at --sysroot)
cflags << "-isysroot #{MacOS.sdk_path}"
ldflags << "-isysroot #{MacOS.sdk_path}"
cppflags << "-I#{MacOS.sdk_path}/usr/include" # find zlib
# For the Xlib.h, Python needs this header dir with the system Tk
if build.without? "tcl-tk"
cflags << "-I#{MacOS.sdk_path}/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers"
end
end
# Avoid linking to libgcc https://mail.python.org/pipermail/python-dev/2012-February/116205.html
args << "MACOSX_DEPLOYMENT_TARGET=#{MacOS.version}"
# We want our readline! This is just to outsmart the detection code,
# superenv makes cc always find includes/libs!
inreplace "setup.py",
"do_readline = self.compiler.find_library_file(lib_dirs, 'readline')",
"do_readline = '#{Formula["readline"].opt_lib}/libhistory.dylib'"
if build.stable?
inreplace "setup.py", "/usr/local/ssl", Formula["openssl"].opt_prefix
else
args << "--with-openssl=#{Formula["openssl"].opt_prefix}"
end
inreplace "setup.py" do |s|
s.gsub! "sqlite_setup_debug = False", "sqlite_setup_debug = True"
s.gsub! "for d_ in inc_dirs + sqlite_inc_paths:",
"for d_ in ['#{Formula["sqlite"].opt_include}']:"
end
# Allow python modules to use ctypes.find_library to find homebrew's stuff
# even if homebrew is not a /usr/local/lib. Try this with:
# `brew install enchant && pip install pyenchant`
inreplace "./Lib/ctypes/macholib/dyld.py" do |f|
f.gsub! "DEFAULT_LIBRARY_FALLBACK = [", "DEFAULT_LIBRARY_FALLBACK = [ '#{HOMEBREW_PREFIX}/lib',"
f.gsub! "DEFAULT_FRAMEWORK_FALLBACK = [", "DEFAULT_FRAMEWORK_FALLBACK = [ '#{HOMEBREW_PREFIX}/Frameworks',"
end
if build.with? "tcl-tk"
tcl_tk = Formula["tcl-tk"].opt_prefix
cppflags << "-I#{tcl_tk}/include"
ldflags << "-L#{tcl_tk}/lib"
end
args << "CFLAGS=#{cflags.join(" ")}" unless cflags.empty?
args << "LDFLAGS=#{ldflags.join(" ")}" unless ldflags.empty?
args << "CPPFLAGS=#{cppflags.join(" ")}" unless cppflags.empty?
system "./configure", *args
system "make"
ENV.deparallelize do
# Tell Python not to install into /Applications (default for framework builds)
system "make", "install", "PYTHONAPPSDIR=#{prefix}"
system "make", "frameworkinstallextras", "PYTHONAPPSDIR=#{pkgshare}"
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"
# Fix for https://github.com/Homebrew/homebrew-core/issues/21212
inreplace Dir[lib_cellar/"**/_sysconfigdata_m_darwin_darwin.py"],
%r{('LINKFORSHARED': .*?)'(Python.framework/Versions/3.\d+/Python)'}m,
"\\1'#{opt_prefix}/Frameworks/\\2'"
# A fix, because python and python3 both want to install Python.framework
# and therefore we can't link both into HOMEBREW_PREFIX/Frameworks
# https://github.com/Homebrew/homebrew/issues/15943
["Headers", "Python", "Resources"].each { |f| rm(prefix/"Frameworks/Python.framework/#{f}") }
rm prefix/"Frameworks/Python.framework/Versions/Current"
# Symlink the pkgconfig files into HOMEBREW_PREFIX so they're accessible.
(lib/"pkgconfig").install_symlink Dir["#{frameworks}/Python.framework/Versions/#{xy}/lib/pkgconfig/*"]
# Remove the site-packages that Python created in its Cellar.
(prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/site-packages").rmtree
%w[setuptools pip wheel].each do |r|
(libexec/r).install resource(r)
end
cd "Doc" do
if build.head?
system bin/"python3", "-m", "venv", "./venv"
resource("blurb").stage do
system buildpath/"Doc/venv/bin/python3", "-m", "pip", "install", "-v",
"--no-deps", "--no-binary", ":all", "--ignore-installed", "."
end
end
system "make", "html"
doc.install Dir["build/html/*"]
end
# Install unversioned symlinks in libexec/bin.
{
"idle" => "idle3",
"pydoc" => "pydoc3",
"python" => "python3",
"python-config" => "python3-config",
}.each do |unversioned_name, versioned_name|
(libexec/"bin").install_symlink (bin/versioned_name).realpath => unversioned_name
end
end
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
site_packages.mkpath
# Symlink the prefix site-packages into the cellar.
site_packages_cellar.unlink if site_packages_cellar.exist?
site_packages_cellar.parent.install_symlink site_packages
# Write our sitecustomize.py
rm_rf Dir["#{site_packages}/sitecustomize.py[co]"]
(site_packages/"sitecustomize.py").atomic_write(sitecustomize)
# Remove old setuptools installations that may still fly around and be
# listed in the easy_install.pth. This can break setuptools build with
# zipimport.ZipImportError: bad local file header
# setuptools-0.9.8-py3.3.egg
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"
end
end
rm_rf [bin/"pip", bin/"easy_install"]
mv bin/"wheel", bin/"wheel3"
# Install unversioned symlinks in libexec/bin.
{
"easy_install" => "easy_install-#{xy}",
"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[pip3 pip#{xy} easy_install-#{xy} wheel3].each do |e|
(HOMEBREW_PREFIX/"bin").install_symlink bin/e
end
# Help distutils find brewed stuff when building extensions
include_dirs = [HOMEBREW_PREFIX/"include", Formula["openssl"].opt_include,
Formula["sqlite"].opt_include]
library_dirs = [HOMEBREW_PREFIX/"lib", Formula["openssl"].opt_lib,
Formula["sqlite"].opt_lib]
if build.with? "tcl-tk"
include_dirs << Formula["tcl-tk"].opt_include
library_dirs << Formula["tcl-tk"].opt_lib
end
cfg = prefix/"Frameworks/Python.framework/Versions/#{xy}/lib/python#{xy}/distutils/distutils.cfg"
cfg.atomic_write <<~EOS
[install]
prefix=#{HOMEBREW_PREFIX}
[build_ext]
include_dirs=#{include_dirs.join ":"}
library_dirs=#{library_dirs.join ":"}
EOS
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!
# <https://docs.brew.sh/Homebrew-and-Python>
import re
import os
import sys
if sys.version_info[0] != 3:
# This can only happen if the user has set the PYTHONPATH for 3.x and run Python 2.x or vice versa.
# Every Python looks at the PYTHONPATH variable and we can't fix it here in sitecustomize.py,
# because the PYTHONPATH is evaluated after the sitecustomize.py. Many modules (e.g. PyQt4) are
# built only for a specific version of Python and will fail with cryptic error messages.
# In the end this means: Don't set the PYTHONPATH permanently if you use different Python versions.
exit('Your PYTHONPATH points to a site-packages dir for Python 3.x but you are running Python ' +
str(sys.version_info[0]) + '.x!\\n PYTHONPATH is currently: "' + str(os.environ['PYTHONPATH']) + '"\\n' +
' You should `unset PYTHONPATH` to fix this.')
# 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_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
sys.executable = '#{opt_bin}/python#{xy}'
EOS
end
def caveats
if prefix.exist?
xy = (prefix/"Frameworks/Python.framework/Versions").children.min.basename.to_s
else
xy = version.to_s.slice(/(3\.\d)/) || "3.6"
end
text = <<~EOS
Python has been installed as
#{HOMEBREW_PREFIX}/bin/python3
Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to
`python3`, `python3-config`, `pip3` etc., respectively, have been installed into
#{opt_libexec}/bin
If you need Homebrew's Python 2.7 run
brew install python@2
Pip, setuptools, and wheel have been installed. To update them run
pip3 install --upgrade pip setuptools wheel
You can install Python packages with
pip3 install <package>
They will install into the site-package directory
#{HOMEBREW_PREFIX/"lib/python#{xy}/site-packages"}
See: https://docs.brew.sh/Homebrew-and-Python
EOS
# Tk warning only for 10.6
tk_caveats = <<~EOS
Apple's Tcl/Tk is not recommended for use with Python on Mac OS X 10.6.
For more information see: https://www.python.org/download/mac/tcltk/
EOS
text += tk_caveats unless MacOS.version >= :lion
text
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"
# 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/"pip3", "list", "--format=columns"
end
end
__END__
diff --git a/setup.py b/setup.py
index 2779658..902d0eb 100644
--- a/setup.py
+++ b/setup.py
@@ -1699,9 +1699,6 @@ class PyBuildExt(build_ext):
# Rather than complicate the code below, detecting and building
# AquaTk is a separate method. Only one Tkinter will be built on
# Darwin - either AquaTk, if it is found, or X11 based Tk.
- if (host_platform == 'darwin' and
- self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
- return
# Assume we haven't found any of the libraries or include files
# The versions with dots are used on Unix, and the versions without
@@ -1747,22 +1744,6 @@ class PyBuildExt(build_ext):
if dir not in include_dirs:
include_dirs.append(dir)
- # Check for various platform-specific directories
- if host_platform == 'sunos5':
- include_dirs.append('/usr/openwin/include')
- added_lib_dirs.append('/usr/openwin/lib')
- elif os.path.exists('/usr/X11R6/include'):
- include_dirs.append('/usr/X11R6/include')
- added_lib_dirs.append('/usr/X11R6/lib64')
- added_lib_dirs.append('/usr/X11R6/lib')
- elif os.path.exists('/usr/X11R5/include'):
- include_dirs.append('/usr/X11R5/include')
- added_lib_dirs.append('/usr/X11R5/lib')
- else:
- # Assume default location for X11
- include_dirs.append('/usr/X11/include')
- added_lib_dirs.append('/usr/X11/lib')
-
# If Cygwin, then verify that X is installed before proceeding
if host_platform == 'cygwin':
x11_inc = find_file('X11/Xlib.h', [], include_dirs)
@@ -1786,10 +1767,6 @@ class PyBuildExt(build_ext):
if host_platform in ['aix3', 'aix4']:
libs.append('ld')
- # Finally, link with the X11 libraries (not appropriate on cygwin)
- if host_platform != "cygwin":
- libs.append('X11')
-
ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
define_macros=[('WITH_APPINIT', 1)] + defs,
include_dirs = include_dirs,
@dukechem
Copy link
Author

dukechem commented Aug 3, 2019

I could not get 3.6.8 to build from source with this line commented out:

depends_on "sphinx-doc" => :build `  # tells brew to make sphinx-build available in `buildpath`
brew install python --with-tcl-tkl  --ignore-dependencies  #  fails if you first " brew unlink python "

The make html at end fails without a working sphinx-build, with or without --ignore-dependencies

(For a linux cuda box, linuxbrew installed 3.6.8 just by editing to 3.6.8 the top few lines of python.rb file. But trickier with macos...)

To build 3.6.8 from source, need to first brew install python (to get 3.7.x), then pip3 install sphinx which creates /usr/local/bin/sphinx-build which is a Python script text executable (not a symlink). This sphinx-build is needed by make html during the 3.6.8 build, but will NOT run if you brew unlink python as brew install python insists. So in example below, we can brew link python in another terminal once we've started brew install python --with-tcl-tk to build 3.6.8 from source

\end tl:dr

=== DETAILS and TRANSCRIPT below ===
I needed a 3.6 python for tensorflow, as detailed at https://www.pyimagesearch.com/2019/01/30/macos-mojave-install-tensorflow-and-keras-for-deep-learning/ The 3.6.5 trick at above website works, but I wanted 3.6.8, likely the last 3.6.x release so as to have the most bug-free 3.6.x python to do pip3 install tensorflow-gpu. The example below is for a 10.13 macbook-pro with nvidia/cuda.

brew switch python 3.7.0
brew unlink python
brew edit python # and paste in the python.rb from this gisthub

https://gist.github.com/dukechem/ef5cb77d0b571eb0f794a4be821bd53c

brew install python --with-tcl-tk  # this will build python 3.6.8 per the gist python.rb formula
### once the config starts, open another terminal and do:
brew switch 3.7.0  #  

The brew switch allow make html to run sphinx-build without error, only failing at the end to link the 3.6.8 that was built. However brew switch 3.6.8 will work as shown in transcript below.

$ date
Sat Aug  3 19:20:51 EDT 2019
 student$ brew install  --with-tcl-tk python
Updating Homebrew...
Error: python 3.7.0 is already installed
To install 3.6.8_1, first run `brew unlink python`.
$ brew unlink python
$ brew install  --with-tcl-tk python  ### Once configure begins (below) do:  brew  switch  python 3.7.0 (in different terminal)  
Updating Homebrew...
==> Downloading https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/823e256de9f32d36f4a0349bfec734e6e7ca420b8dacc331ad18664cbd1d5fcc--Python-3.6.8.tar.xz
==> Patching
patching file setup.py
Hunk #1 succeeded at 1820 (offset 121 lines).
Hunk #2 succeeded at 1865 (offset 121 lines).
Hunk #3 succeeded at 1888 (offset 121 lines).
==> ./configure --prefix=/usr/local/Cellar/python/3.6.8_1 --enable-ipv6 --datarootdir=/usr/local/Cellar/python/3.6.8_1/share --datadir=/usr/local/Cellar/python/3.6.8_1/share --enable-f
==> make
==> make install PYTHONAPPSDIR=/usr/local/Cellar/python/3.6.8_1
==> make frameworkinstallextras PYTHONAPPSDIR=/usr/local/Cellar/python/3.6.8_1/share/python
==> Downloading https://files.pythonhosted.org/packages/1a/04/d6f1159feaccdfc508517dba1929eb93a2854de729fa68da9d5c6b48fa00/setuptools-39.2.0.zip
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/70eb364cb9b10112f2e5ed328d1456b0075d0dd06a211bb3c831bab55d88cbe1--setuptools-39.2.0.zip
==> Downloading https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/c51d1f8b1f2d396f90c5267323d17d1b4561aed67dadad03b6499ad4cde70fe7--pip-10.0.1.tar.gz
==> Downloading https://files.pythonhosted.org/packages/2a/fb/aefe5d5dbc3f4fe1e815bcdb05cbaab19744d201bbc9b59cfa06ec7fc789/wheel-0.31.1.tar.gz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/692113901ac5a4259d2158ae4b1de853f24f8029633d3d874c98ff7005d84460--wheel-0.31.1.tar.gz
==> make html
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.0
Error: Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.0

$   student$ python3 --version
Python 3.7.0
$ brew switch python 
Error: Usage: brew switch <formula> <version>
python installed versions: 3.6.5_1, 3.6.8_1, 3.7.0
$ brew switch python 3.6.8_1
Cleaning /usr/local/Cellar/python/3.6.8_1
Cleaning /usr/local/Cellar/python/3.7.0
Cleaning /usr/local/Cellar/python/3.6.5_1
21 links created for /usr/local/Cellar/python/3.6.8_1
$ 
$ brew postinstall python
==> Postinstalling python
==> /usr/local/Cellar/python/3.6.8_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.8_1/bin --install-lib=/usr/local/lib
==> /usr/local/Cellar/python/3.6.8_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.8_1/bin --install-lib=/usr/local/lib
==> /usr/local/Cellar/python/3.6.8_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.8_1/bin --install-lib=/usr/local/lib
$  
$ python3 --version
Python 3.6.8
$ which python3
/usr/local/bin/python3

Not sure I would risk a pip install --upgrade pip at this point ;-) Also can anyone explain with brew postinstall python does?

@dukechem
Copy link
Author

dukechem commented Aug 4, 2019

Updated from 3.6.8 to 3.6.9 and it still works same way... About 5 minutes is needed for "brew install python --with-tcl-tk" to finish.

$$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.6
$ brew install python --with-tcl-tk  
Updating Homebrew...
Error: python 3.6.8_1 is already installed
To install 3.6.9_1, first run `brew unlink python`.
$ brew unlink python  ### but not for more than a few seconds... just until "brew install python" gets past "Updating Homebrew..." 
$ brew install python --with-tcl-tk  ## Once "Updating" is done, open another terminal to do: "brew switch python 3.7.0"
Updating Homebrew...
==> Downloading https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/817fb4115d2dfd0831a1abe2946639cc9b7c8998a5dfdad3846335f5b98f4f6a--Python-3.6.9.tar.xz
==> Patching
patching file setup.py
Hunk #1 succeeded at 1820 (offset 121 lines).
Hunk #2 succeeded at 1865 (offset 121 lines).
Hunk #3 succeeded at 1888 (offset 121 lines).
==> ./configure --prefix=/usr/local/Cellar/python/3.6.9_1 --enable-ipv6 --datarootdir=/usr/local/Cellar/python/3.6.9_1/share --datadir=/usr/local/Cellar/python/3.6.9_1/share --enable-f
==> make
==> make install PYTHONAPPSDIR=/usr/local/Cellar/python/3.6.9_1
==> make frameworkinstallextras PYTHONAPPSDIR=/usr/local/Cellar/python/3.6.9_1/share/python
==> Downloading https://files.pythonhosted.org/packages/1a/04/d6f1159feaccdfc508517dba1929eb93a2854de729fa68da9d5c6b48fa00/setuptools-39.2.0.zip
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/70eb364cb9b10112f2e5ed328d1456b0075d0dd06a211bb3c831bab55d88cbe1--setuptools-39.2.0.zip
==> Downloading https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/c51d1f8b1f2d396f90c5267323d17d1b4561aed67dadad03b6499ad4cde70fe7--pip-10.0.1.tar.gz
==> Downloading https://files.pythonhosted.org/packages/2a/fb/aefe5d5dbc3f4fe1e815bcdb05cbaab19744d201bbc9b59cfa06ec7fc789/wheel-0.31.1.tar.gz
Already downloaded: /Users/student/Library/Caches/Homebrew/downloads/692113901ac5a4259d2158ae4b1de853f24f8029633d3d874c98ff7005d84460--wheel-0.31.1.tar.gz
==> make html
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.0
Error: Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.0
$ brew switch python 3.6.9_1
Cleaning /usr/local/Cellar/python/3.6.8_1
Cleaning /usr/local/Cellar/python/3.7.0
Cleaning /usr/local/Cellar/python/3.6.5_1
Cleaning /usr/local/Cellar/python/3.6.9_1
21 links created for /usr/local/Cellar/python/3.6.9_1
$ which python3
/usr/local/bin/python3
$ python3 --version
Python 3.6.9
$ brew postinstall python
==> Postinstalling python
==> /usr/local/Cellar/python/3.6.9_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.9_1/bi
==> /usr/local/Cellar/python/3.6.9_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.9_1/bi
==> /usr/local/Cellar/python/3.6.9_1/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python/3.6.9_1/bi
$   pip3 install --upgrade pip setuptools wheel
Collecting pip
  Using cached https://files.pythonhosted.org/packages/62/ca/94d32a6516ed197a491d17d46595ce58a83cbb2fca280414e57cd86b84dc/pip-19.2.1-py2.py3-none-any.whl
Collecting setuptools
  Using cached https://files.pythonhosted.org/packages/ec/51/f45cea425fd5cb0b0380f5b0f048ebc1da5b417e48d304838c02d6288a1e/setuptools-41.0.1-py2.py3-none-any.whl
Requirement already up-to-date: wheel in /usr/local/lib/python3.6/site-packages (0.33.4)
Installing collected packages: pip, setuptools
  Found existing installation: pip 10.0.1
    Uninstalling pip-10.0.1:
      Successfully uninstalled pip-10.0.1
  Found existing installation: setuptools 39.2.0
    Uninstalling setuptools-39.2.0:
      Successfully uninstalled setuptools-39.2.0
Successfully installed pip-19.2.1 setuptools-41.0.1
$ python3 --version
Python 3.6.9

@dukechem
Copy link
Author

dukechem commented Aug 4, 2019

Tho it seems to build ok on macos 10.14.6, pip3 does not work giving a the known-issue "No module named 'zlib'",
Using UN-commented depends_on "sphinx-doc" => :build that is needed so sphinx-build is in brew buildpath

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
$ brew install python3 . # installs 3.7.4
$ pip3 . install  sphinx . # creates /usr/local/bin/sphinx-build  
$ brew edit sphinx-doc . # . comment-out (put # in front of) this line:    #depends_on "python"
$ brew edit python # replace with gist for 3.6.9 with UN-commented   depends_on "sphinx-doc" => :build   
$ brew unlink python
$ brew install python --with-tcl-tk
Updating Homebrew...
==> Downloading https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz 
### ... takes a few minutes to build...
# while building, open another terminal and do:     brew   switch .  python 3.7.4
==> make html
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.4
Error: Cannot link python
Another version is already linked: /usr/local/Cellar/python/3.7.4
$  brew switch python 3.6.9_1
Cleaning /usr/local/Cellar/python/3.7.4
Cleaning /usr/local/Cellar/python/3.6.9_1
21 links created for /usr/local/Cellar/python/3.6.9_1
$ brew postinstall python
==> Postinstalling python
==> /usr/local/Cellar/python/3.6.9_1 ...
$ python3 --version
Python 3.6.9
$ which python3
/usr/local/bin/python3
$ pip3
...
ModuleNotFoundError: No module named 'zlib' . # known issue... Not sure how to get pip3 of 3.6.9 to work on 10.14.6 ...

@dukechem
Copy link
Author

dukechem commented Oct 3, 2019

Note: Info below also was posted at https://eric.blog/2019/01/12/install-unison-2-48-4-on-mac-os-x-with-homebrew/
Example below shows general method to find and install commits for other older or newer versions of unison, in this case, 2.48.15 ...
It follows advice given at https://medium.com/@schmijos/installing-old-homebrew-formulas-dc91de0c329c

Note: this is ok for simple binary bottles, like unison, with few, if any, dependencies. But dependencies quickly break things if you try such tricks to try to have something like both python versions 3.69 and 3.74: pip3 breaks for example as shown (here) at https://gist.github.com/dukechem in python.rb per comments at https://gist.github.com/dukechem/ef5cb77d0b571eb0f794a4be821bd53c

cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core

git log master -- Formula/unison.rb
...
commit f5755fe4ccecb63c669d633f804428267d3bf3d1
Author: BrewTestBot <brew-test-bot@googlegroups.com>
Date:   Tue Feb 20 12:46:06 2018 +0000

    unison: update 2.48.15 bottle.

$ brew unlink unison
$ export HOMEBREW_NO_INSTALL_CLEANUP=1
 $ brew install  https://raw.githubusercontent.com/Homebrew/homebrew-core/f5755fe4ccecb63c669d633f804428267d3bf3d1/Formula/unison.rb
==> Consider using `brew extract unison ...`!
This will extract your desired unison version to a stable tap instead of
installing from an unstable URL!

######################################################################## 100.0%
...
$  brew switch unison
unison installed versions: 2.48.4_1, 2.48.15, 2.51.2
$ brew switch unison 2.48.15
Cleaning /usr/local/Cellar/unison/2.51.2
Cleaning /usr/local/Cellar/unison/2.48.4_1
Cleaning /usr/local/Cellar/unison/2.48.15
1 links created for /usr/local/Cellar/unison/2.48.15
$ unison -version
unison version 2.48.15

@dirkk0
Copy link

dirkk0 commented Feb 11, 2020

Yes, this works, thanks!

If you throw this in a batch file, you get 2.48:

cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core
brew unlink unison
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install  https://raw.githubusercontent.com/Homebrew/homebrew-core/f5755fe4ccecb63c669d633f804428267d3bf3d1/Formula/unison.rb
brew switch unison 2.48.15
unison -version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment