From 9d5c42fbbab573dce39d425b150c0fcd86a4c87d Mon Sep 17 00:00:00 2001 From: Raphael Groner Date: Feb 28 2016 11:57:32 +0000 Subject: v2.2.3 --- diff --git a/python-qutepart.spec b/python-qutepart.spec index 0485f86..191dde0 100644 --- a/python-qutepart.spec +++ b/python-qutepart.spec @@ -1,17 +1,30 @@ %global srcname qutepart %global sum Code editor widget +%global desc_common \ +Qutepart is a code editor widget for PyQt. Features: \ + - Syntax highlighting for 196 languages. \ + - Smart indentation for many languages. \ + - Line numbers. \ + - Bookmarks. \ + - Advanced edit operations. \ + - Matching braces highlighting. \ + - Autocompletion based on document content. \ + - Marking too long lines with red line. \ + - Rectangular selection and copy-paste. \ + - Linter marks support. + %if 0%{?fedora} %bcond_without python3 %endif -%global py3_commit0 0e9612914f0ab90fd62c8160590191bfe4153658 -%global py3_date 20151020 +%global py3_commit0 b4368fd3c0cee1c885fac9382608e1283801064b +%global py3_date 20151124 Name: python-%{srcname} -Version: 2.2.2 -Release: 6%{?dist} +Version: 2.2.3 +Release: 1%{?dist} Summary: %{sum} License: LGPLv2+ @@ -20,10 +33,8 @@ URL: https://github.com/hlamer/%{srcname} Source0: %{url}/archive/v%{version}.tar.gz#/%{srcname}-%{version}.tar.gz # experimental python3 from upstream py3 branch as a subpackage # https://github.com/hlamer/qutepart/issues/30 -Patch0: %{url}/compare/v%{version}...%{py3_commit0}.patch#/%{srcname}-py3.patch -# AttributeError: type object 'QApplication' has no attribute 'instance' -# https://github.com/hlamer/qutepart/issues/29 -Patch1: %{url}/compare/v%{version}...39dc2a200a11a293611e995429c80c9b0fa545e7.patch#/%{srcname}-docs.patch +# important: before downloading a new diff because new py3_commit0, delete the old file! +Patch0: %{url}/compare/v%{version}...%{py3_commit0}.patch#/%{srcname}-py3-%{py3_commit0}.patch BuildRequires: pcre-devel Requires: pcre @@ -47,17 +58,7 @@ BuildRequires: python3-sphinx BuildRequires: xorg-x11-server-Xvfb %description -Qutepart is a code editor widget for PyQt. Features: - - Syntax highlighting for 196 languages. - - Smart indentation for many languages. - - Line numbers. - - Bookmarks. - - Advanced edit operations. - - Matching braces highlighting. - - Autocompletion based on document content. - - Marking too long lines with red line. - - Rectangular selection and copy-paste. - - Linter marks support. +%{desc_common} %package -n python2-%{srcname} @@ -65,38 +66,16 @@ Summary: %{sum} %{?python_provide:%python_provide python2-%{srcname}} %description -n python2-%{srcname} -Qutepart is a code editor widget for PyQt. Features: - - Syntax highlighting for 196 languages. - - Smart indentation for many languages. - - Line numbers. - - Bookmarks. - - Advanced edit operations. - - Matching braces highlighting. - - Autocompletion based on document content. - - Marking too long lines with red line. - - Rectangular selection and copy-paste. - - Linter marks support. +%{desc_common} -%if 0%{with python3} %package -n python3-%{srcname} -Release: 6.%{py3_date}git%(c=%{py3_commit0}; echo ${c:0:7})%{?dist} +Release: 6.%{py3_date}git%(c=%{py3_commit0}; echo ${c:0:1%{?dist}}) Summary: %{sum} %{?python_provide:%python_provide python3-%{srcname}} %description -n python3-%{srcname} -Qutepart is a code editor widget for PyQt. Features: - - Syntax highlighting for 196 languages. - - Smart indentation for many languages. - - Line numbers. - - Bookmarks. - - Advanced edit operations. - - Matching braces highlighting. - - Autocompletion based on document content. - - Marking too long lines with red line. - - Rectangular selection and copy-paste. - - Linter marks support. -%endif +%{desc_common} %prep @@ -117,9 +96,6 @@ rm tests/test_bookmarks.py tests/test_bracket_hlighter.py tests/test_completion. popd %endif -# python2 -%patch1 -p1 - %build # we need CFLAGS for internal gcc call, py2_build sets them @@ -185,6 +161,9 @@ xvfb-run -a %{__python3} run_all.py %changelog +* Sun Feb 28 2016 Raphael Groner - 2.2.3-1 +- new version + * Sat Feb 27 2016 Raphael Groner - 2.2.2-6 - rebuild to validate dependencies (bug with librsvg-2.so.2) diff --git a/qutepart-py3.patch b/qutepart-py3.patch deleted file mode 100644 index a9283cd..0000000 --- a/qutepart-py3.patch +++ /dev/null @@ -1,2018 +0,0 @@ -From c108980a24445f53bc2d8ffa2799fb323628f73b Mon Sep 17 00:00:00 2001 -From: Andrei Kopats -Date: Sun, 22 Jun 2014 11:42:09 +0300 -Subject: [PATCH 1/4] Use Python 3 - ---- - README.md | 4 +- - debian/control | 6 +- - doc/source/conf.py | 16 ++-- - editor.py | 4 +- - profiling/typing_performance_test.py | 12 +-- - qutepart/__init__.py | 12 +-- - qutepart/indenter/cstyle.py | 2 +- - qutepart/lines.py | 2 +- - qutepart/rectangularselection.py | 13 +-- - qutepart/syntax/__init__.py | 2 +- - qutepart/syntax/data/regenerate-definitions-db.py | 4 +- - qutepart/syntax/loader.py | 28 +++--- - qutepart/syntax/parser.py | 10 +-- - qutepart/vim.py | 8 +- - rpm/python-qutepart.spec | 16 ++-- - setup.py | 30 +++---- - tests/run_all.py | 2 +- - tests/test_actions.py | 2 +- - tests/test_api.py | 100 +++++++++++----------- - tests/test_bookmarks.py | 2 +- - tests/test_bracket_hlighter.py | 2 +- - tests/test_completion.py | 2 +- - tests/test_draw_whitespace.py | 6 +- - tests/test_edit.py | 2 +- - tests/test_indent.py | 2 +- - tests/test_indenter/indenttest.py | 2 +- - tests/test_indenter/test_cstyle.py | 5 +- - tests/test_indenter/test_haskell.py | 6 +- - tests/test_indenter/test_lisp.py | 5 +- - tests/test_indenter/test_normal.py | 5 +- - tests/test_indenter/test_python.py | 5 +- - tests/test_indenter/test_ruby.py | 5 +- - tests/test_indenter/test_scheme.py | 5 +- - tests/test_indenter/test_xmlindent.py | 5 +- - tests/test_rectangular_selection.py | 6 +- - tests/test_syntax/test_dynamic_substitution.py | 2 +- - tests/test_syntax/test_rules.py | 18 ++-- - tests/test_syntax/test_xml_definition_parsing.py | 2 +- - tests/test_vim.py | 4 +- - tools/show-syntax.py | 6 +- - 40 files changed, 198 insertions(+), 172 deletions(-) - -diff --git a/README.md b/README.md -index 66ae1f3..27e1256 100644 ---- a/README.md -+++ b/README.md -@@ -20,7 +20,7 @@ Component has been created for [Enki editor](http://enki-editor.org) as replacem - - Qutepart depends on: - --* Python 2.7 -+* Python 3 - * PyQt4 (see *Known problems* section) - * pcre - -@@ -29,7 +29,7 @@ On Debian, Ubuntu and other Linuxes install package `libpcreX-dev`, where `X` is - For other OSes - see instructions on pcre website - - #### 2. Install Python development files --On Debian, Ubuntu and other Linuxes install package `python-dev`, on other systems - see Python website -+On Debian, Ubuntu and other Linuxes install package `python3-dev`, on other systems - see Python website - - #### 3. Install C compiler - It will probably be gcc -diff --git a/debian/control b/debian/control -index 492fbbe..22c29a7 100644 ---- a/debian/control -+++ b/debian/control -@@ -2,16 +2,16 @@ Source: python-qutepart - Maintainer: Andrei Kopats - Section: python - Priority: optional --Build-Depends: debhelper (>= 7.4.1), python2.7, libpcre3-dev, python2.7-dev, python-qt4, python-setuptools -+Build-Depends: debhelper (>= 7.4.1), python3, libpcre3-dev, python3-dev, python3-qt5, python3-setuptools - X-Python-Version: >= 2.7 - Standards-Version: 3.9.4 - Homepage: https://github.com/hlamer/qutepart - Vcs-Git: https://github.com/hlamer/qutepart - Vcs-Browser: https://github.com/hlamer/qutepart - --Package: python-qutepart -+Package: python3-qutepart - Architecture: any --Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4, libpcre3 -+Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python3-pyqt4, libpcre3 - Description: Code editor component - Some of the features: - * Syntax highlighting for 196 languages -diff --git a/doc/source/conf.py b/doc/source/conf.py -index 7f81195..1eff823 100644 ---- a/doc/source/conf.py -+++ b/doc/source/conf.py -@@ -75,8 +75,8 @@ def __getattr__(self, name): - master_doc = 'index' - - # General information about the project. --project = u'qutepart' --copyright = u'2013, Andrei Kopats' -+project = 'qutepart' -+copyright = '2013, Andrei Kopats' - - # The version info for the project you're documenting, acts as replacement for - # |version| and |release|, also used in various other places throughout the -@@ -219,8 +219,8 @@ def __getattr__(self, name): - # Grouping the document tree into LaTeX files. List of tuples - # (source start file, target name, title, author, documentclass [howto/manual]). - latex_documents = [ -- ('index', 'qutepart.tex', u'qutepart Documentation', -- u'Andrei Kopats', 'manual'), -+ ('index', 'qutepart.tex', 'qutepart Documentation', -+ 'Andrei Kopats', 'manual'), - ] - - # The name of an image file (relative to this directory) to place at the top of -@@ -251,8 +251,8 @@ def __getattr__(self, name): - # One entry per manual page. List of tuples - # (source start file, name, description, authors, manual section). - man_pages = [ -- ('index', 'qutepart', u'qutepart Documentation', -- [u'Andrei Kopats'], 1) -+ ('index', 'qutepart', 'qutepart Documentation', -+ ['Andrei Kopats'], 1) - ] - - # If true, show URL addresses after external links. -@@ -265,8 +265,8 @@ def __getattr__(self, name): - # (source start file, target name, title, author, - # dir menu entry, description, category) - texinfo_documents = [ -- ('index', 'qutepart', u'qutepart Documentation', -- u'Andrei Kopats', 'qutepart', 'One line description of project.', -+ ('index', 'qutepart', 'qutepart Documentation', -+ 'Andrei Kopats', 'qutepart', 'One line description of project.', - 'Miscellaneous'), - ] - -diff --git a/editor.py b/editor.py -index ba7c411..a4ba78e 100755 ---- a/editor.py -+++ b/editor.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - import os -@@ -38,7 +38,7 @@ def main(): - import qutepart # after correct sys.path has been set - - with open(ns.file) as file: -- text = unicode(file.read(), 'utf8') -+ text = file.read() - - if ns.debug: - logging.getLogger('qutepart').setLevel(logging.DEBUG) -diff --git a/profiling/typing_performance_test.py b/profiling/typing_performance_test.py -index 2812272..427ad52 100755 ---- a/profiling/typing_performance_test.py -+++ b/profiling/typing_performance_test.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - import time -@@ -17,7 +17,7 @@ - - q = qutepart.Qutepart() - q.detectSyntax(sourceFilePath=sys.argv[1]) --print 'Language:', q.language() -+print('Language:', q.language()) - - q.showMaximized() - -@@ -29,7 +29,7 @@ - def click(key): - clockBefore = time.clock() - -- if isinstance(key, basestring): -+ if isinstance(key, str): - QTest.keyClicks(q, key) - else: - QTest.keyClick(q, key) -@@ -56,11 +56,11 @@ def doTest(): - - clockAfter = time.clock() - typingTime = clockAfter - clockBefore -- print 'Typed {} chars in {} sec. {} ms per character'.format(len(text), typingTime, typingTime * 1000 / len(text)) -- print 'Time per click: count of clicks' -+ print('Typed {} chars in {} sec. {} ms per character'.format(len(text), typingTime, typingTime * 1000 / len(text))) -+ print('Time per click: count of clicks') - clickTimeKeys = sorted(clickTimes.keys()) - for ckt in clickTimeKeys: -- print ' %5dms: %4d' % (ckt, clickTimes[ckt]) -+ print(' %5dms: %4d' % (ckt, clickTimes[ckt])) - - app.quit() - -diff --git a/qutepart/__init__.py b/qutepart/__init__.py -index 298b3e5..9b1926b 100644 ---- a/qutepart/__init__.py -+++ b/qutepart/__init__.py -@@ -221,12 +221,12 @@ class Qutepart(QPlainTextEdit): - **Public methods** - ''' - -- userWarning = pyqtSignal(unicode) -- languageChanged = pyqtSignal(unicode) -+ userWarning = pyqtSignal(str) -+ languageChanged = pyqtSignal(str) - indentWidthChanged = pyqtSignal(int) - indentUseTabsChanged = pyqtSignal(bool) -- eolChanged = pyqtSignal(unicode) -- vimModeIndicationChanged = pyqtSignal(QColor, unicode) -+ eolChanged = pyqtSignal(str) -+ vimModeIndicationChanged = pyqtSignal(QColor, str) - vimModeEnabledChanged = pyqtSignal(bool) - - LINT_ERROR = 'e' -@@ -434,7 +434,7 @@ def lines(self): - @lines.setter - def lines(self, value): - if not isinstance(value, (list, tuple)) or \ -- not all([isinstance(item, basestring) for item in value]): -+ not all([isinstance(item, str) for item in value]): - raise TypeError('Invalid new value of "lines" attribute') - self.setPlainText('\n'.join(value)) - -@@ -467,7 +467,7 @@ def selectedText(self): - text = self.textCursor().selectedText() - - # replace unicode paragraph separator with habitual \n -- text = text.replace(u'\u2029', '\n') -+ text = text.replace('\u2029', '\n') - - return text - -diff --git a/qutepart/indenter/cstyle.py b/qutepart/indenter/cstyle.py -index f1f38fb..a470838 100644 ---- a/qutepart/indenter/cstyle.py -+++ b/qutepart/indenter/cstyle.py -@@ -20,7 +20,7 @@ - - def dbg(*args): - if (DEBUG_MODE): -- print args -+ print(args) - - #global variables and functions - -diff --git a/qutepart/lines.py b/qutepart/lines.py -index 537dd49..f1c1482 100644 ---- a/qutepart/lines.py -+++ b/qutepart/lines.py -@@ -137,7 +137,7 @@ def __init__(self, block): - def __iter__(self): - return self - -- def next(self): -+ def __next__(self): - if self._block.isValid(): - self._block, result = self._block.next(), self._block.text() - return result -diff --git a/qutepart/rectangularselection.py b/qutepart/rectangularselection.py -index 74d0004..730e717 100644 ---- a/qutepart/rectangularselection.py -+++ b/qutepart/rectangularselection.py -@@ -82,7 +82,7 @@ def _visibleCharPositionGenerator(self, text): - if char == '\t': - currentPos += self._qpart.indentWidth - # trim reminder. If width('\t') == 4, width('abc\t') == 4 -- currentPos = currentPos / self._qpart.indentWidth * self._qpart.indentWidth -+ currentPos = currentPos // self._qpart.indentWidth * self._qpart.indentWidth - else: - currentPos += 1 - yield currentPos -@@ -93,8 +93,9 @@ def _realToVisibleColumn(self, text, realColumn): - """ - generator = self._visibleCharPositionGenerator(text) - for i in range(realColumn): -- val = generator.next() -- return generator.next() -+ val = next(generator) -+ val = next(generator) -+ return val - - def _visibleToRealColumn(self, text, visiblePos): - """If \t is used, real position of symbol in block and visible position differs -@@ -203,10 +204,10 @@ def _indentUpTo(self, text, width): - return '' - elif self._qpart.indentUseTabs and \ - all([char == '\t' for char in text]): # if using tabs and only tabs in text -- return '\t' * (diff / self._qpart.indentWidth) + \ -+ return '\t' * (diff // self._qpart.indentWidth) + \ - ' ' * (diff % self._qpart.indentWidth) - else: -- return ' ' * diff -+ return ' ' * int(diff) - - def paste(self, mimeData): - """Paste recrangular selection. -@@ -217,7 +218,7 @@ def paste(self, mimeData): - elif self._qpart.textCursor().hasSelection(): - self._qpart.textCursor().deleteChar() - -- text = str(mimeData.data(self.MIME_TYPE)).decode('utf8') -+ text = bytes(mimeData.data(self.MIME_TYPE)).decode('utf8') - lines = text.splitlines() - cursorLine, cursorCol = self._qpart.cursorPosition - if cursorLine + len(lines) > len(self._qpart.lines): -diff --git a/qutepart/syntax/__init__.py b/qutepart/syntax/__init__.py -index 24b59fd..ca34c40 100644 ---- a/qutepart/syntax/__init__.py -+++ b/qutepart/syntax/__init__.py -@@ -82,7 +82,7 @@ def __str__(self): - res += ' license: %s\n' % self.license - res += ' hidden: %s\n' % self.hidden - res += ' indenter: %s\n' % self.indenter -- res += unicode(self.parser) -+ res += str(self.parser) - - return res - -diff --git a/qutepart/syntax/data/regenerate-definitions-db.py b/qutepart/syntax/data/regenerate-definitions-db.py -index c4cc525..1d649cf 100755 ---- a/qutepart/syntax/data/regenerate-definitions-db.py -+++ b/qutepart/syntax/data/regenerate-definitions-db.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os.path - import json -@@ -81,7 +81,7 @@ def main(): - with open('syntax_db.json', 'w') as syntaxDbFile: - json.dump(result, syntaxDbFile, sort_keys=True, indent=4) - -- print 'Done. Do not forget to commit the changes' -+ print('Done. Do not forget to commit the changes') - - if __name__ == '__main__': - main() -diff --git a/qutepart/syntax/loader.py b/qutepart/syntax/loader.py -index 5b2b489..63226f5 100644 ---- a/qutepart/syntax/loader.py -+++ b/qutepart/syntax/loader.py -@@ -93,7 +93,7 @@ def _parseBoolAttribute(value): - - def _safeGetRequiredAttribute(xmlElement, name, default): - if name in xmlElement.attrib: -- return unicode(xmlElement.attrib[name]) -+ return str(xmlElement.attrib[name]) - else: - _logger.warning("Required attribute '%s' is not set for element '%s'", name, xmlElement.tag) - return default -@@ -233,7 +233,7 @@ def _loadDetectChar(parentContext, xmlElement, attributeToFormatMap, formatConve - _logger.warning('Too little DetectChar index %d', index) - index = 0 - -- return _parserModule.DetectChar(abstractRuleParams, unicode(char), index) -+ return _parserModule.DetectChar(abstractRuleParams, str(char), index) - - def _loadDetect2Chars(parentContext, xmlElement, attributeToFormatMap, formatConverterFunction): - char = _safeGetRequiredAttribute(xmlElement, 'char', None) -@@ -286,11 +286,11 @@ def _processCraracterCodes(text): - i.e. \0377 is character with code 255 in the unicode table - Convert such notation to unicode text - """ -- text = unicode(text) -+ text = str(text) - def replFunc(matchObj): - matchText = matchObj.group(0) -- charCode = eval(matchText[1:]) -- return chr(charCode).decode('latin1') -+ charCode = eval('0o' + matchText[2:]) -+ return chr(charCode) - return re.sub(r"\\0\d\d\d", replFunc, text) - - insensitive = _parseBoolAttribute(xmlElement.attrib.get('insensitive', 'false')) -@@ -365,8 +365,8 @@ def _loadContexts(highlightingElement, parser, attributeToFormatMap, formatConve - contextList = [] - for xmlElement in xmlElementList: - name = _safeGetRequiredAttribute(xmlElement, -- u'name', -- u'Error: context name is not set!!!') -+ 'name', -+ 'Error: context name is not set!!!') - context = _parserModule.Context(parser, name) - contextList.append(context) - -@@ -448,7 +448,7 @@ def _makeFormat(defaultTheme, defaultStyleName, textType, item=None): - - if item is not None: - caseInsensitiveAttributes = {} -- for key, value in item.attrib.iteritems(): -+ for key, value in item.attrib.items(): - caseInsensitiveAttributes[key.lower()] = value.lower() - - if 'color' in caseInsensitiveAttributes: -@@ -503,7 +503,7 @@ def _loadLists(root, highlightingElement): - lists = {} # list name: list - for listElement in highlightingElement.findall('list'): - # Sometimes item.text is none. Broken xml files -- items = [unicode(item.text.strip()) \ -+ items = [str(item.text.strip()) \ - for item in listElement.findall('item') \ - if item.text is not None] - name = _safeGetRequiredAttribute(listElement, 'name', 'Error: list name is not set!!!') -@@ -520,9 +520,9 @@ def _makeKeywordsLowerCase(listDict): - def _loadSyntaxDescription(root, syntax): - syntax.name = _safeGetRequiredAttribute(root, 'name', 'Error: .parser name is not set!!!') - syntax.section = _safeGetRequiredAttribute(root, 'section', 'Error: Section is not set!!!') -- syntax.extensions = filter(None, _safeGetRequiredAttribute(root, 'extensions', '').split(';')) -- syntax.firstLineGlobs = filter(None, root.attrib.get('firstLineGlobs', '').split(';')) -- syntax.mimetype = filter(None, root.attrib.get('mimetype', '').split(';')) -+ syntax.extensions = [_f for _f in _safeGetRequiredAttribute(root, 'extensions', '').split(';') if _f] -+ syntax.firstLineGlobs = [_f for _f in root.attrib.get('firstLineGlobs', '').split(';') if _f] -+ syntax.mimetype = [_f for _f in root.attrib.get('mimetype', '').split(';') if _f] - syntax.version = root.attrib.get('version', None) - syntax.kateversion = root.attrib.get('kateversion', None) - syntax.priority = int(root.attrib.get('priority', '0')) -@@ -540,7 +540,7 @@ def loadSyntax(syntax, filePath, formatConverterFunction = None): - try: - root = xml.etree.ElementTree.parse(definitionFile).getroot() - except Exception as ex: -- print >> sys.stderr, 'When opening %s:' % filePath -+ print('When opening %s:' % filePath, file=sys.stderr) - raise - - highlightingElement = root.find('highlighting') -@@ -579,7 +579,7 @@ def loadSyntax(syntax, filePath, formatConverterFunction = None): - 'mode' in indentationElement.attrib: - syntax.indenter = indentationElement.attrib['mode'] - -- deliminatorSetAsString = u''.join(list(deliminatorSet)) -+ deliminatorSetAsString = ''.join(list(deliminatorSet)) - debugOutputEnabled = _logger.isEnabledFor(logging.DEBUG) # for cParser - parser = _parserModule.Parser(syntax, deliminatorSetAsString, lists, keywordsCaseSensitive, debugOutputEnabled) - syntax._setParser(parser) -diff --git a/qutepart/syntax/parser.py b/qutepart/syntax/parser.py -index e1ad239..b7de532 100644 ---- a/qutepart/syntax/parser.py -+++ b/qutepart/syntax/parser.py -@@ -819,7 +819,7 @@ def __str__(self): - res += '\t\t%s: %s\n' % ('dynamic', self.dynamic) - - for rule in self.rules: -- res += unicode(rule) -+ res += str(rule) - return res - - def parseBlock(self, contextStack, currentColumnIndex, text): -@@ -917,8 +917,8 @@ def __str__(self): - """Serialize. - For debug logs - """ -- res = u'Parser\n' -- for name, value in vars(self).iteritems(): -+ res = 'Parser\n' -+ for name, value in vars(self).items(): - if not name.startswith('_') and \ - not name in ('defaultContext', 'deliminatorSet', 'contexts', 'lists', 'syntax') and \ - not value is None: -@@ -926,12 +926,12 @@ def __str__(self): - - res += '\tDefault context: %s\n' % self.defaultContext.name - -- for listName, listValue in self.lists.iteritems(): -+ for listName, listValue in self.lists.items(): - res += '\tList %s: %s\n' % (listName, listValue) - - - for context in self.contexts.values(): -- res += unicode(context) -+ res += str(context) - - return res - -diff --git a/qutepart/vim.py b/qutepart/vim.py -index b7f9968..fa74e3f 100644 ---- a/qutepart/vim.py -+++ b/qutepart/vim.py -@@ -76,7 +76,7 @@ class Vim(QObject): - """Vim mode implementation. - Listens events and does actions - """ -- modeIndicationChanged = pyqtSignal(QColor, unicode) -+ modeIndicationChanged = pyqtSignal(QColor, str) - - internalClipboard = '' # delete commands save text to this clipboard - -@@ -266,7 +266,7 @@ def text(self): - - def _reset(self): - self._processCharCoroutine = self._processChar() -- self._processCharCoroutine.next() # run until the first yield -+ next(self._processCharCoroutine) # run until the first yield - self._typedText = '' - - _MOTIONS = (_0, _Home, -@@ -684,7 +684,7 @@ def cmdInternalPaste(self, cmd): - else: - cursor.removeSelectedText() - -- if isinstance(Vim.internalClipboard, basestring): -+ if isinstance(Vim.internalClipboard, str): - self._qpart.textCursor().insertText(Vim.internalClipboard) - elif isinstance(Vim.internalClipboard, list): - currentLineIndex = self._qpart.cursorPosition[0] -@@ -1020,7 +1020,7 @@ def cmdInternalPaste(self, cmd, count): - if not Vim.internalClipboard: - return - -- if isinstance(Vim.internalClipboard, basestring): -+ if isinstance(Vim.internalClipboard, str): - cursor = self._qpart.textCursor() - if cmd == _p: - cursor.movePosition(QTextCursor.Right) -diff --git a/rpm/python-qutepart.spec b/rpm/python-qutepart.spec -index 2bf52ec..3f97174 100644 ---- a/rpm/python-qutepart.spec -+++ b/rpm/python-qutepart.spec -@@ -1,4 +1,4 @@ --Name: python-qutepart -+Name: python3-qutepart - Version: 2.2.2 - Release: 1%{?dist} - Summary: Code editor widget for PyQt -@@ -10,18 +10,18 @@ URL: https://github.com/hlamer/qutepart - Source0: https://github.com/hlamer/qutepart/archive/v%{version}.tar.gz#/qutepart-%{version}.tar.gz - - BuildRequires: pcre-devel --BuildRequires: python-devel --BuildRequires: python-setuptools --Requires: python >= 2.7 -+BuildRequires: python3-devel -+BuildRequires: python3-setuptools -+Requires: python >= 3.3 - Requires: pcre - - - %if 0%{?fedora_version} --BuildRequires: PyQt4 --Requires: PyQt4 -+BuildRequires: python3-PyQt4 -+Requires: python3-PyQt4 - %else --BuildRequires: python-qt4 --Requires: python-qt4 -+BuildRequires: python3-qt4 -+Requires: python3-qt4 - %endif - - -diff --git a/setup.py b/setup.py -index fbd77dd..5b26ba1 100755 ---- a/setup.py -+++ b/setup.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - import os -@@ -63,19 +63,19 @@ def _checkDependencies(): - There should be better way to check, if C compiler is installed - """ - if not compiler.has_function('rand', includes = ['stdlib.h']): -- print "It seems like C compiler is not installed or not operable." -+ print("It seems like C compiler is not installed or not operable.") - return False - - if not compiler.has_function('rand', - includes = ['stdlib.h', 'Python.h'], - include_dirs=[distutils.sysconfig.get_python_inc()], - library_dirs=[os.path.join(os.path.dirname(sys.executable), 'libs')]): -- print "Failed to find Python headers." -- print "Try to install python-dev package" -- print "If not standard directories are used, pass parameters" -- print "\tpython setup.py install --lib-dir=c://github/pcre-8.32/build/Release --include-dir=c://github/pcre-8.32/build" -- print "\tpython setup.py install --lib-dir=/usr/local/lib --include-dir=/usr/local/include" -- print "--lib-dir= and --include-dir= may be used multiple times" -+ print("Failed to find Python headers.") -+ print("Try to install python-dev package") -+ print("If not standard directories are used, pass parameters") -+ print("\tpython setup.py install --lib-dir=c://github/pcre-8.32/build/Release --include-dir=c://github/pcre-8.32/build") -+ print("\tpython setup.py install --lib-dir=/usr/local/lib --include-dir=/usr/local/include") -+ print("--lib-dir= and --include-dir= may be used multiple times") - return False - - if not compiler.has_function('pcre_version', -@@ -83,13 +83,13 @@ def _checkDependencies(): - libraries = ['pcre'], - include_dirs=include_dirs, - library_dirs=library_dirs): -- print "Failed to find pcre library." -- print "Try to install libpcre{version}-dev package, or go to http://pcre.org" -- print "If not standard directories are used, pass parameters:" -- print "\tpython setup.py install --lib-dir=c://github/pcre-8.32/build/Release --include-dir=c://github/pcre-8.32/build" -- print "or" -- print "\tpython setup.py install --lib-dir=/my/local/lib --include-dir=/my/local/include" -- print "--lib-dir= and --include-dir= may be used multiple times" -+ print("Failed to find pcre library." -+ print("Try to install libpcre{version}-dev package, or go to http://pcre.org") -+ print("If not standard directories are used, pass parameters:") -+ print("\tpython setup.py install --lib-dir=c://github/pcre-8.32/build/Release --include-dir=c://github/pcre-8.32/build") -+ print("or") -+ print("\tpython setup.py install --lib-dir=/my/local/lib --include-dir=/my/local/include") -+ print("--lib-dir= and --include-dir= may be used multiple times") - return False - - return True -diff --git a/tests/run_all.py b/tests/run_all.py -index 3578404..5c9a4d2 100755 ---- a/tests/run_all.py -+++ b/tests/run_all.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - import base -diff --git a/tests/test_actions.py b/tests/test_actions.py -index e5b20e2..9b65857 100755 ---- a/tests/test_actions.py -+++ b/tests/test_actions.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os - import sys -diff --git a/tests/test_api.py b/tests/test_api.py -index 2eff704..09efda6 100755 ---- a/tests/test_api.py -+++ b/tests/test_api.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os - import sys -@@ -41,50 +41,50 @@ def test_setSelection(self): - - self.qpart.selectedPosition = ((0, 3), (0, 7)) - -- self.assertEquals(self.qpart.selectedText, "f fd") -- self.assertEquals(self.qpart.selectedPosition, ((0, 3), (0, 7))) -+ self.assertEqual(self.qpart.selectedText, "f fd") -+ self.assertEqual(self.qpart.selectedPosition, ((0, 3), (0, 7))) - - def test_selected_multiline_text(self): - self.qpart.text = "a\nb" - self.qpart.selectedPosition = ((0, 0), (1, 1)) -- self.assertEquals(self.qpart.selectedText, "a\nb") -+ self.assertEqual(self.qpart.selectedText, "a\nb") - - class ReplaceText(_BaseTest): - def test_replaceText1(self): - # Basic case - self.qpart.text = '123456789' - self.qpart.replaceText(3, 4, 'xyz') -- self.assertEquals(self.qpart.text, '123xyz89') -+ self.assertEqual(self.qpart.text, '123xyz89') - - def test_replaceText2(self): - # Replace uses (line, col) position - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText((1, 4), 3, 'Z') -- self.assertEquals(self.qpart.text, '12345\n6789Zbcde') -+ self.assertEqual(self.qpart.text, '12345\n6789Zbcde') - - def test_replaceText3(self): - # Edge cases - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText((0, 0), 3, 'Z') -- self.assertEquals(self.qpart.text, 'Z45\n67890\nabcde') -+ self.assertEqual(self.qpart.text, 'Z45\n67890\nabcde') - - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText((2, 4), 1, 'Z') -- self.assertEquals(self.qpart.text, '12345\n67890\nabcdZ') -+ self.assertEqual(self.qpart.text, '12345\n67890\nabcdZ') - - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText((0, 0), 0, 'Z') -- self.assertEquals(self.qpart.text, 'Z12345\n67890\nabcde') -+ self.assertEqual(self.qpart.text, 'Z12345\n67890\nabcde') - - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText((2, 5), 0, 'Z') -- self.assertEquals(self.qpart.text, '12345\n67890\nabcdeZ') -+ self.assertEqual(self.qpart.text, '12345\n67890\nabcdeZ') - - def test_replaceText4(self): - # Replace nothing with something - self.qpart.text = '12345\n67890\nabcde' - self.qpart.replaceText(2, 0, 'XYZ') -- self.assertEquals(self.qpart.text, '12XYZ345\n67890\nabcde') -+ self.assertEqual(self.qpart.text, '12XYZ345\n67890\nabcde') - - def test_replaceText5(self): - # Make sure exceptions are raised for invalid params -@@ -101,23 +101,23 @@ def test_1(self): - # Basic case - self.qpart.text = '123456789' - self.qpart.insertText(3, 'xyz') -- self.assertEquals(self.qpart.text, '123xyz456789') -+ self.assertEqual(self.qpart.text, '123xyz456789') - - def test_2(self): - # (line, col) position - self.qpart.text = '12345\n67890\nabcde' - self.qpart.insertText((1, 4), 'Z') -- self.assertEquals(self.qpart.text, '12345\n6789Z0\nabcde') -+ self.assertEqual(self.qpart.text, '12345\n6789Z0\nabcde') - - def test_3(self): - # Edge cases - self.qpart.text = '12345\n67890\nabcde' - self.qpart.insertText((0, 0), 'Z') -- self.assertEquals(self.qpart.text, 'Z12345\n67890\nabcde') -+ self.assertEqual(self.qpart.text, 'Z12345\n67890\nabcde') - - self.qpart.text = '12345\n67890\nabcde' - self.qpart.insertText((2, 5), 'Z') -- self.assertEquals(self.qpart.text, '12345\n67890\nabcdeZ') -+ self.assertEqual(self.qpart.text, '12345\n67890\nabcdeZ') - - - class IsCodeOrComment(_BaseTest): -@@ -129,10 +129,10 @@ def test_1(self): - self.qpart.text = 'a + b # comment' - self.qpart.detectSyntax(language = 'Python') - self._wait_highlighting_finished() -- self.assertEquals([self.qpart.isCode(0, i) for i in range(len(self.qpart.text))], -+ self.assertEqual([self.qpart.isCode(0, i) for i in range(len(self.qpart.text))], - [True, True, True, True, True, True, False, False, False, False, \ - False, False, False, False, False]) -- self.assertEquals([self.qpart.isComment(0, i) for i in range(len(self.qpart.text))], -+ self.assertEqual([self.qpart.isComment(0, i) for i in range(len(self.qpart.text))], - [False, False, False, False, False, False, True, True, True, True, \ - True, True, True, True, True]) - -@@ -168,19 +168,19 @@ def test_here_doc(self): - class DetectSyntax(_BaseTest): - def test_1(self): - self.qpart.detectSyntax(xmlFileName='ada.xml') -- self.assertEquals(self.qpart.language(), 'Ada') -+ self.assertEqual(self.qpart.language(), 'Ada') - - self.qpart.detectSyntax(mimeType='text/x-cgsrc') -- self.assertEquals(self.qpart.language(), 'Cg') -+ self.assertEqual(self.qpart.language(), 'Cg') - - self.qpart.detectSyntax(language='CSS') -- self.assertEquals(self.qpart.language(), 'CSS') -+ self.assertEqual(self.qpart.language(), 'CSS') - - self.qpart.detectSyntax(sourceFilePath='/tmp/file.feh') -- self.assertEquals(self.qpart.language(), 'ferite') -+ self.assertEqual(self.qpart.language(), 'ferite') - - self.qpart.detectSyntax(firstLine='') -- self.assertEquals(self.qpart.language(), 'PHP (HTML)') -+ self.assertEqual(self.qpart.language(), 'PHP (HTML)') - - - class Signals(_BaseTest): -@@ -191,7 +191,7 @@ def setNeVal(val): - self.qpart.languageChanged.connect(setNeVal) - - self.qpart.detectSyntax(language='Python') -- self.assertEquals(newValue[0], 'Python') -+ self.assertEqual(newValue[0], 'Python') - - def test_indent_width_changed(self): - newValue = [None] -@@ -200,7 +200,7 @@ def setNeVal(val): - self.qpart.indentWidthChanged.connect(setNeVal) - - self.qpart.indentWidth = 7 -- self.assertEquals(newValue[0], 7) -+ self.assertEqual(newValue[0], 7) - - def test_use_tabs_changed(self): - newValue = [None] -@@ -210,7 +210,7 @@ def setNeVal(val): - self.qpart.indentUseTabsChanged.connect(setNeVal) - - self.qpart.indentUseTabs = True -- self.assertEquals(newValue[0], True) -+ self.assertEqual(newValue[0], True) - - def test_eol_changed(self): - newValue = [None] -@@ -220,7 +220,7 @@ def setNeVal(val): - self.qpart.eolChanged.connect(setNeVal) - - self.qpart.eol = '\r\n' -- self.assertEquals(newValue[0], '\r\n') -+ self.assertEqual(newValue[0], '\r\n') - - - class Completion(_BaseTest): -@@ -268,27 +268,27 @@ def setUp(self): - self.qpart.text = 'abcd\nefgh\nklmn\nopqr' - - def test_accessByIndex(self): -- self.assertEquals(self.qpart.lines[0], 'abcd') -- self.assertEquals(self.qpart.lines[1], 'efgh') -- self.assertEquals(self.qpart.lines[-1], 'opqr') -+ self.assertEqual(self.qpart.lines[0], 'abcd') -+ self.assertEqual(self.qpart.lines[1], 'efgh') -+ self.assertEqual(self.qpart.lines[-1], 'opqr') - - def test_modifyByIndex(self): - self.qpart.lines[2] = 'new text' -- self.assertEquals(self.qpart.text, 'abcd\nefgh\nnew text\nopqr') -+ self.assertEqual(self.qpart.text, 'abcd\nefgh\nnew text\nopqr') - - def test_getSlice(self): -- self.assertEquals(self.qpart.lines[0], 'abcd') -- self.assertEquals(self.qpart.lines[1], 'efgh') -- self.assertEquals(self.qpart.lines[3], 'opqr') -- self.assertEquals(self.qpart.lines[-4], 'abcd') -- self.assertEquals(self.qpart.lines[1:4], ['efgh', 'klmn', 'opqr']) -- self.assertEquals(self.qpart.lines[1:7], ['efgh', 'klmn', 'opqr']) # Python list behaves this way -- self.assertEquals(self.qpart.lines[0:0], []) -- self.assertEquals(self.qpart.lines[0:1], ['abcd']) -- self.assertEquals(self.qpart.lines[:2], ['abcd', 'efgh']) -- self.assertEquals(self.qpart.lines[0:-2], ['abcd', 'efgh']) -- self.assertEquals(self.qpart.lines[-2:], ['klmn', 'opqr']) -- self.assertEquals(self.qpart.lines[-4:-2], ['abcd', 'efgh']) -+ self.assertEqual(self.qpart.lines[0], 'abcd') -+ self.assertEqual(self.qpart.lines[1], 'efgh') -+ self.assertEqual(self.qpart.lines[3], 'opqr') -+ self.assertEqual(self.qpart.lines[-4], 'abcd') -+ self.assertEqual(self.qpart.lines[1:4], ['efgh', 'klmn', 'opqr']) -+ self.assertEqual(self.qpart.lines[1:7], ['efgh', 'klmn', 'opqr']) # Python list behaves this way -+ self.assertEqual(self.qpart.lines[0:0], []) -+ self.assertEqual(self.qpart.lines[0:1], ['abcd']) -+ self.assertEqual(self.qpart.lines[:2], ['abcd', 'efgh']) -+ self.assertEqual(self.qpart.lines[0:-2], ['abcd', 'efgh']) -+ self.assertEqual(self.qpart.lines[-2:], ['klmn', 'opqr']) -+ self.assertEqual(self.qpart.lines[-4:-2], ['abcd', 'efgh']) - - with self.assertRaises(IndexError): - self.qpart.lines[4] -@@ -297,27 +297,27 @@ def test_getSlice(self): - - def test_setSlice_1(self): - self.qpart.lines[0] = 'xyz' -- self.assertEquals(self.qpart.text, 'xyz\nefgh\nklmn\nopqr') -+ self.assertEqual(self.qpart.text, 'xyz\nefgh\nklmn\nopqr') - - def test_setSlice_2(self): - self.qpart.lines[1] = 'xyz' -- self.assertEquals(self.qpart.text, 'abcd\nxyz\nklmn\nopqr') -+ self.assertEqual(self.qpart.text, 'abcd\nxyz\nklmn\nopqr') - - def test_setSlice_3(self): - self.qpart.lines[-4] = 'xyz' -- self.assertEquals(self.qpart.text, 'xyz\nefgh\nklmn\nopqr') -+ self.assertEqual(self.qpart.text, 'xyz\nefgh\nklmn\nopqr') - - def test_setSlice_4(self): - self.qpart.lines[0:4] = ['st', 'uv', 'wx', 'z'] -- self.assertEquals(self.qpart.text, 'st\nuv\nwx\nz') -+ self.assertEqual(self.qpart.text, 'st\nuv\nwx\nz') - - def test_setSlice_5(self): - self.qpart.lines[0:47] = ['st', 'uv', 'wx', 'z'] -- self.assertEquals(self.qpart.text, 'st\nuv\nwx\nz') -+ self.assertEqual(self.qpart.text, 'st\nuv\nwx\nz') - - def test_setSlice_6(self): - self.qpart.lines[1:3] = ['st', 'uv'] -- self.assertEquals(self.qpart.text, 'abcd\nst\nuv\nopqr') -+ self.assertEqual(self.qpart.text, 'abcd\nst\nuv\nopqr') - - def test_setSlice_61(self): - with self.assertRaises(ValueError): -@@ -325,11 +325,11 @@ def test_setSlice_61(self): - - def test_setSlice_7(self): - self.qpart.lines[-3:3] = ['st', 'uv'] -- self.assertEquals(self.qpart.text, 'abcd\nst\nuv\nopqr') -+ self.assertEqual(self.qpart.text, 'abcd\nst\nuv\nopqr') - - def test_setSlice_8(self): - self.qpart.lines[-3:-1] = ['st', 'uv'] -- self.assertEquals(self.qpart.text, 'abcd\nst\nuv\nopqr') -+ self.assertEqual(self.qpart.text, 'abcd\nst\nuv\nopqr') - - def test_setSlice_9(self): - with self.assertRaises(IndexError): -diff --git a/tests/test_bookmarks.py b/tests/test_bookmarks.py -index 2bdc034..795f4fe 100755 ---- a/tests/test_bookmarks.py -+++ b/tests/test_bookmarks.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os - import sys -diff --git a/tests/test_bracket_hlighter.py b/tests/test_bracket_hlighter.py -index 3c19748..8dead38 100755 ---- a/tests/test_bracket_hlighter.py -+++ b/tests/test_bracket_hlighter.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os - import sys -diff --git a/tests/test_completion.py b/tests/test_completion.py -index 848e55c..d8ea3ad 100755 ---- a/tests/test_completion.py -+++ b/tests/test_completion.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import os - import sys -diff --git a/tests/test_draw_whitespace.py b/tests/test_draw_whitespace.py -index e3cbbed..fa484e9 100755 ---- a/tests/test_draw_whitespace.py -+++ b/tests/test_draw_whitespace.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - # encoding: utf8 - - -@@ -48,11 +48,11 @@ def _ws_test(self, - try: - self._verify(text, expectedResult) - except: -- print "Failed params:\n\tany {}\n\tincorrect {}\n\ttabs {}\n\twidth {}".format( -+ print("Failed params:\n\tany {}\n\tincorrect {}\n\ttabs {}\n\twidth {}".format( - self.qpart.drawAnyWhitespace, - self.qpart.drawIncorrectIndentation, - self.qpart.indentUseTabs, -- self.qpart.indentWidth) -+ self.qpart.indentWidth)) - raise - - def _verify(self, text, expectedResult): -diff --git a/tests/test_edit.py b/tests/test_edit.py -index 7dda435..0f91f9c 100755 ---- a/tests/test_edit.py -+++ b/tests/test_edit.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - import unittest -diff --git a/tests/test_indent.py b/tests/test_indent.py -index bc9483d..2ce5d57 100755 ---- a/tests/test_indent.py -+++ b/tests/test_indent.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - import unittest -diff --git a/tests/test_indenter/indenttest.py b/tests/test_indenter/indenttest.py -index e4f9a77..58e7a53 100644 ---- a/tests/test_indenter/indenttest.py -+++ b/tests/test_indenter/indenttest.py -@@ -25,7 +25,7 @@ def setOrigin(self, text): - - def verifyExpected(self, text): - lines = self.qpart.text.split('\n') -- self.assertEquals(text, map(str, lines)) -+ self.assertEquals(text, [l for l in lines]) - - def setCursorPosition(self, line, col): - self.qpart.cursorPosition = line, col -diff --git a/tests/test_indenter/test_cstyle.py b/tests/test_indenter/test_cstyle.py -index 91cf219..3901ce9 100755 ---- a/tests/test_indenter/test_cstyle.py -+++ b/tests/test_indenter/test_cstyle.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - class BaseTestClass(IndentTest): -diff --git a/tests/test_indenter/test_haskell.py b/tests/test_indenter/test_haskell.py -index a4ad710..b98ef37 100755 ---- a/tests/test_indenter/test_haskell.py -+++ b/tests/test_indenter/test_haskell.py -@@ -1,7 +1,11 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) -+ - from indenttest import IndentTest - - -diff --git a/tests/test_indenter/test_lisp.py b/tests/test_indenter/test_lisp.py -index 14598ba..84cde3a 100755 ---- a/tests/test_indenter/test_lisp.py -+++ b/tests/test_indenter/test_lisp.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - -diff --git a/tests/test_indenter/test_normal.py b/tests/test_indenter/test_normal.py -index 49e464a..5e1cd92 100755 ---- a/tests/test_indenter/test_normal.py -+++ b/tests/test_indenter/test_normal.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - -diff --git a/tests/test_indenter/test_python.py b/tests/test_indenter/test_python.py -index 48f83f9..40714b8 100755 ---- a/tests/test_indenter/test_python.py -+++ b/tests/test_indenter/test_python.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - -diff --git a/tests/test_indenter/test_ruby.py b/tests/test_indenter/test_ruby.py -index 34e1ec5..f810d90 100755 ---- a/tests/test_indenter/test_ruby.py -+++ b/tests/test_indenter/test_ruby.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - class BaseTestClass(IndentTest): -diff --git a/tests/test_indenter/test_scheme.py b/tests/test_indenter/test_scheme.py -index 435eb3d..13324a2 100755 ---- a/tests/test_indenter/test_scheme.py -+++ b/tests/test_indenter/test_scheme.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - class BaseTestClass(IndentTest): -diff --git a/tests/test_indenter/test_xmlindent.py b/tests/test_indenter/test_xmlindent.py -index dd66255..4fc6707 100755 ---- a/tests/test_indenter/test_xmlindent.py -+++ b/tests/test_indenter/test_xmlindent.py -@@ -1,7 +1,10 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -+import os.path -+import sys -+sys.path.append(os.path.abspath(os.path.join(__file__, '..'))) - from indenttest import IndentTest - - class BaseTestClass(IndentTest): -diff --git a/tests/test_rectangular_selection.py b/tests/test_rectangular_selection.py -index 5083e84..c814ec0 100755 ---- a/tests/test_rectangular_selection.py -+++ b/tests/test_rectangular_selection.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - # encoding: utf8 - - -@@ -145,7 +145,7 @@ def test_copy_paste(self): - - def test_copy_paste_utf8(self): - self.qpart.show() -- self.qpart.text = u'фыва' -+ self.qpart.text = 'фыва' - for i in range(3): - QTest.keyClick(self.qpart, Qt.Key_Right, Qt.AltModifier | Qt.ShiftModifier) - QTest.keyClick(self.qpart, Qt.Key_C, Qt.ControlModifier) -@@ -155,7 +155,7 @@ def test_copy_paste_utf8(self): - QTest.keyClick(self.qpart, Qt.Key_V, Qt.ControlModifier) - - self.assertEqual(self.qpart.text, -- u'фыва фыв') -+ 'фыва фыв') - - def test_paste_replace_selection(self): - self.qpart.show() -diff --git a/tests/test_syntax/test_dynamic_substitution.py b/tests/test_syntax/test_dynamic_substitution.py -index 39b445a..45045cd 100755 ---- a/tests/test_syntax/test_dynamic_substitution.py -+++ b/tests/test_syntax/test_dynamic_substitution.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - import sys -diff --git a/tests/test_syntax/test_rules.py b/tests/test_syntax/test_rules.py -index 75f2958..859afff 100755 ---- a/tests/test_syntax/test_rules.py -+++ b/tests/test_syntax/test_rules.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import unittest - -@@ -24,7 +24,7 @@ def tryMatch(rule, column, text): - return tryMatchWithData(rule, None, column, text) - - def tryMatchWithData(rule, contextData, column, text): -- textToMatchObject = parser.TextToMatchObject(column, unicode(text), _currentSyntax.parser.deliminatorSet, contextData) -+ textToMatchObject = parser.TextToMatchObject(column, str(text), _currentSyntax.parser.deliminatorSet, contextData) - ruleTryMatchResult = rule.tryMatch(textToMatchObject) - if ruleTryMatchResult is not None: - return ruleTryMatchResult.length -@@ -50,17 +50,17 @@ def test_DetectChar_dynamic(self): - rule = self._getRule("perl.xml", "ip_string_6", 1) - text = "a" - -- self.assertEqual(tryMatchWithData(rule, (u'a', u'b', u'c'), 0, text), 1) -- self.assertEqual(tryMatchWithData(rule, (u'x', u'y', u'z'), 0, text), None) -+ self.assertEqual(tryMatchWithData(rule, ('a', 'b', 'c'), 0, text), 1) -+ self.assertEqual(tryMatchWithData(rule, ('x', 'y', 'z'), 0, text), None) - - def test_DetectChar_dynamic2(self): - rule = self._getRule("perl.xml", "string_6", 3) - text = "abcdXefg" - -- count = tryMatchWithData(rule, (u'X', u'Y', u'Z',), 0, text) -+ count = tryMatchWithData(rule, ('X', 'Y', 'Z',), 0, text) - self.assertEqual(count, None) - -- count = tryMatchWithData(rule, (u'X', u'Y', u'Z',), 4, text) -+ count = tryMatchWithData(rule, ('X', 'Y', 'Z',), 4, text) - self.assertEqual(count, 1) - - def test_Detect2Chars(self): -@@ -156,7 +156,7 @@ def test_RegExpr(self): - - rule = self._getRule('fsharp.xml', 'ModuleEnv2', 0) - if hasattr(rule, 'regExp'): # only on Python version -- self.assertEqual(rule.regExp.pattern, u"[A-Z][A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\xff0-9_']*") -+ self.assertEqual(rule.regExp.pattern, "[A-Z][A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\xff0-9_']*") - - def test_RegExpr_slashB(self): - rule = self._getRule('fortran.xml', 'find_numbers', 3) -@@ -291,7 +291,7 @@ def test_dynamic_reg_exp(self): - """ - rule = self._getRule("ruby.xml", "gdl_dq_string_5", 2) # "\s*%1" - text = '%|a| x' -- count = tryMatchWithData(rule, (u'blabla|', u'|', ), 3, text) -+ count = tryMatchWithData(rule, ('blabla|', '|', ), 3, text) - self.assertEqual(count, 1) - - def test_dynamic_string_detect(self): -@@ -300,7 +300,7 @@ def test_dynamic_string_detect(self): - rule = self._getRule("php.xml", "phpsource", 34) # heredoc - text = "<<': - QTest.keyClick(self.qpart, key, Qt.ShiftModifier) -diff --git a/tools/show-syntax.py b/tools/show-syntax.py -index 500d548..0008df8 100755 ---- a/tools/show-syntax.py -+++ b/tools/show-syntax.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - - import sys - sys.path.insert(0, '.') -@@ -11,7 +11,7 @@ - - if __name__ == '__main__': - if len(sys.argv) != 2: -- print 'Usage:\n\t%s SYNTAX_FILE_NAME' % sys.argv[0] -+ print('Usage:\n\t%s SYNTAX_FILE_NAME' % sys.argv[0]) - else: - syntax = SyntaxManager().getSyntax(xmlFileName = sys.argv[1]) -- print unicode(syntax) -+ print(str(syntax)) - -From 148bcd1d9743941ad40acab80e40adeaeba8734c Mon Sep 17 00:00:00 2001 -From: Andrei Kopats -Date: Thu, 13 Aug 2015 12:43:36 +0300 -Subject: [PATCH 2/4] qt5 - ---- - README.md | 2 +- - doc/source/conf.py | 4 ++-- - editor.py | 5 +++-- - profiling/typing_performance_test.py | 6 +++--- - qutepart/__init__.py | 15 ++++++++++----- - qutepart/bookmarks.py | 5 +++-- - qutepart/brackethlighter.py | 5 +++-- - qutepart/completer.py | 5 +++-- - qutepart/htmldelegate.py | 13 +++++++------ - qutepart/indenter/__init__.py | 2 +- - qutepart/lines.py | 2 +- - qutepart/rectangularselection.py | 5 +++-- - qutepart/sideareas.py | 7 ++++--- - qutepart/syntaxhlighter.py | 6 +++--- - qutepart/vim.py | 5 +++-- - rpm/python-qutepart.spec | 4 ++-- - tests/base.py | 22 +++++++++++----------- - tests/test_actions.py | 4 ++-- - tests/test_api.py | 10 ++++------ - tests/test_bookmarks.py | 4 ++-- - tests/test_bracket_hlighter.py | 4 ++-- - tests/test_completion.py | 32 ++++++++++++++++++-------------- - tests/test_draw_whitespace.py | 4 ++-- - tests/test_edit.py | 4 ++-- - tests/test_indent.py | 4 ++-- - tests/test_indenter/indenttest.py | 4 ++-- - tests/test_rectangular_selection.py | 4 ++-- - tests/test_vim.py | 4 ++-- - 28 files changed, 103 insertions(+), 88 deletions(-) - -diff --git a/README.md b/README.md -index 27e1256..2487d7c 100644 ---- a/README.md -+++ b/README.md -@@ -21,7 +21,7 @@ Component has been created for [Enki editor](http://enki-editor.org) as replacem - Qutepart depends on: - - * Python 3 --* PyQt4 (see *Known problems* section) -+* PyQt5 (see *Known problems* section) - * pcre - - #### 1. Install [pcre](http://www.pcre.org/) and development files -diff --git a/doc/source/conf.py b/doc/source/conf.py -index 1eff823..e1ed48b 100644 ---- a/doc/source/conf.py -+++ b/doc/source/conf.py -@@ -16,7 +16,7 @@ - - - """ --Fake PyQt4 module, for building docs on system without PyQt (rtfd.org) -+Fake PyQt5 module, for building docs on system without PyQt (rtfd.org) - - http://read-the-docs.readthedocs.org/en/latest/faq.html#my-project-isn-t-building-with-autodoc - """ -@@ -38,7 +38,7 @@ def __getattr__(self, name): - else: - return Mock() - --MOCK_MODULES = ['PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4.QtWebKit'] -+MOCK_MODULES = ['PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWebKit'] - for mod_name in MOCK_MODULES: - sys.modules[mod_name] = Mock() - -diff --git a/editor.py b/editor.py -index a4ba78e..069d084 100755 ---- a/editor.py -+++ b/editor.py -@@ -8,7 +8,8 @@ - import sip - sip.setapi('QString', 2) - --from PyQt4.QtGui import QApplication, QLabel, QMainWindow, QPalette, QVBoxLayout, QWidget -+from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QWidget -+from PyQt5.QtGui import QPalette - - - def _parseCommandLine(): -@@ -123,7 +124,7 @@ def onVimModeChanged(color, text): - window.resize(800, 600) - window.show() - -- from PyQt4.QtCore import QTimer -+ from PyQt5.QtCore import QTimer - if ns.quit: - QTimer.singleShot(0, app.quit) - -diff --git a/profiling/typing_performance_test.py b/profiling/typing_performance_test.py -index 427ad52..0d1a918 100755 ---- a/profiling/typing_performance_test.py -+++ b/profiling/typing_performance_test.py -@@ -6,9 +6,9 @@ - import sip - sip.setapi('QString', 2) - --from PyQt4.QtCore import QTimer, Qt --from PyQt4.QtGui import QApplication, QPlainTextEdit --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import QTimer, Qt -+from PyQt5.QtGui import QApplication, QPlainTextEdit -+from PyQt5.QtTest import QTest - - import qutepart - -diff --git a/qutepart/__init__.py b/qutepart/__init__.py -index 9b1926b..1c1aa3c 100644 ---- a/qutepart/__init__.py -+++ b/qutepart/__init__.py -@@ -15,13 +15,18 @@ - 'Use next code:\n\timport sip\n\tsip.setapi("QString", 2)\n'\ - 'before importing Qutepart' - --from PyQt4.QtCore import QRect, Qt, QEvent, pyqtSignal --from PyQt4.QtGui import QAction, QApplication, QColor, QBrush, \ -- QDialog, QFont, \ -+from PyQt5.QtCore import QRect, Qt, QEvent, pyqtSignal -+from PyQt5.QtGui import QColor, QBrush, QFont, \ - QIcon, QKeySequence, QPainter, QPen, QPalette, \ -+ QTextCharFormat, QTextCursor, \ -+ QTextBlock, QTextFormat -+ -+from PyQt5.QtWidgets import QAction, QApplication, QDialog, \ - QPlainTextEdit, \ -- QPrintDialog, QTextCharFormat, QTextCursor, \ -- QTextBlock, QTextEdit, QTextFormat -+ QShortcut, \ -+ QTextEdit -+ -+from PyQt5.QtPrintSupport import QPrintDialog - - from qutepart.syntax import SyntaxManager - from qutepart.syntaxhlighter import SyntaxHighlighter -diff --git a/qutepart/bookmarks.py b/qutepart/bookmarks.py -index 27df11b..77489b1 100644 ---- a/qutepart/bookmarks.py -+++ b/qutepart/bookmarks.py -@@ -1,7 +1,8 @@ - """Bookmarks functionality implementation""" - --from PyQt4.QtCore import Qt --from PyQt4.QtGui import QAction, QIcon, QKeySequence, QTextCursor -+from PyQt5.QtCore import Qt -+from PyQt5.QtGui import QIcon, QKeySequence, QTextCursor -+from PyQt5.QtWidgets import QAction - - import qutepart - -diff --git a/qutepart/brackethlighter.py b/qutepart/brackethlighter.py -index a308c82..f324d60 100644 ---- a/qutepart/brackethlighter.py -+++ b/qutepart/brackethlighter.py -@@ -4,8 +4,9 @@ - - import time - --from PyQt4.QtCore import Qt --from PyQt4.QtGui import QTextCursor, QTextEdit -+from PyQt5.QtCore import Qt -+from PyQt5.QtGui import QTextCursor -+from PyQt5.QtWidgets import QTextEdit - - - class _TimeoutException(UserWarning): -diff --git a/qutepart/completer.py b/qutepart/completer.py -index 51acd38..4c9c8a6 100644 ---- a/qutepart/completer.py -+++ b/qutepart/completer.py -@@ -4,8 +4,9 @@ - import re - import time - --from PyQt4.QtCore import pyqtSignal, QAbstractItemModel, QEvent, QModelIndex, QObject, QSize, Qt, QTimer, Qt --from PyQt4.QtGui import QCursor, QListView, QStyle -+from PyQt5.QtCore import pyqtSignal, QAbstractItemModel, QEvent, QModelIndex, QObject, QSize, Qt, QTimer, Qt -+from PyQt5.QtGui import QCursor -+from PyQt5.QtWidgets import QListView, QStyle - - from qutepart.htmldelegate import HTMLDelegate - -diff --git a/qutepart/htmldelegate.py b/qutepart/htmldelegate.py -index c366ace..ffc61e8 100644 ---- a/qutepart/htmldelegate.py -+++ b/qutepart/htmldelegate.py -@@ -3,10 +3,11 @@ - ========================================================= - """ - --from PyQt4.QtGui import QApplication, QAbstractTextDocumentLayout, \ -- QStyledItemDelegate, QStyle, QStyleOptionViewItemV4, \ -- QTextDocument, QPalette --from PyQt4.QtCore import QSize -+from PyQt5.QtGui import QTextDocument, QPalette, QAbstractTextDocumentLayout -+from PyQt5.QtWidgets import QApplication, \ -+ QStyledItemDelegate, QStyle, QStyleOptionViewItem -+ -+from PyQt5.QtCore import QSize - - _HTML_ESCAPE_TABLE = \ - { -@@ -37,7 +38,7 @@ def paint(self, painter, option, index): - """ - option.state &= ~QStyle.State_HasFocus # never draw focus rect - -- options = QStyleOptionViewItemV4(option) -+ options = QStyleOptionViewItem(option) - self.initStyleOption(options,index) - - style = QApplication.style() if options.widget is None else options.widget.style() -@@ -72,7 +73,7 @@ def paint(self, painter, option, index): - def sizeHint(self, option, index): - """QStyledItemDelegate.sizeHint implementation - """ -- options = QStyleOptionViewItemV4(option) -+ options = QStyleOptionViewItem(option) - self.initStyleOption(options,index) - - doc = QTextDocument() -diff --git a/qutepart/indenter/__init__.py b/qutepart/indenter/__init__.py -index f63e6c0..44bbc92 100644 ---- a/qutepart/indenter/__init__.py -+++ b/qutepart/indenter/__init__.py -@@ -7,7 +7,7 @@ - logger = logging.getLogger('qutepart') - - --from PyQt4.QtGui import QTextCursor -+from PyQt5.QtGui import QTextCursor - - - def _getSmartIndenter(indenterName, qpart, indenter): -diff --git a/qutepart/lines.py b/qutepart/lines.py -index f1c1482..c1b5086 100644 ---- a/qutepart/lines.py -+++ b/qutepart/lines.py -@@ -2,7 +2,7 @@ - list-like object for access text document lines - """ - --from PyQt4.QtGui import QTextCursor -+from PyQt5.QtGui import QTextCursor - - - def _iterateBlocksFrom(block): -diff --git a/qutepart/rectangularselection.py b/qutepart/rectangularselection.py -index 730e717..f3f7732 100644 ---- a/qutepart/rectangularselection.py -+++ b/qutepart/rectangularselection.py -@@ -1,5 +1,6 @@ --from PyQt4.QtCore import Qt, QMimeData --from PyQt4.QtGui import QApplication, QKeyEvent, QKeySequence, QPalette, QTextCursor, QTextEdit, QWidget -+from PyQt5.QtCore import Qt, QMimeData -+from PyQt5.QtGui import QKeyEvent, QKeySequence, QPalette, QTextCursor -+from PyQt5.QtWidgets import QApplication, QTextEdit, QWidget - - - class RectangularSelection: -diff --git a/qutepart/sideareas.py b/qutepart/sideareas.py -index 08736d0..eac36c7 100644 ---- a/qutepart/sideareas.py -+++ b/qutepart/sideareas.py -@@ -1,10 +1,11 @@ - """Line numbers and bookmarks areas - """ - --from PyQt4.QtCore import QPoint, Qt, pyqtSignal --from PyQt4.QtGui import QPainter, QPalette, \ -+from PyQt5.QtCore import QEvent, QPoint, Qt, pyqtSignal -+from PyQt5.QtGui import QPainter, QPalette, \ - QPixmap, \ -- QTextBlock, QToolTip, QWidget -+ QTextBlock -+from PyQt5.QtWidgets import QToolTip, QWidget - - import qutepart - from qutepart.bookmarks import Bookmarks -diff --git a/qutepart/syntaxhlighter.py b/qutepart/syntaxhlighter.py -index 7d2f065..dee9849 100644 ---- a/qutepart/syntaxhlighter.py -+++ b/qutepart/syntaxhlighter.py -@@ -4,10 +4,10 @@ - - import time - -- --from PyQt4.QtCore import QObject, QTimer --from PyQt4.QtGui import QApplication, QBrush, QColor, QFont, \ -+from PyQt5.QtCore import Qt, QObject, QTimer -+from PyQt5.QtGui import QBrush, QColor, QFont, \ - QTextBlockUserData, QTextCharFormat, QTextLayout -+from PyQt5.QtWidgets import QApplication - - import qutepart.syntax - -diff --git a/qutepart/vim.py b/qutepart/vim.py -index fa74e3f..fd6f441 100644 ---- a/qutepart/vim.py -+++ b/qutepart/vim.py -@@ -1,7 +1,8 @@ - import sys - --from PyQt4.QtCore import Qt, pyqtSignal, QObject --from PyQt4.QtGui import QColor, QTextCursor, QTextEdit -+from PyQt5.QtCore import Qt, pyqtSignal, QObject -+from PyQt5.QtGui import QColor, QTextCursor -+from PyQt5.QtWidgets import QTextEdit - - - """ This magic code sets variables like _a and _A in the global scope -diff --git a/rpm/python-qutepart.spec b/rpm/python-qutepart.spec -index 3f97174..2b55336 100644 ---- a/rpm/python-qutepart.spec -+++ b/rpm/python-qutepart.spec -@@ -17,8 +17,8 @@ Requires: pcre - - - %if 0%{?fedora_version} --BuildRequires: python3-PyQt4 --Requires: python3-PyQt4 -+BuildRequires: python3-PyQt5 -+Requires: python3-PyQt5 - %else - BuildRequires: python3-qt4 - Requires: python3-qt4 -diff --git a/tests/base.py b/tests/base.py -index b8f0350..6e89725 100644 ---- a/tests/base.py -+++ b/tests/base.py -@@ -7,9 +7,9 @@ - import sip - sip.setapi('QString', 2) - --from PyQt4.QtCore import Qt, QTimer --from PyQt4.QtGui import QApplication --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt, QTimer -+from PyQt5.QtWidgets import QApplication -+from PyQt5.QtTest import QTest - - - sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) -@@ -18,13 +18,13 @@ - # Create a single, persistent QApplication for use in all tests. - papp = QApplication(sys.argv) - --def _processPendingEvents(app): -+def _processPendingEvents(): - """Process pending application events. - Timeout is used, because on Windows hasPendingEvents() always returns True - """ - t = time.time() -- while app.hasPendingEvents() and (time.time() - t < 0.1): -- app.processEvents() -+ while QApplication.instance().hasPendingEvents() and (time.time() - t < 0.1): -+ QApplication.instance().processEvents() - - - def in_main_loop(func, *args): -@@ -37,18 +37,18 @@ def wrapper(*args): - - def execWithArgs(): - self.qpart.show() -- QTest.qWaitForWindowShown(self.qpart) -- _processPendingEvents(self.app) -+ QTest.qWaitForWindowExposed(self.qpart) -+ _processPendingEvents() - - try: - func(*args) - finally: -- _processPendingEvents(self.app) -- self.app.quit() -+ _processPendingEvents() -+ QApplication.instance().quit() - - QTimer.singleShot(0, execWithArgs) - -- self.app.exec_() -+ QApplication.instance().exec_() - - wrapper.__name__ = func.__name__ # for unittest test runner - return wrapper -diff --git a/tests/test_actions.py b/tests/test_actions.py -index 9b65857..f355848 100755 ---- a/tests/test_actions.py -+++ b/tests/test_actions.py -@@ -6,8 +6,8 @@ - - import base - --from PyQt4.QtTest import QTest --from PyQt4.QtCore import Qt, QTimer -+from PyQt5.QtTest import QTest -+from PyQt5.QtCore import Qt, QTimer - - from qutepart import Qutepart - -diff --git a/tests/test_api.py b/tests/test_api.py -index 09efda6..9831e16 100755 ---- a/tests/test_api.py -+++ b/tests/test_api.py -@@ -6,8 +6,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - -@@ -17,8 +17,6 @@ - class _BaseTest(unittest.TestCase): - """Base class for tests - """ -- app = base.papp # app crashes, if created more than once -- - def setUp(self): - self.qpart = Qutepart() - -@@ -122,7 +120,7 @@ def test_3(self): - - class IsCodeOrComment(_BaseTest): - def _wait_highlighting_finished(self): -- base._processPendingEvents(self.app) -+ base._processPendingEvents() - - def test_1(self): - # Basic case -@@ -234,7 +232,7 @@ def setUp(self): - super(Completion, self).setUp() - self.qpart.text = 'completableWord\n' - self.qpart.cursorPosition = (1, 0) -- base._processPendingEvents(self.app) -+ base._processPendingEvents() - - def test_completion_enabled(self): - self._assertNotVisible() -diff --git a/tests/test_bookmarks.py b/tests/test_bookmarks.py -index 795f4fe..31b0755 100755 ---- a/tests/test_bookmarks.py -+++ b/tests/test_bookmarks.py -@@ -6,8 +6,8 @@ - - import base - --from PyQt4.QtCore import Qt, QTimer, QPoint --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt, QTimer, QPoint -+from PyQt5.QtTest import QTest - - - from qutepart import Qutepart, iterateBlocksFrom -diff --git a/tests/test_bracket_hlighter.py b/tests/test_bracket_hlighter.py -index 8dead38..3ce076b 100755 ---- a/tests/test_bracket_hlighter.py -+++ b/tests/test_bracket_hlighter.py -@@ -6,8 +6,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - from qutepart.brackethlighter import BracketHighlighter -diff --git a/tests/test_completion.py b/tests/test_completion.py -index d8ea3ad..a7051a4 100755 ---- a/tests/test_completion.py -+++ b/tests/test_completion.py -@@ -6,9 +6,9 @@ - - import base - --from PyQt4.QtCore import Qt, QPoint --from PyQt4.QtGui import QMainWindow --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt, QPoint -+from PyQt5.QtWidgets import QMainWindow -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - import qutepart.completer -@@ -18,7 +18,6 @@ - class Test(unittest.TestCase): - """Base class for tests - """ -- app = base.papp # app crashes, if created more than once - - def setUp(self): - self._window = QMainWindow() -@@ -27,13 +26,13 @@ def setUp(self): - self._window.menuBar().addAction(self.qpart.invokeCompletionAction) - - def tearDown(self): -- del self.qpart -+ self.qpart.close() - -+ @base.in_main_loop - def test_down_selects_first(self): - self.qpart.text = 'aaaa\nbbbb\ncccX\ndddd\ncccY' - -- while self.app.hasPendingEvents(): -- self.app.processEvents() -+ QTest.qWait(1) - - QTest.keyClicks(self.qpart, "ccc") - QTest.keyClick(self.qpart, Qt.Key_Down) -@@ -41,10 +40,11 @@ def test_down_selects_first(self): - QTest.keyClick(self.qpart, Qt.Key_Enter) - self.assertEqual(self.qpart.text, 'cccX\naaaa\nbbbb\ncccX\ndddd\ncccY') - -+ @base.in_main_loop - def test_down_selects_second(self): - self.qpart.text = 'aaaa\nbbbb\ncccX\ndddd\ncccY' - -- base._processPendingEvents(self.app) -+ QTest.qWait(1) - - QTest.keyClicks(self.qpart, "ccc") - -@@ -54,19 +54,20 @@ def test_down_selects_second(self): - QTest.keyClick(self.qpart, Qt.Key_Enter) - self.assertEqual(self.qpart.text, 'cccY\naaaa\nbbbb\ncccX\ndddd\ncccY') - -- @unittest.skip("Crashes Qt 4.8.3") -+ @unittest.skip("Fix this test sometimes") -+ @base.in_main_loop - def test_click_selects_first(self): - self.qpart.text = 'aaaa\nbbbb\ncccX\ndddd\ncccY' -- - QTest.keyClicks(self.qpart, "ccc") - QTest.mouseClick(self.qpart, Qt.LeftButton) - QTest.keyClick(self.qpart, Qt.Key_Enter) - self.assertEqual(self.qpart.text, 'cccY\naaaa\nbbbb\ncccX\ndddd\ncccY') - -+ @base.in_main_loop - def test_tab_completes(self): - self.qpart.text = 'aaaaa\naaaaaXXXXX\n' - -- base._processPendingEvents(self.app) -+ QTest.qWait(1) - - self.qpart.cursorPosition = (2, 0) - QTest.keyClicks(self.qpart, "aaa") -@@ -75,12 +76,13 @@ def test_tab_completes(self): - QTest.keyClick(self.qpart, Qt.Key_Tab) - self.assertEqual(self.qpart.text, 'aaaaa\naaaaaXXXXX\naaaaaXXXXX') - -+ @base.in_main_loop - def test_manual(self): - self._window.show() - - self.qpart.text = 'aaaaa\naaaaaXXXXX\n' - -- base._processPendingEvents(self.app) -+ QTest.qWait(1) - - self.qpart.cursorPosition = (2, 0) - QTest.keyClicks(self.qpart, "a") -@@ -97,14 +99,16 @@ def test_too_long_list(self): - - self.qpart.text = '\n'.join(['asdf' + str(i) \ - for i in range(100)]) + '\n' -- base._processPendingEvents(self.app) -+ -+ QTest.qWait(1) -+ - self.qpart.cursorPosition = (100, 0) - QTest.keyClicks(self.qpart, "asdf") - self.assertIsNotNone(self.qpart._completer._widget) - - self.qpart.text = '\n'.join(['asdf' + str(i) \ - for i in range(1000)]) + '\n' -- base._processPendingEvents(self.app) -+ QTest.qWait(1) - self.qpart.cursorPosition = (1000, 0) - QTest.keyClicks(self.qpart, "asdf") - self.assertIsNone(self.qpart._completer._widget) -diff --git a/tests/test_draw_whitespace.py b/tests/test_draw_whitespace.py -index fa484e9..88c92c3 100755 ---- a/tests/test_draw_whitespace.py -+++ b/tests/test_draw_whitespace.py -@@ -8,8 +8,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - -diff --git a/tests/test_edit.py b/tests/test_edit.py -index 0f91f9c..3e55db4 100755 ---- a/tests/test_edit.py -+++ b/tests/test_edit.py -@@ -5,8 +5,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - -diff --git a/tests/test_indent.py b/tests/test_indent.py -index 2ce5d57..9e44763 100755 ---- a/tests/test_indent.py -+++ b/tests/test_indent.py -@@ -5,8 +5,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - -diff --git a/tests/test_indenter/indenttest.py b/tests/test_indenter/indenttest.py -index 58e7a53..0fd0b8b 100644 ---- a/tests/test_indenter/indenttest.py -+++ b/tests/test_indenter/indenttest.py -@@ -3,8 +3,8 @@ - import sip - sip.setapi('QString', 2) - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - import sys - import os -diff --git a/tests/test_rectangular_selection.py b/tests/test_rectangular_selection.py -index c814ec0..e18965e 100755 ---- a/tests/test_rectangular_selection.py -+++ b/tests/test_rectangular_selection.py -@@ -8,8 +8,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - -diff --git a/tests/test_vim.py b/tests/test_vim.py -index 2f27fe3..24b5df6 100755 ---- a/tests/test_vim.py -+++ b/tests/test_vim.py -@@ -6,8 +6,8 @@ - - import base - --from PyQt4.QtCore import Qt --from PyQt4.QtTest import QTest -+from PyQt5.QtCore import Qt -+from PyQt5.QtTest import QTest - - from qutepart import Qutepart - - -From 8e8ac3fee4252b7aff5c9401dedc1119235ac973 Mon Sep 17 00:00:00 2001 -From: Andrei Kopats -Date: Thu, 13 Aug 2015 14:59:07 +0300 -Subject: [PATCH 3/4] qt5: vim test fix - ---- - qutepart/vim.py | 5 ++--- - tests/test_vim.py | 2 -- - 2 files changed, 2 insertions(+), 5 deletions(-) - -diff --git a/qutepart/vim.py b/qutepart/vim.py -index fd6f441..a84154a 100644 ---- a/qutepart/vim.py -+++ b/qutepart/vim.py -@@ -652,11 +652,10 @@ def cmdJoinLines(self, cmd, repeatLineCount=None): - - self._qpart.setTextCursor(cursor) - -- - def cmdAppendAfterChar(self, cmd): - cursor = self._qpart.textCursor() -- cursor.movePosition(QTextCursor.Right) -- self._qpart.setTextCursor(cursor) -+ cursor.setPosition(cursor.position() + 1) -+ self._qpart.setTextCursor(cursor) # move Right doesn't work here on Py3 Qt5 - self.switchMode(Insert) - - def cmdReplaceSelectedLines(self, cmd): -diff --git a/tests/test_vim.py b/tests/test_vim.py -index 24b5df6..90a5de0 100755 ---- a/tests/test_vim.py -+++ b/tests/test_vim.py -@@ -736,8 +736,6 @@ def test_08(self): - 'The quick The quick brown fox') - - -- -- - class Visual(_Test): - def test_01(self): - """ x - -From 0e9612914f0ab90fd62c8160590191bfe4153658 Mon Sep 17 00:00:00 2001 -From: Andrei Kopats -Date: Tue, 20 Oct 2015 21:03:43 +0300 -Subject: [PATCH 4/4] py3: fix setup.py - ---- - setup.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/setup.py b/setup.py -index 5b26ba1..dcac71e 100755 ---- a/setup.py -+++ b/setup.py -@@ -83,7 +83,7 @@ def _checkDependencies(): - libraries = ['pcre'], - include_dirs=include_dirs, - library_dirs=library_dirs): -- print("Failed to find pcre library." -+ print("Failed to find pcre library.") - print("Try to install libpcre{version}-dev package, or go to http://pcre.org") - print("If not standard directories are used, pass parameters:") - print("\tpython setup.py install --lib-dir=c://github/pcre-8.32/build/Release --include-dir=c://github/pcre-8.32/build")