scripts/install.py

branch
eric7
changeset 8440
f71f33c0d47a
parent 8430
14c69f0ccca5
child 8442
a23078cc9fa7
equal deleted inserted replaced
8439:982a9383c57a 8440:f71f33c0d47a
1419 if answer in ("", "Y", "y"): 1419 if answer in ("", "Y", "y"):
1420 subprocess.call( # secok 1420 subprocess.call( # secok
1421 [sys.executable, "-m", "pip", "install", "--upgrade", "pip"]) 1421 [sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
1422 1422
1423 1423
1424 def versionToStr(version):
1425 """
1426 Function to convert a version number into a version string.
1427
1428 @param version version number to convert
1429 @type int
1430 @return version string
1431 @rtype str
1432 """
1433 parts = []
1434 while version:
1435 parts.append(version & 0xff)
1436 version >>= 8
1437 return '.'.join(str(p) for p in reversed(parts))
1438
1439
1424 def doDependancyChecks(): 1440 def doDependancyChecks():
1425 """ 1441 """
1426 Perform some dependency checks. 1442 Perform some dependency checks.
1427 """ 1443 """
1444 # TODO: update as necessary for PyQt6 6.2.0
1445 # TODO: change that once QScintilla 2.13.0 is released
1446 requiredVersions = {
1447 "pyqt6": 0x60101,
1448 "pyqt6-charts": 0x60101,
1449 #"pyqt6-webengine": 0x60200,
1450 "pyqt6-qscintilla": 0x20c01,
1451 "sip": 0x60100,
1452 }
1453
1428 try: 1454 try:
1429 isSudo = os.getuid() == 0 and sys.platform != "darwin" 1455 isSudo = os.getuid() == 0 and sys.platform != "darwin"
1430 # disregard sudo installs on macOS 1456 # disregard sudo installs on macOS
1431 except AttributeError: 1457 except AttributeError:
1432 isSudo = False 1458 isSudo = False
1453 1479
1454 try: 1480 try:
1455 from PyQt6.QtCore import qVersion 1481 from PyQt6.QtCore import qVersion
1456 except ImportError as msg: 1482 except ImportError as msg:
1457 installed = not isSudo and pipInstall( 1483 installed = not isSudo and pipInstall(
1458 "PyQt6>=6.1.0", 1484 "PyQt6>={0}".format(versionToStr(requiredVersions["pyqt6"])),
1459 "'PyQt6' could not be detected.\nError: {0}".format(msg) 1485 "'PyQt6' could not be detected.\nError: {0}".format(msg)
1460 ) 1486 )
1461 if installed: 1487 if installed:
1462 # try to import it again 1488 # try to import it again
1463 try: 1489 try:
1488 except ImportError as msg: 1514 except ImportError as msg:
1489 if isSudo: 1515 if isSudo:
1490 print("Optional 'PyQt6-WebEngine' could not be detected.") 1516 print("Optional 'PyQt6-WebEngine' could not be detected.")
1491 else: 1517 else:
1492 pipInstall( 1518 pipInstall(
1493 "PyQt6-WebEngine>=6.2.0", 1519 "PyQt6-WebEngine>={0}".format(
1520 versionToStr(requiredVersions["pyqt6-webengine"])),
1494 "Optional 'PyQt6-WebEngine' could not be detected.\n" 1521 "Optional 'PyQt6-WebEngine' could not be detected.\n"
1495 "Error: {0}".format(msg) 1522 "Error: {0}".format(msg)
1496 ) 1523 )
1497 1524
1498 try: 1525 try:
1500 except ImportError as msg: 1527 except ImportError as msg:
1501 if isSudo: 1528 if isSudo:
1502 print("Optional 'PyQt6-Charts' could not be detected.") 1529 print("Optional 'PyQt6-Charts' could not be detected.")
1503 else: 1530 else:
1504 pipInstall( 1531 pipInstall(
1505 "PyQt6-Charts>=6.1.0", 1532 "PyQt6-Charts>={0}".format(
1533 versionToStr(requiredVersions["pyqt6-charts"])),
1506 "Optional 'PyQt6-Charts' could not be detected.\n" 1534 "Optional 'PyQt6-Charts' could not be detected.\n"
1507 "Error: {0}".format(msg) 1535 "Error: {0}".format(msg)
1508 ) 1536 )
1509 print("Found PyQt6-Charts") 1537 print("Found PyQt6-Charts")
1510 1538
1511 try: 1539 try:
1512 from PyQt6 import Qsci # __IGNORE_WARNING__ 1540 from PyQt6 import Qsci # __IGNORE_WARNING__
1513 except ImportError as msg: 1541 except ImportError as msg:
1514 installed = not isSudo and pipInstall( 1542 installed = not isSudo and pipInstall(
1515 "PyQt6-QScintilla", 1543 "PyQt6-QScintilla>={0}".format(
1544 versionToStr(requiredVersions["pyqt6-qscintilla"])),
1516 "'PyQt6-QScintilla' could not be detected.\nError: {0}".format(msg) 1545 "'PyQt6-QScintilla' could not be detected.\nError: {0}".format(msg)
1517 ) 1546 )
1518 if installed: 1547 if installed:
1519 # try to import it again 1548 # try to import it again
1520 try: 1549 try:
1532 print("Found PyQt6-QScintilla") 1561 print("Found PyQt6-QScintilla")
1533 1562
1534 impModulesList = [ 1563 impModulesList = [
1535 "PyQt6.QtGui", "PyQt6.QtNetwork", "PyQt6.QtPrintSupport", 1564 "PyQt6.QtGui", "PyQt6.QtNetwork", "PyQt6.QtPrintSupport",
1536 "PyQt6.QtSql", "PyQt6.QtSvg", "PyQt6.QtSvgWidgets", "PyQt6.QtWidgets", 1565 "PyQt6.QtSql", "PyQt6.QtSvg", "PyQt6.QtSvgWidgets", "PyQt6.QtWidgets",
1537 ]
1538 altModulesList = [
1539 # Tuple with alternatives, flag indicating it's ok to not be
1540 # available (e.g. for 32-Bit Windows)
1541 # TODO: enable this once PyQt 6.2.0/Qt 6.2.0 is released
1542 #~ (("PyQt6.QtWebEngineWidgets", ), sys.maxsize <= 2**32), # __IGNORE_WARNING__
1543 ] 1566 ]
1544 optionalModulesList = { 1567 optionalModulesList = {
1545 # key is pip project name 1568 # key is pip project name
1546 # value is tuple of package name, pip install constraint 1569 # value is tuple of package name, pip install constraint
1547 "docutils": ("docutils", ""), 1570 "docutils": ("docutils", ""),
1573 print('Sorry, please install {0}.'.format(name)) 1596 print('Sorry, please install {0}.'.format(name))
1574 print('Error: {0}'.format(msg)) 1597 print('Error: {0}'.format(msg))
1575 modulesOK = False 1598 modulesOK = False
1576 if not modulesOK: 1599 if not modulesOK:
1577 exit(1) 1600 exit(1)
1578 # check mandatory modules with alternatives 1601
1579 if altModulesList:
1580 altModulesOK = True
1581 for altModules, forcedOk in altModulesList:
1582 modulesOK = False
1583 for altModule in altModules:
1584 name = altModule.split(".")[1]
1585 with contextlib.suppress(ImportError):
1586 __import__(altModule)
1587 print("Found", name)
1588 modulesOK = True
1589 break
1590 if not modulesOK and not forcedOk:
1591 altModulesOK = False
1592 print('Sorry, please install {0}.'
1593 .format(" or ".join(altModules)))
1594 if not altModulesOK:
1595 exit(1)
1596 # check optional modules 1602 # check optional modules
1597 for optPackage in optionalModulesList: 1603 for optPackage in optionalModulesList:
1598 try: 1604 try:
1599 __import__(optionalModulesList[optPackage][0]) 1605 __import__(optionalModulesList[optPackage][0])
1600 print("Found", optPackage) 1606 print("Found", optPackage)
1619 1625
1620 print("\nVersion Information") 1626 print("\nVersion Information")
1621 print("-------------------") 1627 print("-------------------")
1622 1628
1623 # check version of Qt 1629 # check version of Qt
1630 # ===================
1624 qtMajor = int(qVersion().split('.')[0]) 1631 qtMajor = int(qVersion().split('.')[0])
1625 qtMinor = int(qVersion().split('.')[1]) 1632 qtMinor = int(qVersion().split('.')[1])
1626 print("Qt6: {0}".format(qVersion().strip())) 1633 print("Qt6: {0}".format(qVersion().strip()))
1627 if qtMajor == 6 and qtMinor < 1: 1634 if qtMajor == 6 and qtMinor < 1:
1628 print('Sorry, you must have Qt version 6.1.0 or better.') 1635 print('Sorry, you must have Qt version 6.1.0 or better.')
1629 exit(2) 1636 exit(2)
1630 1637
1631 # check version of sip 1638 # check version of sip
1639 # ====================
1632 with contextlib.suppress(ImportError, AttributeError): 1640 with contextlib.suppress(ImportError, AttributeError):
1633 try: 1641 try:
1634 from PyQt6 import sip 1642 from PyQt6 import sip
1635 except ImportError: 1643 except ImportError:
1636 import sip 1644 import sip
1637 sipVersion = sip.SIP_VERSION_STR 1645 print("sip:", sip.SIP_VERSION_STR.strip())
1638 print("sip:", sipVersion.strip())
1639 # always assume, that snapshots or dev versions are new enough 1646 # always assume, that snapshots or dev versions are new enough
1640 if "snapshot" not in sipVersion and "dev" not in sipVersion: 1647 if (
1641 while sipVersion.count('.') < 2: 1648 "snapshot" not in sip.SIP_VERSION_STR and
1642 sipVersion += '.0' 1649 "dev" not in sip.SIP_VERSION_STR
1643 (major, minor, pat) = sipVersion.split('.')[:3] 1650 ):
1644 major = int(major) 1651 if sip.SIP_VERSION < requiredVersions["sip"]:
1645 minor = int(minor) 1652 print(
1646 pat = int(pat) 1653 'Sorry, you must have sip {0} or higher or'
1647 if ( 1654 ' a recent development release.'
1648 major < 6 or 1655 .format(versionToStr(requiredVersions["sip"]))
1649 (major == 6 and minor < 0) or 1656 )
1650 (major == 6 and minor == 1 and pat < 0)
1651 ):
1652 print('Sorry, you must have sip 6.1.0 or higher or'
1653 ' a recent snapshot release.')
1654 exit(3) 1657 exit(3)
1655 # check for blacklisted versions 1658 # check for blacklisted versions
1656 for vers in BlackLists["sip"] + PlatformBlackLists["sip"]: 1659 for vers in BlackLists["sip"] + PlatformBlackLists["sip"]:
1657 if vers == sipVersion: 1660 if vers == sip.SIP_VERSION:
1658 print( 1661 print(
1659 'Sorry, sip version {0} is not compatible with eric.' 1662 'Sorry, sip version {0} is not compatible with eric.'
1660 .format(vers)) 1663 .format(versionToStr(vers)))
1661 print('Please install another version.') 1664 print('Please install another version.')
1662 exit(3) 1665 exit(3)
1663 1666
1664 # check version of PyQt 1667 # check version of PyQt6
1665 from PyQt6.QtCore import PYQT_VERSION_STR 1668 # ======================
1666 pyqtVersion = PYQT_VERSION_STR 1669 from PyQt6.QtCore import PYQT_VERSION, PYQT_VERSION_STR
1667 print("PyQt6:", pyqtVersion.strip()) 1670 print("PyQt6:", PYQT_VERSION_STR.strip())
1668 # always assume, that snapshots or dev versions are new enough 1671 # always assume, that snapshots or dev versions are new enough
1669 if "snapshot" not in pyqtVersion and "dev" not in pyqtVersion: 1672 if "snapshot" not in PYQT_VERSION_STR and "dev" not in PYQT_VERSION_STR:
1670 while pyqtVersion.count('.') < 2: 1673 if PYQT_VERSION < requiredVersions["pyqt6"]:
1671 pyqtVersion += '.0' 1674 print(
1672 (major, minor, pat) = pyqtVersion.split('.')[:3] 1675 'Sorry, you must have PyQt {0} or better or'
1673 major = int(major) 1676 ' a recent development release.'
1674 minor = int(minor) 1677 .format(versionToStr(requiredVersions["pyqt6"]))
1675 pat = int(pat) 1678 )
1676 if major == 6 and minor < 1:
1677 print('Sorry, you must have PyQt 6.1.0 or better or'
1678 ' a recent snapshot release.')
1679 exit(4) 1679 exit(4)
1680 # check for blacklisted versions 1680 # check for blacklisted versions
1681 for vers in BlackLists["PyQt6"] + PlatformBlackLists["PyQt6"]: 1681 for vers in BlackLists["PyQt6"] + PlatformBlackLists["PyQt6"]:
1682 if vers == pyqtVersion: 1682 if vers == PYQT_VERSION:
1683 print('Sorry, PyQt version {0} is not compatible with eric.' 1683 print('Sorry, PyQt version {0} is not compatible with eric.'
1684 .format(vers)) 1684 .format(versionToStr(vers)))
1685 print('Please install another version.') 1685 print('Please install another version.')
1686 exit(4) 1686 exit(4)
1687 1687
1688 # check version of QScintilla 1688 # check version of QScintilla
1689 from PyQt6.Qsci import QSCINTILLA_VERSION_STR 1689 # ===========================
1690 scintillaVersion = QSCINTILLA_VERSION_STR 1690 from PyQt6.Qsci import QSCINTILLA_VERSION, QSCINTILLA_VERSION_STR
1691 print("PyQt6-QScintilla:", QSCINTILLA_VERSION_STR.strip()) 1691 print("PyQt6-QScintilla:", QSCINTILLA_VERSION_STR.strip())
1692 # always assume, that snapshots or dev versions are new enough 1692 # always assume, that snapshots or dev versions are new enough
1693 if "snapshot" not in scintillaVersion and "dev" not in scintillaVersion: 1693 if (
1694 while scintillaVersion.count('.') < 2: 1694 "snapshot" not in QSCINTILLA_VERSION_STR and
1695 scintillaVersion += '.0' 1695 "dev" not in QSCINTILLA_VERSION_STR
1696 (major, minor, pat) = scintillaVersion.split('.')[:3] 1696 ):
1697 major = int(major) 1697 if QSCINTILLA_VERSION < requiredVersions["pyqt6-qscintilla"]:
1698 minor = int(minor) 1698 print(
1699 pat = int(pat) 1699 'Sorry, you must have PyQt6-QScintilla {0} or higher or'
1700 if ( 1700 ' a recent development release.'
1701 major < 2 or 1701 .format(versionToStr(requiredVersions["pyqt6-qscintilla"]))
1702 (major == 2 and minor < 12) or 1702 )
1703 # TODO: raise pat once QScintilla 2.12.2 is released
1704 (major == 2 and minor == 12 and pat < 1)
1705 ):
1706 print('Sorry, you must have PyQt6-QScintilla 2.12.1 or higher or'
1707 ' a recent snapshot release.')
1708 exit(5) 1703 exit(5)
1709 # check for blacklisted versions 1704 # check for blacklisted versions
1710 for vers in ( 1705 for vers in (
1711 BlackLists["QScintilla2"] + 1706 BlackLists["QScintilla2"] +
1712 PlatformBlackLists["QScintilla2"] 1707 PlatformBlackLists["QScintilla2"]
1713 ): 1708 ):
1714 if vers == scintillaVersion: 1709 if vers == QSCINTILLA_VERSION:
1715 print( 1710 print(
1716 'Sorry, QScintilla2 version {0} is not compatible with' 1711 'Sorry, QScintilla2 version {0} is not compatible with'
1717 ' eric.'.format(vers)) 1712 ' eric.'.format(versionToStr(vers)))
1718 print('Please install another version.') 1713 print('Please install another version.')
1719 exit(5) 1714 exit(5)
1720 1715
1721 # print version info for additional modules 1716 # print version info for additional modules
1722 # TODO: add info about QtSerialPort once PyQt 6.2.0/Qt 6.2.0 is released 1717 # TODO: add info about QtSerialPort once PyQt 6.2.0/Qt 6.2.0 is released

eric ide

mercurial