@@ -1283,6 +1283,7 @@ def get_install_requires(self):
12831283
12841284class BackendAgg (OptionalBackendPackage ):
12851285 name = "agg"
1286+ force = True
12861287
12871288 def get_extension (self ):
12881289 sources = [
@@ -1300,36 +1301,10 @@ def get_extension(self):
13001301
13011302class BackendTkAgg (OptionalBackendPackage ):
13021303 name = "tkagg"
1304+ force = True
13031305
1304- def __init__ (self ):
1305- self .tcl_tk_cache = None
1306-
1307- def check_requirements (self ):
1308- try :
1309- if PY3min :
1310- import tkinter as Tkinter
1311- else :
1312- import Tkinter
1313- except ImportError :
1314- raise CheckFailed ('TKAgg requires Tkinter.' )
1315- except RuntimeError :
1316- raise CheckFailed ('Tkinter present but import failed.' )
1317- else :
1318- if Tkinter .TkVersion < 8.3 :
1319- raise CheckFailed ("Tcl/Tk v8.3 or later required." )
1320-
1321- ext = self .get_extension ()
1322- check_include_file (ext .include_dirs , "tk.h" , "Tk" )
1323-
1324- try :
1325- tk_v = Tkinter .__version__ .split ()[- 2 ]
1326- except (AttributeError , IndexError ):
1327- # Tkinter.__version__ has been removed in python 3
1328- tk_v = 'not identified'
1329-
1330- BackendAgg .force = True
1331-
1332- return "version %s" % tk_v
1306+ def check (self ):
1307+ return "installing; run-time loading from Python Tcl / Tk"
13331308
13341309 def get_extension (self ):
13351310 sources = [
@@ -1343,251 +1318,11 @@ def get_extension(self):
13431318 LibAgg ().add_flags (ext , add_sources = False )
13441319 return ext
13451320
1346- def query_tcltk (self ):
1347- """
1348- Tries to open a Tk window in order to query the Tk object
1349- about its library paths. This should never be called more
1350- than once by the same process, as Tk intricacies may cause the
1351- Python interpreter to hang. The function also has a workaround
1352- if no X server is running (useful for autobuild systems).
1353- """
1354- # Use cached values if they exist, which ensures this function
1355- # only executes once
1356- if self .tcl_tk_cache is not None :
1357- return self .tcl_tk_cache
1358-
1359- # By this point, we already know that Tkinter imports correctly
1360- if PY3min :
1361- import tkinter as Tkinter
1362- else :
1363- import Tkinter
1364- tcl_lib_dir = ''
1365- tk_lib_dir = ''
1366- # First try to open a Tk window (requires a running X server)
1367- try :
1368- tk = Tkinter .Tk ()
1369- except Tkinter .TclError :
1370- # Next, start Tcl interpreter without opening a Tk window
1371- # (no need for X server) This feature is available in
1372- # python version 2.4 and up
1373- try :
1374- tcl = Tkinter .Tcl ()
1375- except AttributeError : # Python version not high enough
1376- pass
1377- except Tkinter .TclError : # Something went wrong while opening Tcl
1378- pass
1379- else :
1380- tcl_lib_dir = str (tcl .getvar ('tcl_library' ))
1381- # Guess Tk location based on Tcl location
1382- (head , tail ) = os .path .split (tcl_lib_dir )
1383- tail = tail .replace ('Tcl' , 'Tk' ).replace ('tcl' , 'tk' )
1384- tk_lib_dir = os .path .join (head , tail )
1385- if not os .path .exists (tk_lib_dir ):
1386- tk_lib_dir = tcl_lib_dir .replace (
1387- 'Tcl' , 'Tk' ).replace ('tcl' , 'tk' )
1388- else :
1389- # Obtain Tcl and Tk locations from Tk widget
1390- tk .withdraw ()
1391- tcl_lib_dir = str (tk .getvar ('tcl_library' ))
1392- tk_lib_dir = str (tk .getvar ('tk_library' ))
1393- tk .destroy ()
1394-
1395- # Save directories and version string to cache
1396- self .tcl_tk_cache = tcl_lib_dir , tk_lib_dir , str (Tkinter .TkVersion )[:3 ]
1397- return self .tcl_tk_cache
1398-
1399- def parse_tcl_config (self , tcl_lib_dir , tk_lib_dir ):
1400- try :
1401- if PY3min :
1402- import tkinter as Tkinter
1403- else :
1404- import Tkinter
1405- except ImportError :
1406- return None
1407-
1408- tcl_poss = [tcl_lib_dir ,
1409- os .path .normpath (os .path .join (tcl_lib_dir , '..' )),
1410- "/usr/lib/tcl" + str (Tkinter .TclVersion ),
1411- "/usr/lib" ]
1412- tk_poss = [tk_lib_dir ,
1413- os .path .normpath (os .path .join (tk_lib_dir , '..' )),
1414- "/usr/lib/tk" + str (Tkinter .TkVersion ),
1415- "/usr/lib" ]
1416- for ptcl , ptk in zip (tcl_poss , tk_poss ):
1417- tcl_config = os .path .join (ptcl , "tclConfig.sh" )
1418- tk_config = os .path .join (ptk , "tkConfig.sh" )
1419- if (os .path .exists (tcl_config ) and os .path .exists (tk_config )):
1420- break
1421- if not (os .path .exists (tcl_config ) and os .path .exists (tk_config )):
1422- return None
1423-
1424- def get_var (file , varname ):
1425- p = subprocess .Popen (
1426- '. %s ; eval echo ${%s}' % (file , varname ),
1427- shell = True ,
1428- executable = "/bin/sh" ,
1429- stdout = subprocess .PIPE )
1430- result = p .communicate ()[0 ]
1431- return result .decode ('ascii' )
1432-
1433- tcl_lib_dir = get_var (
1434- tcl_config , 'TCL_LIB_SPEC' ).split ()[0 ][2 :].strip ()
1435- tcl_inc_dir = get_var (
1436- tcl_config , 'TCL_INCLUDE_SPEC' )[2 :].strip ()
1437- tcl_lib = get_var (tcl_config , 'TCL_LIB_FLAG' )[2 :].strip ()
1438-
1439- tk_lib_dir = get_var (tk_config , 'TK_LIB_SPEC' ).split ()[0 ][2 :].strip ()
1440- tk_inc_dir = get_var (tk_config , 'TK_INCLUDE_SPEC' ).strip ()
1441- if tk_inc_dir == '' :
1442- tk_inc_dir = tcl_inc_dir
1443- else :
1444- tk_inc_dir = tk_inc_dir [2 :]
1445- tk_lib = get_var (tk_config , 'TK_LIB_FLAG' )[2 :].strip ()
1446-
1447- if not os .path .exists (os .path .join (tk_inc_dir , 'tk.h' )):
1448- return None
1449-
1450- return (tcl_lib_dir , tcl_inc_dir , tcl_lib ,
1451- tk_lib_dir , tk_inc_dir , tk_lib )
1452-
1453- def guess_tcl_config (self , tcl_lib_dir , tk_lib_dir , tk_ver ):
1454- if not (os .path .exists (tcl_lib_dir ) and os .path .exists (tk_lib_dir )):
1455- return None
1456-
1457- tcl_lib = os .path .normpath (os .path .join (tcl_lib_dir , '../' ))
1458- tk_lib = os .path .normpath (os .path .join (tk_lib_dir , '../' ))
1459-
1460- tcl_inc = os .path .normpath (
1461- os .path .join (tcl_lib_dir ,
1462- '../../include/tcl' + tk_ver ))
1463- if not os .path .exists (tcl_inc ):
1464- tcl_inc = os .path .normpath (
1465- os .path .join (tcl_lib_dir ,
1466- '../../include' ))
1467-
1468- tk_inc = os .path .normpath (os .path .join (
1469- tk_lib_dir ,
1470- '../../include/tk' + tk_ver ))
1471- if not os .path .exists (tk_inc ):
1472- tk_inc = os .path .normpath (os .path .join (
1473- tk_lib_dir ,
1474- '../../include' ))
1475-
1476- if not os .path .exists (os .path .join (tk_inc , 'tk.h' )):
1477- tk_inc = tcl_inc
1478-
1479- if not os .path .exists (tcl_inc ):
1480- # this is a hack for suse linux, which is broken
1481- if (sys .platform .startswith ('linux' ) and
1482- os .path .exists ('/usr/include/tcl.h' ) and
1483- os .path .exists ('/usr/include/tk.h' )):
1484- tcl_inc = '/usr/include'
1485- tk_inc = '/usr/include'
1486-
1487- if not os .path .exists (os .path .join (tk_inc , 'tk.h' )):
1488- return None
1489-
1490- return tcl_lib , tcl_inc , 'tcl' + tk_ver , tk_lib , tk_inc , 'tk' + tk_ver
1491-
1492- def hardcoded_tcl_config (self ):
1493- tcl_inc = "/usr/local/include"
1494- tk_inc = "/usr/local/include"
1495- tcl_lib = "/usr/local/lib"
1496- tk_lib = "/usr/local/lib"
1497- return tcl_lib , tcl_inc , 'tcl' , tk_lib , tk_inc , 'tk'
1498-
14991321 def add_flags (self , ext ):
1322+ ext .include_dirs .extend (['src' ])
15001323 if sys .platform == 'win32' :
1501- major , minor1 , minor2 , s , tmp = sys .version_info
1502- if sys .version_info [0 :2 ] < (3 , 4 ):
1503- ext .include_dirs .extend (['win32_static/include/tcl85' ])
1504- ext .libraries .extend (['tk85' , 'tcl85' ])
1505- else :
1506- ext .include_dirs .extend (['win32_static/include/tcl86' ])
1507- ext .libraries .extend (['tk86t' , 'tcl86t' ])
1508- ext .library_dirs .extend ([os .path .join (sys .prefix , 'dlls' )])
1509-
1510- elif sys .platform == 'darwin' :
1511- # this config section lifted directly from Imaging - thanks to
1512- # the effbot!
1513-
1514- # First test for a MacOSX/darwin framework install
1515- from os .path import join , exists
1516- framework_dirs = [
1517- join (os .getenv ('HOME' ), '/Library/Frameworks' ),
1518- '/Library/Frameworks' ,
1519- '/System/Library/Frameworks/' ,
1520- ]
1521-
1522- # Find the directory that contains the Tcl.framework and
1523- # Tk.framework bundles.
1524- tk_framework_found = 0
1525- for F in framework_dirs :
1526- # both Tcl.framework and Tk.framework should be present
1527- for fw in 'Tcl' , 'Tk' :
1528- if not exists (join (F , fw + '.framework' )):
1529- break
1530- else :
1531- # ok, F is now directory with both frameworks. Continure
1532- # building
1533- tk_framework_found = 1
1534- break
1535- if tk_framework_found :
1536- # For 8.4a2, we must add -I options that point inside
1537- # the Tcl and Tk frameworks. In later release we
1538- # should hopefully be able to pass the -F option to
1539- # gcc, which specifies a framework lookup path.
1540-
1541- tk_include_dirs = [
1542- join (F , fw + '.framework' , H )
1543- for fw in ('Tcl' , 'Tk' )
1544- for H in ('Headers' , 'Versions/Current/PrivateHeaders' )
1545- ]
1546-
1547- # For 8.4a2, the X11 headers are not included. Rather
1548- # than include a complicated search, this is a
1549- # hard-coded path. It could bail out if X11 libs are
1550- # not found...
1551-
1552- # tk_include_dirs.append('/usr/X11R6/include')
1553- frameworks = ['-framework' , 'Tcl' , '-framework' , 'Tk' ]
1554- ext .include_dirs .extend (tk_include_dirs )
1555- ext .extra_link_args .extend (frameworks )
1556- ext .extra_compile_args .extend (frameworks )
1557-
1558- # you're still here? ok we'll try it this way...
1559- else :
1560- # There are 3 methods to try, in decreasing order of "smartness"
1561- #
1562- # 1. Parse the tclConfig.sh and tkConfig.sh files that have
1563- # all the information we need
1564- #
1565- # 2. Guess the include and lib dirs based on the location of
1566- # Tkinter's 'tcl_library' and 'tk_library' variables.
1567- #
1568- # 3. Use some hardcoded locations that seem to work on a lot
1569- # of distros.
1570-
1571- # Query Tcl/Tk system for library paths and version string
1572- try :
1573- tcl_lib_dir , tk_lib_dir , tk_ver = self .query_tcltk ()
1574- except :
1575- tk_ver = ''
1576- result = self .hardcoded_tcl_config ()
1577- else :
1578- result = self .parse_tcl_config (tcl_lib_dir , tk_lib_dir )
1579- if result is None :
1580- result = self .guess_tcl_config (
1581- tcl_lib_dir , tk_lib_dir , tk_ver )
1582- if result is None :
1583- result = self .hardcoded_tcl_config ()
1584-
1585- # Add final versions of directories and libraries to ext lists
1586- (tcl_lib_dir , tcl_inc_dir , tcl_lib ,
1587- tk_lib_dir , tk_inc_dir , tk_lib ) = result
1588- ext .include_dirs .extend ([tcl_inc_dir , tk_inc_dir ])
1589- ext .library_dirs .extend ([tcl_lib_dir , tk_lib_dir ])
1590- ext .libraries .extend ([tcl_lib , tk_lib ])
1324+ # PSAPI library needed for finding Tcl / Tk at run time
1325+ ext .libraries .extend (['psapi' ])
15911326
15921327
15931328class BackendGtk (OptionalBackendPackage ):
@@ -1701,8 +1436,6 @@ def check(self):
17011436 return super (BackendGtkAgg , self ).check ()
17021437 except :
17031438 raise
1704- else :
1705- BackendAgg .force = True
17061439
17071440 def get_package_data (self ):
17081441 return {'matplotlib' : ['mpl-data/*.glade' ]}
@@ -1778,7 +1511,6 @@ def check_requirements(self):
17781511 p .join ()
17791512
17801513 if success :
1781- BackendAgg .force = True
17821514 return msg
17831515 else :
17841516 raise CheckFailed (msg )
@@ -1851,7 +1583,6 @@ def check_requirements(self):
18511583 p .join ()
18521584
18531585 if success :
1854- BackendAgg .force = True
18551586 return msg
18561587 else :
18571588 raise CheckFailed (msg )
@@ -1895,8 +1626,6 @@ def check_requirements(self):
18951626 raise CheckFailed (
18961627 "Requires wxPython 2.8, found %s" % backend_version )
18971628
1898- BackendAgg .force = True
1899-
19001629 return "version %s" % backend_version
19011630
19021631
@@ -1935,7 +1664,7 @@ def check_requirements(self):
19351664 config = self .get_config ()
19361665 if config is False :
19371666 raise CheckFailed ("skipping due to configuration" )
1938- return "installing "
1667+ return ""
19391668
19401669 def get_extension (self ):
19411670 sources = [
@@ -2010,7 +1739,6 @@ def backend_pyside_internal_check(self):
20101739 except ImportError :
20111740 raise CheckFailed ("PySide not found" )
20121741 else :
2013- BackendAgg .force = True
20141742 return ("Qt: %s, PySide: %s" %
20151743 (QtCore .__version__ , __version__ ))
20161744
@@ -2027,7 +1755,6 @@ def backend_pyqt4_internal_check(self):
20271755 except AttributeError :
20281756 raise CheckFailed ('PyQt4 not correctly imported' )
20291757 else :
2030- BackendAgg .force = True
20311758 return ("Qt: %s, PyQt: %s" % (self .convert_qt_version (qt_version ), pyqt_version_str ))
20321759
20331760
@@ -2069,7 +1796,6 @@ def backend_qt5_internal_check(self):
20691796 except AttributeError :
20701797 raise CheckFailed ('PyQt5 not correctly imported' )
20711798 else :
2072- BackendAgg .force = True
20731799 return ("Qt: %s, PyQt: %s" % (self .convert_qt_version (qt_version ), pyqt_version_str ))
20741800
20751801
0 commit comments