aboutsummaryrefslogtreecommitdiffstats
path: root/tools/missing_bindings.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/missing_bindings.py')
-rw-r--r--tools/missing_bindings.py458
1 files changed, 0 insertions, 458 deletions
diff --git a/tools/missing_bindings.py b/tools/missing_bindings.py
deleted file mode 100644
index 33a296832..000000000
--- a/tools/missing_bindings.py
+++ /dev/null
@@ -1,458 +0,0 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-# This script is used to generate a summary of missing types / classes
-# which are present in C++ Qt5, but are missing in PySide2.
-#
-# Required packages: bs4
-# Installed via: pip install bs4
-#
-# The script uses beautiful soup 4 to parse out the class names from
-# the online Qt documentation. It then tries to import the types from
-# PySide2.
-#
-# Example invocation of script:
-# python missing_bindings.py --qt-version 5.9 -w all
-# --qt-version - specify which version of qt documentation to load.
-# -w - if PyQt5 is an installed package, check if the tested
-# class also exists there.
-
-from __future__ import print_function
-
-try:
- import urllib.request as urllib2
-except ImportError:
- import urllib2
-
-import argparse
-from bs4 import BeautifulSoup
-from collections import OrderedDict
-from time import gmtime, strftime
-import sys
-import os.path
-
-modules_to_test = OrderedDict()
-
-# Essentials
-modules_to_test['QtCore'] = 'qtcore-module.html'
-modules_to_test['QtGui'] = 'qtgui-module.html'
-modules_to_test['QtMultimedia'] = 'qtmultimedia-module.html'
-modules_to_test['QtMultimediaWidgets'] = 'qtmultimediawidgets-module.html'
-modules_to_test['QtNetwork'] = 'qtnetwork-module.html'
-modules_to_test['QtQml'] = 'qtqml-module.html'
-modules_to_test['QtQuick'] = 'qtquick-module.html'
-modules_to_test['QtQuickWidgets'] = 'qtquickwidgets-module.html'
-modules_to_test['QtSql'] = 'qtsql-module.html'
-modules_to_test['QtTest'] = 'qttest-module.html'
-modules_to_test['QtWidgets'] = 'qtwidgets-module.html'
-
-# Addons
-modules_to_test['Qt3DCore'] = 'qt3dcore-module.html'
-modules_to_test['Qt3DInput'] = 'qt3dinput-module.html'
-modules_to_test['Qt3DLogic'] = 'qt3dlogic-module.html'
-modules_to_test['Qt3DRender'] = 'qt3drender-module.html'
-modules_to_test['Qt3DAnimation'] = 'qt3danimation-module.html'
-modules_to_test['Qt3DExtras'] = 'qt3dextras-module.html'
-modules_to_test['QtConcurrent'] = 'qtconcurrent-module.html'
-#modules_to_test['QtNetworkAuth'] = 'qtnetworkauth-module.html'
-modules_to_test['QtHelp'] = 'qthelp-module.html'
-modules_to_test['QtLocation'] = 'qtlocation-module.html'
-modules_to_test['QtPrintSupport'] = 'qtprintsupport-module.html'
-modules_to_test['QtScxml'] = 'qtscxml-module.html'
-#modules_to_test['QtSpeech'] = 'qtspeech-module.html'
-modules_to_test['QtSvg'] = 'qtsvg-module.html'
-modules_to_test['QtUiTools'] = 'qtuitools-module.html'
-modules_to_test['QtWebChannel'] = 'qtwebchannel-module.html'
-modules_to_test['QtWebEngine'] = 'qtwebengine-module.html'
-modules_to_test['QtWebEngineCore'] = 'qtwebenginecore-module.html'
-modules_to_test['QtWebEngineWidgets'] = 'qtwebenginewidgets-module.html'
-modules_to_test['QtWebSockets'] = 'qtwebsockets-module.html'
-modules_to_test['QtMacExtras'] = 'qtmacextras-module.html'
-modules_to_test['QtX11Extras'] = 'qtx11extras-module.html'
-modules_to_test['QtWinExtras'] = 'qtwinextras-module.html'
-modules_to_test['QtXml'] = 'qtxml-module.html'
-modules_to_test['QtXmlPatterns'] = 'qtxmlpatterns-module.html'
-modules_to_test['QtCharts'] = 'qtcharts-module.html'
-modules_to_test['QtDataVisualization'] = 'qtdatavisualization-module.html'
-modules_to_test['QtOpenGL'] = 'qtopengl-module.html'
-modules_to_test['QtPositioning'] = 'qtpositioning-module.html'
-modules_to_test['QtRemoteObjects'] = 'qtremoteobjects-module.html'
-modules_to_test['QtScriptTools'] = 'qtscripttools-module.html'
-modules_to_test['QtSensors'] = 'qtsensors-module.html'
-modules_to_test['QtSerialPort'] = 'qtserialport-module.html'
-types_to_ignore = set()
-# QtCore
-types_to_ignore.add('QFlag')
-types_to_ignore.add('QFlags')
-types_to_ignore.add('QGlobalStatic')
-types_to_ignore.add('QDebug')
-types_to_ignore.add('QDebugStateSaver')
-types_to_ignore.add('QMetaObject.Connection')
-types_to_ignore.add('QPointer')
-types_to_ignore.add('QAssociativeIterable')
-types_to_ignore.add('QSequentialIterable')
-types_to_ignore.add('QStaticPlugin')
-types_to_ignore.add('QChar')
-types_to_ignore.add('QLatin1Char')
-types_to_ignore.add('QHash')
-types_to_ignore.add('QMultiHash')
-types_to_ignore.add('QLinkedList')
-types_to_ignore.add('QList')
-types_to_ignore.add('QMap')
-types_to_ignore.add('QMultiMap')
-types_to_ignore.add('QMap.key_iterator')
-types_to_ignore.add('QPair')
-types_to_ignore.add('QQueue')
-types_to_ignore.add('QScopedArrayPointer')
-types_to_ignore.add('QScopedPointer')
-types_to_ignore.add('QScopedValueRollback')
-types_to_ignore.add('QMutableSetIterator')
-types_to_ignore.add('QSet')
-types_to_ignore.add('QSet.const_iterator')
-types_to_ignore.add('QSet.iterator')
-types_to_ignore.add('QExplicitlySharedDataPointer')
-types_to_ignore.add('QSharedData')
-types_to_ignore.add('QSharedDataPointer')
-types_to_ignore.add('QEnableSharedFromThis')
-types_to_ignore.add('QSharedPointer')
-types_to_ignore.add('QWeakPointer')
-types_to_ignore.add('QStack')
-types_to_ignore.add('QLatin1String')
-types_to_ignore.add('QString')
-types_to_ignore.add('QStringRef')
-types_to_ignore.add('QStringList')
-types_to_ignore.add('QStringMatcher')
-types_to_ignore.add('QVarLengthArray')
-types_to_ignore.add('QVector')
-types_to_ignore.add('QFutureIterator')
-types_to_ignore.add('QHashIterator')
-types_to_ignore.add('QMutableHashIterator')
-types_to_ignore.add('QLinkedListIterator')
-types_to_ignore.add('QMutableLinkedListIterator')
-types_to_ignore.add('QListIterator')
-types_to_ignore.add('QMutableListIterator')
-types_to_ignore.add('QMapIterator')
-types_to_ignore.add('QMutableMapIterator')
-types_to_ignore.add('QSetIterator')
-types_to_ignore.add('QMutableVectorIterator')
-types_to_ignore.add('QVectorIterator')
-
-# QtGui
-types_to_ignore.add('QIconEnginePlugin')
-types_to_ignore.add('QImageIOPlugin')
-types_to_ignore.add('QGenericPlugin')
-types_to_ignore.add('QGenericPluginFactory')
-types_to_ignore.add('QGenericMatrix')
-types_to_ignore.add('QOpenGLExtraFunctions')
-types_to_ignore.add('QOpenGLFunctions')
-types_to_ignore.add('QOpenGLFunctions_1_0')
-types_to_ignore.add('QOpenGLFunctions_1_1')
-types_to_ignore.add('QOpenGLFunctions_1_2')
-types_to_ignore.add('QOpenGLFunctions_1_3')
-types_to_ignore.add('QOpenGLFunctions_1_4')
-types_to_ignore.add('QOpenGLFunctions_1_5')
-types_to_ignore.add('QOpenGLFunctions_2_0')
-types_to_ignore.add('QOpenGLFunctions_2_1')
-types_to_ignore.add('QOpenGLFunctions_3_0')
-types_to_ignore.add('QOpenGLFunctions_3_1')
-types_to_ignore.add('QOpenGLFunctions_3_2_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_3_2_Core')
-types_to_ignore.add('QOpenGLFunctions_3_3_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_3_3_Core')
-types_to_ignore.add('QOpenGLFunctions_4_0_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_0_Core')
-types_to_ignore.add('QOpenGLFunctions_4_1_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_1_Core')
-types_to_ignore.add('QOpenGLFunctions_4_2_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_2_Core')
-types_to_ignore.add('QOpenGLFunctions_4_3_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_3_Core')
-types_to_ignore.add('QOpenGLFunctions_4_4_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_4_Core')
-types_to_ignore.add('QOpenGLFunctions_4_5_Compatibility')
-types_to_ignore.add('QOpenGLFunctions_4_5_Core')
-types_to_ignore.add('QOpenGLFunctions_ES2')
-
-# QtWidgets
-types_to_ignore.add('QItemEditorCreator')
-types_to_ignore.add('QStandardItemEditorCreator')
-types_to_ignore.add('QStylePlugin')
-
-# QtSql
-types_to_ignore.add('QSqlDriverCreator')
-types_to_ignore.add('QSqlDriverPlugin')
-
-qt_documentation_website_prefixes = OrderedDict()
-qt_documentation_website_prefixes['5.6'] = 'http://doc.qt.io/qt-5.6/'
-qt_documentation_website_prefixes['5.8'] = 'http://doc.qt.io/qt-5.8/'
-qt_documentation_website_prefixes['5.9'] = 'http://doc.qt.io/qt-5.9/'
-qt_documentation_website_prefixes['5.10'] = 'http://doc.qt.io/qt-5.10/'
-qt_documentation_website_prefixes['5.11'] = 'http://doc.qt.io/qt-5.11/'
-qt_documentation_website_prefixes['5.11'] = 'http://doc.qt.io/qt-5.11/'
-qt_documentation_website_prefixes['5.12'] = 'http://doc.qt.io/qt-5.12/'
-qt_documentation_website_prefixes['5.13'] = 'http://doc.qt.io/qt-5.13/'
-qt_documentation_website_prefixes['5.14'] = 'http://doc.qt.io/qt-5.14/'
-qt_documentation_website_prefixes['5.15'] = 'http://doc.qt.io/qt-5/'
-qt_documentation_website_prefixes['dev'] = 'http://doc-snapshots.qt.io/qt5-dev/'
-
-
-def qt_version_to_doc_prefix(version):
- if version in qt_documentation_website_prefixes:
- return qt_documentation_website_prefixes[version]
- else:
- raise RuntimeError("The specified qt version is not supported")
-
-
-def create_doc_url(module_doc_page_url, version):
- return qt_version_to_doc_prefix(version) + module_doc_page_url
-
-parser = argparse.ArgumentParser()
-parser.add_argument("module",
- default='all',
- choices=list(modules_to_test.keys()).append('all'),
- nargs='?',
- type=str,
- help="the Qt module for which to get the missing types")
-parser.add_argument("--qt-version",
- "-v",
- default='5.15',
- choices=['5.6', '5.9', '5.11', '5.12', '5.13', '5.14', '5.15', 'dev'],
- type=str,
- dest='version',
- help="the Qt version to use to check for types")
-parser.add_argument("--which-missing",
- "-w",
- default='all',
- choices=['all', 'in-pyqt', 'not-in-pyqt'],
- type=str,
- dest='which_missing',
- help="Which missing types to show (all, or just those "
- "that are not present in PyQt)")
-
-args = parser.parse_args()
-
-if hasattr(args, "module") and args.module != 'all':
- saved_value = modules_to_test[args.module]
- modules_to_test.clear()
- modules_to_test[args.module] = saved_value
-
-pyside_package_name = "PySide2"
-pyqt_package_name = "PyQt5"
-
-total_missing_types_count = 0
-total_missing_types_count_compared_to_pyqt = 0
-total_missing_modules_count = 0
-
-wiki_file = open('missing_bindings_for_wiki_qt_io.txt', 'w')
-wiki_file.truncate()
-
-
-def log(*pargs, **kw):
- print(*pargs)
-
- computed_str = ''
- for arg in pargs:
- computed_str += str(arg)
-
- style = 'text'
- if 'style' in kw:
- style = kw['style']
-
- if style == 'heading1':
- computed_str = '= ' + computed_str + ' ='
- elif style == 'heading5':
- computed_str = '===== ' + computed_str + ' ====='
- elif style == 'with_newline':
- computed_str += '\n'
- elif style == 'bold_colon':
- computed_str = computed_str.replace(':', ":'''")
- computed_str += "'''"
- computed_str += '\n'
- elif style == 'error':
- computed_str = "''" + computed_str.strip('\n') + "''\n"
- elif style == 'text_with_link':
- computed_str = computed_str
- elif style == 'code':
- computed_str = ' ' + computed_str
- elif style == 'end':
- return
-
- print(computed_str, file=wiki_file)
-
-log('PySide2 bindings for Qt {}'.format(args.version), style='heading1')
-
-log("""Using Qt version {} documentation to find public API Qt types and test
-if the types are present in the PySide2 package.""".format(args.version))
-
-log("""Results are usually stored at
-https://wiki.qt.io/PySide2_Missing_Bindings
-so consider taking the contents of the generated
-missing_bindings_for_wiki_qt_io.txt file and updating the linked wiki page.""",
-style='end')
-
-log("""Similar report:
-https://gist.github.com/ethanhs/6c626ca4e291f3682589699296377d3a""",
-style='text_with_link')
-
-python_executable = os.path.basename(sys.executable or '')
-command_line_arguments = ' '.join(sys.argv)
-report_date = strftime("%Y-%m-%d %H:%M:%S %Z", gmtime())
-
-log("""
-This report was generated by running the following command:
- {} {}
-on the following date:
- {}
-""".format(python_executable, command_line_arguments, report_date))
-
-for module_name in modules_to_test.keys():
- log(module_name, style='heading5')
-
- url = create_doc_url(modules_to_test[module_name], args.version)
- log('Documentation link: {}\n'.format(url), style='text_with_link')
-
- # Import the tested module
- try:
- pyside_tested_module = getattr(__import__(pyside_package_name,
- fromlist=[module_name]), module_name)
- except Exception as e:
- log('\nCould not load {}.{}. Received error: {}. Skipping.\n'.format(
- pyside_package_name, module_name, str(e).replace("'", '')),
- style='error')
- total_missing_modules_count += 1
- continue
-
- try:
- pyqt_module_name = module_name
- if module_name == "QtCharts":
- pyqt_module_name = module_name[:-1]
-
- pyqt_tested_module = getattr(__import__(pyqt_package_name,
- fromlist=[pyqt_module_name]), pyqt_module_name)
- except Exception as e:
- log("\nCould not load {}.{} for comparison. "
- "Received error: {}.\n".format(pyqt_package_name, module_name,
- str(e).replace("'", '')), style='error')
-
- # Get C++ class list from documentation page.
- page = urllib2.urlopen(url)
- soup = BeautifulSoup(page, 'html.parser')
-
- # Extract the Qt type names from the documentation classes table
- links = soup.body.select('.annotated a')
- types_on_html_page = []
-
- for link in links:
- link_text = link.text
- link_text = link_text.replace('::', '.')
- if link_text not in types_to_ignore:
- types_on_html_page.append(link_text)
-
- log('Number of types in {}: {}'.format(module_name,
- len(types_on_html_page)), style='bold_colon')
-
- missing_types_count = 0
- missing_types_compared_to_pyqt = 0
- missing_types = []
- for qt_type in types_on_html_page:
- try:
- pyside_qualified_type = 'pyside_tested_module.'
-
- if "QtCharts" == module_name:
- pyside_qualified_type += 'QtCharts.'
- elif "DataVisualization" in module_name:
- pyside_qualified_type += 'QtDataVisualization.'
-
- pyside_qualified_type += qt_type
- eval(pyside_qualified_type)
- except:
- missing_type = qt_type
- missing_types_count += 1
- total_missing_types_count += 1
-
- is_present_in_pyqt = False
- try:
- pyqt_qualified_type = 'pyqt_tested_module.'
-
- if "Charts" in module_name:
- pyqt_qualified_type += 'QtCharts.'
- elif "DataVisualization" in module_name:
- pyqt_qualified_type += 'QtDataVisualization.'
-
- pyqt_qualified_type += qt_type
- eval(pyqt_qualified_type)
- missing_type += " (is present in PyQt5)"
- missing_types_compared_to_pyqt += 1
- total_missing_types_count_compared_to_pyqt += 1
- is_present_in_pyqt = True
- except:
- pass
-
- if args.which_missing == 'all':
- missing_types.append(missing_type)
- elif args.which_missing == 'in-pyqt' and is_present_in_pyqt:
- missing_types.append(missing_type)
- elif (args.which_missing == 'not-in-pyqt' and
- not is_present_in_pyqt):
- missing_types.append(missing_type)
-
- if len(missing_types) > 0:
- log('Missing types in {}:'.format(module_name), style='with_newline')
- missing_types.sort()
- for missing_type in missing_types:
- log(missing_type, style='code')
- log('')
-
- log('Number of missing types: {}'.format(missing_types_count),
- style='bold_colon')
- if len(missing_types) > 0:
- log('Number of missing types that are present in PyQt5: {}'
- .format(missing_types_compared_to_pyqt), style='bold_colon')
- log('End of missing types for {}\n'.format(module_name), style='end')
- else:
- log('', style='end')
-
-log('Summary', style='heading5')
-log('Total number of missing types: {}'.format(total_missing_types_count),
- style='bold_colon')
-log('Total number of missing types that are present in PyQt5: {}'
- .format(total_missing_types_count_compared_to_pyqt), style='bold_colon')
-log('Total number of missing modules: {}'
- .format(total_missing_modules_count), style='bold_colon')
-wiki_file.close()