mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-23 00:02:38 -05:00
add 2to3 script to migrate PyQt4 to PyQt wrappers
This commit is contained in:
parent
964ae1ff04
commit
d57b2fa384
7
scripts/2to3
Executable file
7
scripts/2to3
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
import sys, os
|
||||
|
||||
from lib2to3.main import main
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__))))
|
||||
sys.exit(main('qgis_fixes'))
|
501
scripts/qgis_fixes/fix_pyqt.py
Normal file
501
scripts/qgis_fixes/fix_pyqt.py
Normal file
@ -0,0 +1,501 @@
|
||||
"""Migrate imports of PyQt4 to PyQt wrapper
|
||||
"""
|
||||
# Author: Juergen E. Fischer
|
||||
# Adapted from fix_urllib
|
||||
|
||||
# Local imports
|
||||
from lib2to3.fixes.fix_imports import alternates, FixImports
|
||||
from lib2to3 import fixer_base
|
||||
from lib2to3.fixer_util import (Name, Comma, FromImport, Newline,
|
||||
find_indentation, Node, syms)
|
||||
|
||||
MAPPING = {
|
||||
"PyQt4.QtGui": [
|
||||
("PyQt.QtGui", [
|
||||
"QIcon",
|
||||
"QCursor",
|
||||
"QColor",
|
||||
"QDesktopServices",
|
||||
"QFont",
|
||||
"QFontMetrics",
|
||||
"QKeySequence",
|
||||
"QStandardItemModel",
|
||||
"QStandardItem",
|
||||
"QClipboard",
|
||||
"QPixmap",
|
||||
"QDoubleValidator",
|
||||
"QPainter",
|
||||
"QPen",
|
||||
"QBrush",
|
||||
"QPalette",
|
||||
"QPainterPath",
|
||||
"QImage",
|
||||
"QPolygonF",
|
||||
"QFontMetricsF",
|
||||
"QGradient",
|
||||
]),
|
||||
("PyQt.QtWidgets", [
|
||||
"QAbstractButton",
|
||||
"QAbstractGraphicsShapeItem",
|
||||
"QAbstractItemDelegate",
|
||||
"QAbstractItemView",
|
||||
"QAbstractScrollArea",
|
||||
"QAbstractSlider",
|
||||
"QAbstractSpinBox",
|
||||
"QAbstractTableModel",
|
||||
"QAction",
|
||||
"QActionGroup",
|
||||
"QApplication",
|
||||
"QBoxLayout",
|
||||
"QButtonGroup",
|
||||
"QCalendarWidget",
|
||||
"QCheckBox",
|
||||
"QColorDialog",
|
||||
"QColumnView",
|
||||
"QComboBox",
|
||||
"QCommandLinkButton",
|
||||
"QCommonStyle",
|
||||
"QCompleter",
|
||||
"QDataWidgetMapper",
|
||||
"QDateEdit",
|
||||
"QDateTimeEdit",
|
||||
"QDesktopWidget",
|
||||
"QDial",
|
||||
"QDialog",
|
||||
"QDialogButtonBox",
|
||||
"QDirModel",
|
||||
"QDockWidget",
|
||||
"QDoubleSpinBox",
|
||||
"QErrorMessage",
|
||||
"QFileDialog",
|
||||
"QFileIconProvider",
|
||||
"QFileSystemModel",
|
||||
"QFocusFrame",
|
||||
"QFontComboBox",
|
||||
"QFontDialog",
|
||||
"QFormLayout",
|
||||
"QFrame",
|
||||
"QGesture",
|
||||
"QGestureEvent",
|
||||
"QGestureRecognizer",
|
||||
"QGraphicsAnchor",
|
||||
"QGraphicsAnchorLayout",
|
||||
"QGraphicsBlurEffect",
|
||||
"QGraphicsColorizeEffect",
|
||||
"QGraphicsDropShadowEffect",
|
||||
"QGraphicsEffect",
|
||||
"QGraphicsEllipseItem",
|
||||
"QGraphicsGridLayout",
|
||||
"QGraphicsItem",
|
||||
"QGraphicsItemGroup",
|
||||
"QGraphicsLayout",
|
||||
"QGraphicsLayoutItem",
|
||||
"QGraphicsLineItem",
|
||||
"QGraphicsLinearLayout",
|
||||
"QGraphicsObject",
|
||||
"QGraphicsOpacityEffect",
|
||||
"QGraphicsPathItem",
|
||||
"QGraphicsPixmapItem",
|
||||
"QGraphicsPolygonItem",
|
||||
"QGraphicsProxyWidget",
|
||||
"QGraphicsRectItem",
|
||||
"QGraphicsRotation",
|
||||
"QGraphicsScale",
|
||||
"QGraphicsScene",
|
||||
"QGraphicsSceneContextMenuEvent",
|
||||
"QGraphicsSceneDragDropEvent",
|
||||
"QGraphicsSceneEvent",
|
||||
"QGraphicsSceneHelpEvent",
|
||||
"QGraphicsSceneHoverEvent",
|
||||
"QGraphicsSceneMouseEvent",
|
||||
"QGraphicsSceneMoveEvent",
|
||||
"QGraphicsSceneResizeEvent",
|
||||
"QGraphicsSceneWheelEvent",
|
||||
"QGraphicsSimpleTextItem",
|
||||
"QGraphicsTextItem",
|
||||
"QGraphicsTransform",
|
||||
"QGraphicsView",
|
||||
"QGraphicsWidget",
|
||||
"QGridLayout",
|
||||
"QGroupBox",
|
||||
"QHBoxLayout",
|
||||
"QHeaderView",
|
||||
"QInputDialog",
|
||||
"QItemDelegate",
|
||||
"QItemEditorCreatorBase",
|
||||
"QItemEditorFactory",
|
||||
"QKeyEventTransition",
|
||||
"QLCDNumber",
|
||||
"QLabel",
|
||||
"QLayout",
|
||||
"QLayoutItem",
|
||||
"QLineEdit",
|
||||
"QListView",
|
||||
"QListWidget",
|
||||
"QListWidgetItem",
|
||||
"QMainWindow",
|
||||
"QMdiArea",
|
||||
"QMdiSubWindow",
|
||||
"QMenu",
|
||||
"QMenuBar",
|
||||
"QMessageBox",
|
||||
"QMouseEventTransition",
|
||||
"QPanGesture",
|
||||
"QPinchGesture",
|
||||
"QPlainTextDocumentLayout",
|
||||
"QPlainTextEdit",
|
||||
"QProgressBar",
|
||||
"QProgressDialog",
|
||||
"QPushButton",
|
||||
"QRadioButton",
|
||||
"QRubberBand",
|
||||
"QScrollArea",
|
||||
"QScrollBar",
|
||||
"QShortcut",
|
||||
"QSizeGrip",
|
||||
"QSizePolicy",
|
||||
"QSlider",
|
||||
"QSpacerItem",
|
||||
"QSpinBox",
|
||||
"QSplashScreen",
|
||||
"QSplitter",
|
||||
"QSplitterHandle",
|
||||
"QStackedLayout",
|
||||
"QStackedWidget",
|
||||
"QStatusBar",
|
||||
"QStyle",
|
||||
"QStyleFactory",
|
||||
"QStyleHintReturn",
|
||||
"QStyleHintReturnMask",
|
||||
"QStyleHintReturnVariant",
|
||||
"QStyleOption",
|
||||
"QStyleOptionButton",
|
||||
"QStyleOptionComboBox",
|
||||
"QStyleOptionComplex",
|
||||
"QStyleOptionDockWidget",
|
||||
"QStyleOptionFocusRect",
|
||||
"QStyleOptionFrame",
|
||||
"QStyleOptionGraphicsItem",
|
||||
"QStyleOptionGroupBox",
|
||||
"QStyleOptionHeader",
|
||||
"QStyleOptionMenuItem",
|
||||
"QStyleOptionProgressBar",
|
||||
"QStyleOptionRubberBand",
|
||||
"QStyleOptionSizeGrip",
|
||||
"QStyleOptionSlider",
|
||||
"QStyleOptionSpinBox",
|
||||
"QStyleOptionTab",
|
||||
"QStyleOptionTabBarBase",
|
||||
"QStyleOptionTabWidgetFrame",
|
||||
"QStyleOptionTitleBar",
|
||||
"QStyleOptionToolBar",
|
||||
"QStyleOptionToolBox",
|
||||
"QStyleOptionToolButton",
|
||||
"QStyleOptionViewItem",
|
||||
"QStylePainter",
|
||||
"QStyledItemDelegate",
|
||||
"QSwipeGesture",
|
||||
"QSystemTrayIcon",
|
||||
"QTabBar",
|
||||
"QTabWidget",
|
||||
"QTableView",
|
||||
"QTableWidget",
|
||||
"QTableWidgetItem",
|
||||
"QTableWidgetSelectionRange",
|
||||
"QTapAndHoldGesture",
|
||||
"QTapGesture",
|
||||
"QTextBrowser",
|
||||
"QTextEdit",
|
||||
"QTimeEdit",
|
||||
"QToolBar",
|
||||
"QToolBox",
|
||||
"QToolButton",
|
||||
"QToolTip",
|
||||
"QTreeView",
|
||||
"QTreeWidget",
|
||||
"QTreeWidgetItem",
|
||||
"QTreeWidgetItemIterator",
|
||||
"QUndoCommand",
|
||||
"QUndoGroup",
|
||||
"QUndoStack",
|
||||
"QUndoView",
|
||||
"QVBoxLayout",
|
||||
"QWhatsThis",
|
||||
"QWidget",
|
||||
"QWidgetAction",
|
||||
"QWidgetItem",
|
||||
"QWizard",
|
||||
"QWizardPage",
|
||||
"qApp",
|
||||
"qDrawBorderPixmap",
|
||||
"qDrawPlainRect",
|
||||
"qDrawShadeLine",
|
||||
"qDrawShadePanel",
|
||||
"qDrawShadeRect",
|
||||
"qDrawWinButton",
|
||||
"qDrawWinPanel",
|
||||
]),
|
||||
("PyQt.QtPrintSupport", [
|
||||
"QPrinter",
|
||||
"QAbstractPrintDialog",
|
||||
"QPageSetupDialog",
|
||||
"QPrintDialog",
|
||||
"QPrintEngine",
|
||||
"QPrintPreviewDialog",
|
||||
"QPrintPreviewWidget",
|
||||
"QPrinterInfo",
|
||||
]),
|
||||
("PyQt.QtCore", [
|
||||
"QItemSelectionModel",
|
||||
"QSortFilterProxyModel",
|
||||
]),
|
||||
],
|
||||
"PyQt4.QtCore": [
|
||||
("PyQt.QtCore", [
|
||||
"QAbstractItemModel",
|
||||
"QAbstractTableModel",
|
||||
"QByteArray",
|
||||
"QCoreApplication",
|
||||
"QDataStream",
|
||||
"QDir",
|
||||
"QEvent",
|
||||
"QFile",
|
||||
"QFileInfo",
|
||||
"QIODevice",
|
||||
"QLocale",
|
||||
"QMimeData",
|
||||
"QModelIndex",
|
||||
"QMutex",
|
||||
"QObject",
|
||||
"QProcess",
|
||||
"QSettings",
|
||||
"QSize",
|
||||
"QSizeF",
|
||||
"QTextCodec",
|
||||
"QThread",
|
||||
"QThreadPool",
|
||||
"QTimer",
|
||||
"QTranslator",
|
||||
"QUrl",
|
||||
"Qt",
|
||||
"pyqtProperty",
|
||||
"pyqtWrapperType",
|
||||
"pyqtSignal",
|
||||
"qDebug",
|
||||
"qWarning",
|
||||
"QDate",
|
||||
"QTime",
|
||||
"QDateTime",
|
||||
"QRegExp",
|
||||
"QTemporaryFile",
|
||||
"QTextStream",
|
||||
"QVariant",
|
||||
"QPyNullVariant",
|
||||
"QRect",
|
||||
"QRectF",
|
||||
"QMetaObject",
|
||||
"QPoint",
|
||||
"QPointF",
|
||||
"QDirIterator",
|
||||
"SIGNAL",
|
||||
"SLOT",
|
||||
]),
|
||||
],
|
||||
"PyQt4.QtNetwork": [
|
||||
( "PyQt.QtNetwork", ["QNetworkReply","QNetworkRequest"] )
|
||||
],
|
||||
"PyQt4.QtXml": [
|
||||
( "PyQt.QtXml", [
|
||||
"QDomDocument"
|
||||
]),
|
||||
],
|
||||
"PyQt4.QtSci": [
|
||||
( "PyQt.QtSci", [
|
||||
"QsciAPIs",
|
||||
"QsciLexerCustom",
|
||||
"QsciLexerPython",
|
||||
"QsciScintilla",
|
||||
"QsciLexerSQL",
|
||||
]),
|
||||
],
|
||||
"PyQt4.QtWebkit": [
|
||||
( "PyQt.QtWebkitWidgets", [
|
||||
"QGraphicsWebView",
|
||||
"QWebFrame",
|
||||
"QWebHitTestResult",
|
||||
"QWebInspector",
|
||||
"QWebPage",
|
||||
"QWebView",
|
||||
]),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_pattern():
|
||||
bare = set()
|
||||
for old_module, changes in MAPPING.items():
|
||||
for change in changes:
|
||||
new_module, members = change
|
||||
members = alternates(members)
|
||||
yield """import_name< 'import' (module=%r
|
||||
| dotted_as_names< any* module=%r any* >) >
|
||||
""" % (old_module, old_module)
|
||||
if '.' not in old_module:
|
||||
yield """import_from< 'from' mod_member=%r 'import'
|
||||
( member=%s | import_as_name< member=%s 'as' any > |
|
||||
import_as_names< members=any* >) >
|
||||
""" % (old_module, members, members)
|
||||
else:
|
||||
dotted = old_module.split('.')
|
||||
assert len(dotted)==2
|
||||
yield """import_from< 'from' mod_member=dotted_name<%r '.' %r> 'import'
|
||||
( member=%s | import_as_name< member=%s 'as' any > |
|
||||
import_as_names< members=any* >) >
|
||||
""" % ( dotted[0], dotted[1], members, members)
|
||||
yield """import_from< 'from' module_star=%r 'import' star='*' >
|
||||
""" % old_module
|
||||
yield """import_name< 'import'
|
||||
dotted_as_name< module_as=%r 'as' any > >
|
||||
""" % old_module
|
||||
# bare_with_attr has a special significance for FixImports.match().
|
||||
yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >
|
||||
""" % (old_module, members)
|
||||
|
||||
|
||||
class FixPyqt(FixImports):
|
||||
|
||||
def build_pattern(self):
|
||||
return "|".join(build_pattern())
|
||||
|
||||
def transform_import(self, node, results):
|
||||
"""Transform for the basic import case. Replaces the old
|
||||
import name with a comma separated list of its
|
||||
replacements.
|
||||
"""
|
||||
import_mod = results.get("module")
|
||||
pref = import_mod.prefix
|
||||
|
||||
names = []
|
||||
|
||||
# create a Node list of the replacement modules
|
||||
for name in MAPPING[import_mod.value][:-1]:
|
||||
names.extend([Name(name[0], prefix=pref), Comma()])
|
||||
names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
|
||||
import_mod.replace(names)
|
||||
|
||||
def transform_member(self, node, results):
|
||||
"""Transform for imports of specific module elements. Replaces
|
||||
the module to be imported from with the appropriate new
|
||||
module.
|
||||
"""
|
||||
mod_member = results.get("mod_member")
|
||||
if isinstance(mod_member,Node):
|
||||
module = ""
|
||||
for l in mod_member.leaves():
|
||||
module += l.value
|
||||
mod_member.value = module
|
||||
pref = mod_member.prefix
|
||||
member = results.get("member")
|
||||
|
||||
# Simple case with only a single member being imported
|
||||
if member:
|
||||
# this may be a list of length one, or just a node
|
||||
if isinstance(member, list):
|
||||
member = member[0]
|
||||
new_name = None
|
||||
for change in MAPPING[mod_member.value]:
|
||||
if member.value in change[1]:
|
||||
new_name = change[0]
|
||||
break
|
||||
if new_name:
|
||||
mod_member.replace(Name(new_name, prefix=pref))
|
||||
else:
|
||||
self.cannot_convert(node, "This is an invalid module element")
|
||||
|
||||
# Multiple members being imported
|
||||
else:
|
||||
# a dictionary for replacements, order matters
|
||||
modules = []
|
||||
mod_dict = {}
|
||||
members = results["members"]
|
||||
for member in members:
|
||||
# we only care about the actual members
|
||||
if member.type == syms.import_as_name:
|
||||
as_name = member.children[2].value
|
||||
member_name = member.children[0].value
|
||||
else:
|
||||
member_name = member.value
|
||||
as_name = None
|
||||
if member_name != u",":
|
||||
found = False
|
||||
for change in MAPPING[mod_member.value]:
|
||||
if member_name in change[1]:
|
||||
if change[0] not in mod_dict:
|
||||
modules.append(change[0])
|
||||
mod_dict.setdefault(change[0], []).append(member)
|
||||
found = True
|
||||
if not found:
|
||||
f = open( "/tmp/missing", "a+" )
|
||||
f.write ( "member %s of %s not found\n" % (member_name, mod_member.value) )
|
||||
f.close()
|
||||
|
||||
new_nodes = []
|
||||
indentation = find_indentation(node)
|
||||
first = True
|
||||
def handle_name(name, prefix):
|
||||
if name.type == syms.import_as_name:
|
||||
kids = [Name(name.children[0].value, prefix=prefix),
|
||||
name.children[1].clone(),
|
||||
name.children[2].clone()]
|
||||
return [Node(syms.import_as_name, kids)]
|
||||
return [Name(name.value, prefix=prefix)]
|
||||
for module in modules:
|
||||
elts = mod_dict[module]
|
||||
names = []
|
||||
for elt in elts[:-1]:
|
||||
names.extend(handle_name(elt, pref))
|
||||
names.append(Comma())
|
||||
names.extend(handle_name(elts[-1], pref))
|
||||
new = FromImport(module, names)
|
||||
if not first or node.parent.prefix.endswith(indentation):
|
||||
new.prefix = indentation
|
||||
new_nodes.append(new)
|
||||
first = False
|
||||
if new_nodes:
|
||||
nodes = []
|
||||
for new_node in new_nodes[:-1]:
|
||||
nodes.extend([new_node, Newline()])
|
||||
nodes.append(new_nodes[-1])
|
||||
node.replace(nodes)
|
||||
else:
|
||||
self.cannot_convert(node, "All module elements are invalid")
|
||||
|
||||
def transform_dot(self, node, results):
|
||||
"""Transform for calls to module members in code."""
|
||||
module_dot = results.get("bare_with_attr")
|
||||
member = results.get("member")
|
||||
new_name = None
|
||||
if isinstance(member, list):
|
||||
member = member[0]
|
||||
for change in MAPPING[module_dot.value]:
|
||||
if member.value in change[1]:
|
||||
new_name = change[0]
|
||||
break
|
||||
if new_name:
|
||||
module_dot.replace(Name(new_name,
|
||||
prefix=module_dot.prefix))
|
||||
else:
|
||||
self.cannot_convert(node, "This is an invalid module element")
|
||||
|
||||
def transform(self, node, results):
|
||||
if results.get("module"):
|
||||
self.transform_import(node, results)
|
||||
elif results.get("mod_member"):
|
||||
self.transform_member(node, results)
|
||||
elif results.get("bare_with_attr"):
|
||||
self.transform_dot(node, results)
|
||||
# Renaming and star imports are not supported for these modules.
|
||||
elif results.get("module_star"):
|
||||
self.cannot_convert(node, "Cannot handle star imports.")
|
||||
elif results.get("module_as"):
|
||||
self.cannot_convert(node, "This module is now multiple modules")
|
Loading…
x
Reference in New Issue
Block a user