Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19c38d5

Browse files
committed
Merge remote-tracking branch 'matplotlib/v1.5.x' into v2.x
2 parents e70bc42 + b80e0f1 commit 19c38d5

File tree

4 files changed

+390
-319
lines changed

4 files changed

+390
-319
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ script:
131131
# ghostscript are running at the same time).
132132
- echo Testing using $NPROC processes
133133
- |
134+
echo Testing import of tkagg backend
135+
MPLBACKEND="tkagg" python -c 'import matplotlib.pyplot as plt; print(plt.get_backend())'
136+
echo Testing using $NPROC processes
137+
echo The following args are passed to nose $NOSE_ARGS
134138
if [[ $BUILD_DOCS == false ]]; then
135139
export MPL_REPO_DIR=$PWD # needed for pep8-conformance test of the examples
136140
gdb -return-child-result -batch -ex r -ex bt --args python tests.py -s --processes=$NPROC --process-timeout=300 $TEST_ARGS

setupext.py

Lines changed: 8 additions & 282 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,7 @@ def get_install_requires(self):
14421442

14431443
class BackendAgg(OptionalBackendPackage):
14441444
name = "agg"
1445+
force = True
14451446

14461447
def get_extension(self):
14471448
sources = [
@@ -1459,36 +1460,10 @@ def get_extension(self):
14591460

14601461
class BackendTkAgg(OptionalBackendPackage):
14611462
name = "tkagg"
1463+
force = True
14621464

1463-
def __init__(self):
1464-
self.tcl_tk_cache = None
1465-
1466-
def check_requirements(self):
1467-
try:
1468-
if PY3min:
1469-
import tkinter as Tkinter
1470-
else:
1471-
import Tkinter
1472-
except ImportError:
1473-
raise CheckFailed('TKAgg requires Tkinter.')
1474-
except RuntimeError:
1475-
raise CheckFailed('Tkinter present but import failed.')
1476-
else:
1477-
if Tkinter.TkVersion < 8.3:
1478-
raise CheckFailed("Tcl/Tk v8.3 or later required.")
1479-
1480-
ext = self.get_extension()
1481-
check_include_file(ext.include_dirs, "tk.h", "Tk")
1482-
1483-
try:
1484-
tk_v = Tkinter.__version__.split()[-2]
1485-
except (AttributeError, IndexError):
1486-
# Tkinter.__version__ has been removed in python 3
1487-
tk_v = 'not identified'
1488-
1489-
BackendAgg.force = True
1490-
1491-
return "version %s" % tk_v
1465+
def check(self):
1466+
return "installing; run-time loading from Python Tcl / Tk"
14921467

14931468
def get_extension(self):
14941469
sources = [
@@ -1502,251 +1477,11 @@ def get_extension(self):
15021477
LibAgg().add_flags(ext, add_sources=False)
15031478
return ext
15041479

1505-
def query_tcltk(self):
1506-
"""
1507-
Tries to open a Tk window in order to query the Tk object
1508-
about its library paths. This should never be called more
1509-
than once by the same process, as Tk intricacies may cause the
1510-
Python interpreter to hang. The function also has a workaround
1511-
if no X server is running (useful for autobuild systems).
1512-
"""
1513-
# Use cached values if they exist, which ensures this function
1514-
# only executes once
1515-
if self.tcl_tk_cache is not None:
1516-
return self.tcl_tk_cache
1517-
1518-
# By this point, we already know that Tkinter imports correctly
1519-
if PY3min:
1520-
import tkinter as Tkinter
1521-
else:
1522-
import Tkinter
1523-
tcl_lib_dir = ''
1524-
tk_lib_dir = ''
1525-
# First try to open a Tk window (requires a running X server)
1526-
try:
1527-
tk = Tkinter.Tk()
1528-
except Tkinter.TclError:
1529-
# Next, start Tcl interpreter without opening a Tk window
1530-
# (no need for X server) This feature is available in
1531-
# python version 2.4 and up
1532-
try:
1533-
tcl = Tkinter.Tcl()
1534-
except AttributeError: # Python version not high enough
1535-
pass
1536-
except Tkinter.TclError: # Something went wrong while opening Tcl
1537-
pass
1538-
else:
1539-
tcl_lib_dir = str(tcl.getvar('tcl_library'))
1540-
# Guess Tk location based on Tcl location
1541-
(head, tail) = os.path.split(tcl_lib_dir)
1542-
tail = tail.replace('Tcl', 'Tk').replace('tcl', 'tk')
1543-
tk_lib_dir = os.path.join(head, tail)
1544-
if not os.path.exists(tk_lib_dir):
1545-
tk_lib_dir = tcl_lib_dir.replace(
1546-
'Tcl', 'Tk').replace('tcl', 'tk')
1547-
else:
1548-
# Obtain Tcl and Tk locations from Tk widget
1549-
tk.withdraw()
1550-
tcl_lib_dir = str(tk.getvar('tcl_library'))
1551-
tk_lib_dir = str(tk.getvar('tk_library'))
1552-
tk.destroy()
1553-
1554-
# Save directories and version string to cache
1555-
self.tcl_tk_cache = tcl_lib_dir, tk_lib_dir, str(Tkinter.TkVersion)[:3]
1556-
return self.tcl_tk_cache
1557-
1558-
def parse_tcl_config(self, tcl_lib_dir, tk_lib_dir):
1559-
try:
1560-
if PY3min:
1561-
import tkinter as Tkinter
1562-
else:
1563-
import Tkinter
1564-
except ImportError:
1565-
return None
1566-
1567-
tcl_poss = [tcl_lib_dir,
1568-
os.path.normpath(os.path.join(tcl_lib_dir, '..')),
1569-
"/usr/lib/tcl" + str(Tkinter.TclVersion),
1570-
"/usr/lib"]
1571-
tk_poss = [tk_lib_dir,
1572-
os.path.normpath(os.path.join(tk_lib_dir, '..')),
1573-
"/usr/lib/tk" + str(Tkinter.TkVersion),
1574-
"/usr/lib"]
1575-
for ptcl, ptk in zip(tcl_poss, tk_poss):
1576-
tcl_config = os.path.join(ptcl, "tclConfig.sh")
1577-
tk_config = os.path.join(ptk, "tkConfig.sh")
1578-
if (os.path.exists(tcl_config) and os.path.exists(tk_config)):
1579-
break
1580-
if not (os.path.exists(tcl_config) and os.path.exists(tk_config)):
1581-
return None
1582-
1583-
def get_var(file, varname):
1584-
p = subprocess.Popen(
1585-
'. %s ; eval echo ${%s}' % (file, varname),
1586-
shell=True,
1587-
executable="/bin/sh",
1588-
stdout=subprocess.PIPE)
1589-
result = p.communicate()[0]
1590-
return result.decode('ascii')
1591-
1592-
tcl_lib_dir = get_var(
1593-
tcl_config, 'TCL_LIB_SPEC').split()[0][2:].strip()
1594-
tcl_inc_dir = get_var(
1595-
tcl_config, 'TCL_INCLUDE_SPEC')[2:].strip()
1596-
tcl_lib = get_var(tcl_config, 'TCL_LIB_FLAG')[2:].strip()
1597-
1598-
tk_lib_dir = get_var(tk_config, 'TK_LIB_SPEC').split()[0][2:].strip()
1599-
tk_inc_dir = get_var(tk_config, 'TK_INCLUDE_SPEC').strip()
1600-
if tk_inc_dir == '':
1601-
tk_inc_dir = tcl_inc_dir
1602-
else:
1603-
tk_inc_dir = tk_inc_dir[2:]
1604-
tk_lib = get_var(tk_config, 'TK_LIB_FLAG')[2:].strip()
1605-
1606-
if not os.path.exists(os.path.join(tk_inc_dir, 'tk.h')):
1607-
return None
1608-
1609-
return (tcl_lib_dir, tcl_inc_dir, tcl_lib,
1610-
tk_lib_dir, tk_inc_dir, tk_lib)
1611-
1612-
def guess_tcl_config(self, tcl_lib_dir, tk_lib_dir, tk_ver):
1613-
if not (os.path.exists(tcl_lib_dir) and os.path.exists(tk_lib_dir)):
1614-
return None
1615-
1616-
tcl_lib = os.path.normpath(os.path.join(tcl_lib_dir, '../'))
1617-
tk_lib = os.path.normpath(os.path.join(tk_lib_dir, '../'))
1618-
1619-
tcl_inc = os.path.normpath(
1620-
os.path.join(tcl_lib_dir,
1621-
'../../include/tcl' + tk_ver))
1622-
if not os.path.exists(tcl_inc):
1623-
tcl_inc = os.path.normpath(
1624-
os.path.join(tcl_lib_dir,
1625-
'../../include'))
1626-
1627-
tk_inc = os.path.normpath(os.path.join(
1628-
tk_lib_dir,
1629-
'../../include/tk' + tk_ver))
1630-
if not os.path.exists(tk_inc):
1631-
tk_inc = os.path.normpath(os.path.join(
1632-
tk_lib_dir,
1633-
'../../include'))
1634-
1635-
if not os.path.exists(os.path.join(tk_inc, 'tk.h')):
1636-
tk_inc = tcl_inc
1637-
1638-
if not os.path.exists(tcl_inc):
1639-
# this is a hack for suse linux, which is broken
1640-
if (sys.platform.startswith('linux') and
1641-
os.path.exists('/usr/include/tcl.h') and
1642-
os.path.exists('/usr/include/tk.h')):
1643-
tcl_inc = '/usr/include'
1644-
tk_inc = '/usr/include'
1645-
1646-
if not os.path.exists(os.path.join(tk_inc, 'tk.h')):
1647-
return None
1648-
1649-
return tcl_lib, tcl_inc, 'tcl' + tk_ver, tk_lib, tk_inc, 'tk' + tk_ver
1650-
1651-
def hardcoded_tcl_config(self):
1652-
tcl_inc = "/usr/local/include"
1653-
tk_inc = "/usr/local/include"
1654-
tcl_lib = "/usr/local/lib"
1655-
tk_lib = "/usr/local/lib"
1656-
return tcl_lib, tcl_inc, 'tcl', tk_lib, tk_inc, 'tk'
1657-
16581480
def add_flags(self, ext):
1481+
ext.include_dirs.extend(['src'])
16591482
if sys.platform == 'win32':
1660-
major, minor1, minor2, s, tmp = sys.version_info
1661-
if sys.version_info[0:2] < (3, 4):
1662-
ext.include_dirs.extend(['win32_static/include/tcl85'])
1663-
ext.libraries.extend(['tk85', 'tcl85'])
1664-
else:
1665-
ext.include_dirs.extend(['win32_static/include/tcl86'])
1666-
ext.libraries.extend(['tk86t', 'tcl86t'])
1667-
ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')])
1668-
1669-
elif sys.platform == 'darwin':
1670-
# this config section lifted directly from Imaging - thanks to
1671-
# the effbot!
1672-
1673-
# First test for a MacOSX/darwin framework install
1674-
from os.path import join, exists
1675-
framework_dirs = [
1676-
join(os.getenv('HOME'), '/Library/Frameworks'),
1677-
'/Library/Frameworks',
1678-
'/System/Library/Frameworks/',
1679-
]
1680-
1681-
# Find the directory that contains the Tcl.framework and
1682-
# Tk.framework bundles.
1683-
tk_framework_found = 0
1684-
for F in framework_dirs:
1685-
# both Tcl.framework and Tk.framework should be present
1686-
for fw in 'Tcl', 'Tk':
1687-
if not exists(join(F, fw + '.framework')):
1688-
break
1689-
else:
1690-
# ok, F is now directory with both frameworks. Continure
1691-
# building
1692-
tk_framework_found = 1
1693-
break
1694-
if tk_framework_found:
1695-
# For 8.4a2, we must add -I options that point inside
1696-
# the Tcl and Tk frameworks. In later release we
1697-
# should hopefully be able to pass the -F option to
1698-
# gcc, which specifies a framework lookup path.
1699-
1700-
tk_include_dirs = [
1701-
join(F, fw + '.framework', H)
1702-
for fw in ('Tcl', 'Tk')
1703-
for H in ('Headers', 'Versions/Current/PrivateHeaders')
1704-
]
1705-
1706-
# For 8.4a2, the X11 headers are not included. Rather
1707-
# than include a complicated search, this is a
1708-
# hard-coded path. It could bail out if X11 libs are
1709-
# not found...
1710-
1711-
# tk_include_dirs.append('/usr/X11R6/include')
1712-
frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
1713-
ext.include_dirs.extend(tk_include_dirs)
1714-
ext.extra_link_args.extend(frameworks)
1715-
ext.extra_compile_args.extend(frameworks)
1716-
1717-
# you're still here? ok we'll try it this way...
1718-
else:
1719-
# There are 3 methods to try, in decreasing order of "smartness"
1720-
#
1721-
# 1. Parse the tclConfig.sh and tkConfig.sh files that have
1722-
# all the information we need
1723-
#
1724-
# 2. Guess the include and lib dirs based on the location of
1725-
# Tkinter's 'tcl_library' and 'tk_library' variables.
1726-
#
1727-
# 3. Use some hardcoded locations that seem to work on a lot
1728-
# of distros.
1729-
1730-
# Query Tcl/Tk system for library paths and version string
1731-
try:
1732-
tcl_lib_dir, tk_lib_dir, tk_ver = self.query_tcltk()
1733-
except:
1734-
tk_ver = ''
1735-
result = self.hardcoded_tcl_config()
1736-
else:
1737-
result = self.parse_tcl_config(tcl_lib_dir, tk_lib_dir)
1738-
if result is None:
1739-
result = self.guess_tcl_config(
1740-
tcl_lib_dir, tk_lib_dir, tk_ver)
1741-
if result is None:
1742-
result = self.hardcoded_tcl_config()
1743-
1744-
# Add final versions of directories and libraries to ext lists
1745-
(tcl_lib_dir, tcl_inc_dir, tcl_lib,
1746-
tk_lib_dir, tk_inc_dir, tk_lib) = result
1747-
ext.include_dirs.extend([tcl_inc_dir, tk_inc_dir])
1748-
ext.library_dirs.extend([tcl_lib_dir, tk_lib_dir])
1749-
ext.libraries.extend([tcl_lib, tk_lib])
1483+
# PSAPI library needed for finding Tcl / Tk at run time
1484+
ext.libraries.extend(['psapi'])
17501485

17511486

17521487
class BackendGtk(OptionalBackendPackage):
@@ -1860,8 +1595,6 @@ def check(self):
18601595
return super(BackendGtkAgg, self).check()
18611596
except:
18621597
raise
1863-
else:
1864-
BackendAgg.force = True
18651598

18661599
def get_package_data(self):
18671600
return {'matplotlib': ['mpl-data/*.glade']}
@@ -1937,7 +1670,6 @@ def check_requirements(self):
19371670
p.join()
19381671

19391672
if success:
1940-
BackendAgg.force = True
19411673
return msg
19421674
else:
19431675
raise CheckFailed(msg)
@@ -2010,7 +1742,6 @@ def check_requirements(self):
20101742
p.join()
20111743

20121744
if success:
2013-
BackendAgg.force = True
20141745
return msg
20151746
else:
20161747
raise CheckFailed(msg)
@@ -2054,8 +1785,6 @@ def check_requirements(self):
20541785
raise CheckFailed(
20551786
"Requires wxPython 2.8, found %s" % backend_version)
20561787

2057-
BackendAgg.force = True
2058-
20591788
return "version %s" % backend_version
20601789

20611790

@@ -2090,7 +1819,7 @@ def check_requirements(self):
20901819
config = self.get_config()
20911820
if config is False:
20921821
raise CheckFailed("skipping due to configuration")
2093-
return "installing"
1822+
return ""
20941823

20951824
def get_extension(self):
20961825
sources = [
@@ -2165,7 +1894,6 @@ def backend_pyside_internal_check(self):
21651894
except ImportError:
21661895
raise CheckFailed("PySide not found")
21671896
else:
2168-
BackendAgg.force = True
21691897
return ("Qt: %s, PySide: %s" %
21701898
(QtCore.__version__, __version__))
21711899

@@ -2182,7 +1910,6 @@ def backend_pyqt4_internal_check(self):
21821910
except AttributeError:
21831911
raise CheckFailed('PyQt4 not correctly imported')
21841912
else:
2185-
BackendAgg.force = True
21861913
return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
21871914

21881915

@@ -2224,7 +1951,6 @@ def backend_qt5_internal_check(self):
22241951
except AttributeError:
22251952
raise CheckFailed('PyQt5 not correctly imported')
22261953
else:
2227-
BackendAgg.force = True
22281954
return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
22291955

22301956

0 commit comments

Comments
 (0)