summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author Eric Hameleers <alien@slackware.com>2020-01-01 01:51:29 +0100
committer Eric Hameleers <alien@slackware.com>2020-01-01 01:51:29 +0100
commitafa7e3c5884b6e72ff5410e2d5a4a3fd786e18a3 (patch)
treec8d5f218e16f094871400a6a76eb5be9f295d23c
parentc338d286e89c88eb5095621642a0167be3707f91 (diff)
downloadktown-afa7e3c5884b6e72ff5410e2d5a4a3fd786e18a3.tar.gz
ktown-afa7e3c5884b6e72ff5410e2d5a4a3fd786e18a3.tar.xz
Recompilations caused by the update to Python 3.8 in -current
-rwxr-xr-xdeps/PyQt5/PyQt5.SlackBuild2
-rwxr-xr-xdeps/QScintilla/QScintilla.SlackBuild2
-rwxr-xr-xdeps/brotli/brotli.SlackBuild2
-rwxr-xr-xdeps/cryfs/cryfs.SlackBuild2
-rwxr-xr-xdeps/gpgme/gpgme.SlackBuild2
-rwxr-xr-xdeps/lensfun/lensfun.SlackBuild2
-rwxr-xr-xdeps/mlt/mlt.SlackBuild2
-rwxr-xr-xdeps/python3-random2/python3-random2.SlackBuild4
-rwxr-xr-xdeps/sip/sip.SlackBuild2
-rwxr-xr-xdeps/speech-dispatcher/speech-dispatcher.SlackBuild2
-rw-r--r--kde/build/kauth1
-rw-r--r--kde/build/kcodecs1
-rw-r--r--kde/build/kcompletion1
-rw-r--r--kde/build/kconfig1
-rw-r--r--kde/build/kconfigwidgets1
-rw-r--r--kde/build/kcoreaddons1
-rw-r--r--kde/build/kdbusaddons1
-rw-r--r--kde/build/kdev-python1
-rw-r--r--kde/build/kguiaddons1
-rw-r--r--kde/build/ki18n1
-rw-r--r--kde/build/kitemmodels1
-rw-r--r--kde/build/kitemviews1
-rw-r--r--kde/build/kjobwidgets1
-rw-r--r--kde/build/krita1
-rw-r--r--kde/build/kwidgetsaddons1
-rw-r--r--kde/patch/kdev-python.patch4
-rw-r--r--kde/patch/kdev-python/kdev-python-5.4.4_python38.patch560
27 files changed, 590 insertions, 11 deletions
diff --git a/deps/PyQt5/PyQt5.SlackBuild b/deps/PyQt5/PyQt5.SlackBuild
index 33c203e..8552e19 100755
--- a/deps/PyQt5/PyQt5.SlackBuild
+++ b/deps/PyQt5/PyQt5.SlackBuild
@@ -30,7 +30,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=PyQt5
VERSION=${VERSION:-5.13.2}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
diff --git a/deps/QScintilla/QScintilla.SlackBuild b/deps/QScintilla/QScintilla.SlackBuild
index 50035d4..62f0e60 100755
--- a/deps/QScintilla/QScintilla.SlackBuild
+++ b/deps/QScintilla/QScintilla.SlackBuild
@@ -29,7 +29,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=QScintilla
VERSION=${VERSION:-2.11.4}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
diff --git a/deps/brotli/brotli.SlackBuild b/deps/brotli/brotli.SlackBuild
index fc9ac19..1256fff 100755
--- a/deps/brotli/brotli.SlackBuild
+++ b/deps/brotli/brotli.SlackBuild
@@ -25,7 +25,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=brotli
VERSION=${VERSION:-1.0.7}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-" -j$(nproc) "}
diff --git a/deps/cryfs/cryfs.SlackBuild b/deps/cryfs/cryfs.SlackBuild
index 38f68c6..cfe9f78 100755
--- a/deps/cryfs/cryfs.SlackBuild
+++ b/deps/cryfs/cryfs.SlackBuild
@@ -28,7 +28,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=cryfs
VERSION=${VERSION:-0.10.2}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
diff --git a/deps/gpgme/gpgme.SlackBuild b/deps/gpgme/gpgme.SlackBuild
index 2e8356a..4d72555 100755
--- a/deps/gpgme/gpgme.SlackBuild
+++ b/deps/gpgme/gpgme.SlackBuild
@@ -27,7 +27,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=gpgme
VERSION=${VERSION:-1.13.1}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-"-j$(nproc)"}
diff --git a/deps/lensfun/lensfun.SlackBuild b/deps/lensfun/lensfun.SlackBuild
index ba64125..093b9a6 100755
--- a/deps/lensfun/lensfun.SlackBuild
+++ b/deps/lensfun/lensfun.SlackBuild
@@ -26,7 +26,7 @@
PKGNAM=lensfun
VERSION=${VERSION:-0.3.95}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
CWD=$(pwd)
TMP=${TMP:-/tmp}
diff --git a/deps/mlt/mlt.SlackBuild b/deps/mlt/mlt.SlackBuild
index 310b32e..8bf05be 100755
--- a/deps/mlt/mlt.SlackBuild
+++ b/deps/mlt/mlt.SlackBuild
@@ -28,7 +28,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=mlt
VERSION=${VERSION:-6.18.0}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
PYTHONSITEPKG=$(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
diff --git a/deps/python3-random2/python3-random2.SlackBuild b/deps/python3-random2/python3-random2.SlackBuild
index a0debc7..94147f1 100755
--- a/deps/python3-random2/python3-random2.SlackBuild
+++ b/deps/python3-random2/python3-random2.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright 2018 Eric Hameleers, Eindhoven, NL
+# Copyright 2018, 2019 Eric Hameleers, Eindhoven, NL
# Copyright 2018 Patrick J. Volkerding, Sebeka, MN, USA
# All rights reserved.
#
@@ -26,7 +26,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=python3-random2
SRCNAM=random2
VERSION=${VERSION:-1.0.1}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
NUMJOBS=${NUMJOBS:-" -j$(nproc) "}
diff --git a/deps/sip/sip.SlackBuild b/deps/sip/sip.SlackBuild
index 8c8e167..923ac6c 100755
--- a/deps/sip/sip.SlackBuild
+++ b/deps/sip/sip.SlackBuild
@@ -28,7 +28,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=sip
VERSION=${VERSION:-4.19.20}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
diff --git a/deps/speech-dispatcher/speech-dispatcher.SlackBuild b/deps/speech-dispatcher/speech-dispatcher.SlackBuild
index 483ce9e..a1c9592 100755
--- a/deps/speech-dispatcher/speech-dispatcher.SlackBuild
+++ b/deps/speech-dispatcher/speech-dispatcher.SlackBuild
@@ -26,7 +26,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=speech-dispatcher
VERSION=${VERSION:-0.8.8}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
diff --git a/kde/build/kauth b/kde/build/kauth
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kauth
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kcodecs b/kde/build/kcodecs
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kcodecs
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kcompletion b/kde/build/kcompletion
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kcompletion
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kconfig b/kde/build/kconfig
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kconfig
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kconfigwidgets b/kde/build/kconfigwidgets
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kconfigwidgets
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kcoreaddons b/kde/build/kcoreaddons
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kcoreaddons
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kdbusaddons b/kde/build/kdbusaddons
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kdbusaddons
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kdev-python b/kde/build/kdev-python
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kdev-python
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kguiaddons b/kde/build/kguiaddons
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kguiaddons
@@ -0,0 +1 @@
+2
diff --git a/kde/build/ki18n b/kde/build/ki18n
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/ki18n
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kitemmodels b/kde/build/kitemmodels
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kitemmodels
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kitemviews b/kde/build/kitemviews
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kitemviews
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kjobwidgets b/kde/build/kjobwidgets
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kjobwidgets
@@ -0,0 +1 @@
+2
diff --git a/kde/build/krita b/kde/build/krita
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/krita
@@ -0,0 +1 @@
+2
diff --git a/kde/build/kwidgetsaddons b/kde/build/kwidgetsaddons
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/kde/build/kwidgetsaddons
@@ -0,0 +1 @@
+2
diff --git a/kde/patch/kdev-python.patch b/kde/patch/kdev-python.patch
new file mode 100644
index 0000000..fd47d2b
--- /dev/null
+++ b/kde/patch/kdev-python.patch
@@ -0,0 +1,4 @@
+# Fix compilation against Python 3.8.
+# Fixed in 5.4.5.
+cat $CWD/patch/kdev-python/kdev-python-5.4.4_python38.patch | patch -p1 --verbose || { touch ${SLACK_KDE_BUILD_DIR}/${PKGNAME}.failed ; continue ; }
+
diff --git a/kde/patch/kdev-python/kdev-python-5.4.4_python38.patch b/kde/patch/kdev-python/kdev-python-5.4.4_python38.patch
new file mode 100644
index 0000000..572c9da
--- /dev/null
+++ b/kde/patch/kdev-python/kdev-python-5.4.4_python38.patch
@@ -0,0 +1,560 @@
+From e23fa8f15af89a8bd4bd84dd96b5fd7017457516 Mon Sep 17 00:00:00 2001
+From: Francis Herne <mail@flherne.uk>
+Date: Fri, 20 Sep 2019 00:41:29 +0100
+Subject: [PATCH] Initial Python 3.8 support.
+
+This allows kdev-python to be built and run against CPython 3.8,
+ and if so to parse files containing 3.8 syntax.
+
+BUG: 411956
+FIXED-IN: 5.5.0
+---
+ CMakeLists.txt | 4 +-
+ duchain/declarationbuilder.cpp | 10 ++++-
+ duchain/declarationbuilder.h | 1 +
+ duchain/expressionvisitor.cpp | 4 ++
+ duchain/expressionvisitor.h | 1 +
+ duchain/tests/pyduchaintest.cpp | 19 +++++++++
+ parser/ast.cpp | 7 +++-
+ parser/ast.h | 9 ++++
+ parser/astbuilder.cpp | 6 +++
+ parser/astdefaultvisitor.cpp | 6 +++
+ parser/astdefaultvisitor.h | 2 +
+ parser/astvisitor.cpp | 1 +
+ parser/astvisitor.h | 1 +
+ parser/conversionGenerator.py | 11 +++--
+ parser/generated.h | 36 ++++++++++++++++
+ parser/{python36.sdef => python38.sdef} | 55 ++++++++++++++++++++++---
+ parser/tests/pyasttest.cpp | 5 +++
+ 17 files changed, 164 insertions(+), 14 deletions(-)
+ rename parser/{python36.sdef => python38.sdef} (82%)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 6f9e465b..09b089dd 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -31,7 +31,7 @@ add_definitions( -DTRANSLATION_DOMAIN=\"kdevpython\" )
+
+ # CMake looks for exactly the specified version first and ignores newer versions.
+ # To avoid that, start looking for the newest supported version and work down.
+-set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
++set(Python_ADDITIONAL_VERSIONS 3.8 3.7 3.6 3.5 3.4)
+ foreach(_PYTHON_V ${Python_ADDITIONAL_VERSIONS})
+ find_package(PythonInterp ${_PYTHON_V})
+ if ( PYTHONINTERP_FOUND )
+@@ -49,7 +49,7 @@ if ( PYTHONINTERP_FOUND AND PYTHON_VERSION_STRING VERSION_GREATER "3.4" )
+ endif()
+
+ if ( NOT PYTHONLIBS_FOUND OR PYTHONLIBS_VERSION_STRING VERSION_LESS "3.4.3" )
+- message(FATAL_ERROR "Python >= 3.4.3 but < 3.8 with --enable-shared is required to build kdev-python")
++ message(FATAL_ERROR "Python >= 3.4.3 but < 3.9 with --enable-shared is required to build kdev-python")
+ endif()
+
+ configure_file(kdevpythonversion.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/kdevpythonversion.h" @ONLY)
+diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp
+index e3cb2b9c..61e144c5 100644
+--- a/duchain/declarationbuilder.cpp
++++ b/duchain/declarationbuilder.cpp
+@@ -1354,6 +1354,14 @@ void DeclarationBuilder::visitAnnotationAssignment(AnnotationAssignmentAst* node
+ assignToUnknown(node->target, assignType);
+ }
+
++void DeclarationBuilder::visitAssignmentExpression(AssignmentExpressionAst* node) {
++ AstDefaultVisitor::visitAssignmentExpression(node);
++
++ ExpressionVisitor v(currentContext());
++ v.visitNode(node->value);
++ assignToUnknown(node->target, v.lastType());
++}
++
+ void DeclarationBuilder::visitClassDefinition( ClassDefinitionAst* node )
+ {
+ visitNodeList(node->decorators);
+@@ -1745,7 +1753,7 @@ void DeclarationBuilder::visitArguments( ArgumentsAst* node )
+ int parametersCount = node->arguments.length();
+ int firstDefaultParameterOffset = parametersCount - defaultParametersCount;
+ int currentIndex = 0;
+- foreach ( ArgAst* arg, node->arguments + node->kwonlyargs ) {
++ foreach ( ArgAst* arg, node->posonlyargs + node->arguments + node->kwonlyargs ) {
+ // Iterate over all the function's arguments, create declarations, and add the arguments
+ // to the functions FunctionType.
+ currentIndex += 1;
+diff --git a/duchain/declarationbuilder.h b/duchain/declarationbuilder.h
+index adee6d6d..1992b781 100644
+--- a/duchain/declarationbuilder.h
++++ b/duchain/declarationbuilder.h
+@@ -90,6 +90,7 @@ class KDEVPYTHONDUCHAIN_EXPORT DeclarationBuilder: public DeclarationBuilderBase
+ void visitFunctionDefinition(FunctionDefinitionAst* node) override;
+ void visitAssignment(AssignmentAst* node) override;
+ void visitAnnotationAssignment(AnnotationAssignmentAst* node) override;
++ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
+ void visitFor(ForAst* node) override;
+ void visitImport(ImportAst* node) override;
+ void visitImportFrom(ImportFromAst* node) override;
+diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp
+index 5c5286ae..055c5b49 100644
+--- a/duchain/expressionvisitor.cpp
++++ b/duchain/expressionvisitor.cpp
+@@ -757,5 +757,9 @@ void ExpressionVisitor::visitBooleanOperation(Python::BooleanOperationAst* node)
+ encounter(result);
+ }
+
++void ExpressionVisitor::visitAssignmentExpression(Python::AssignmentExpressionAst* node) {
++ visitNode(node->value);
++}
++
+ }
+
+diff --git a/duchain/expressionvisitor.h b/duchain/expressionvisitor.h
+index 25ca2319..a56481ad 100644
+--- a/duchain/expressionvisitor.h
++++ b/duchain/expressionvisitor.h
+@@ -81,6 +81,7 @@ class KDEVPYTHONDUCHAIN_EXPORT ExpressionVisitor : public AstDefaultVisitor, pub
+ void visitSetComprehension(SetComprehensionAst* node) override;
+ void visitIfExpression(IfExpressionAst* node) override;
+ void visitNameConstant(NameConstantAst* node) override;
++ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
+
+ /**
+ * @brief Checks for magic docstrings that override a call's return type.
+diff --git a/duchain/tests/pyduchaintest.cpp b/duchain/tests/pyduchaintest.cpp
+index 7142ed2b..17ba34e5 100644
+--- a/duchain/tests/pyduchaintest.cpp
++++ b/duchain/tests/pyduchaintest.cpp
+@@ -838,6 +838,7 @@ void PyDUChainTest::testTypes()
+ QEXPECT_FAIL("init_class_no_decl", "aliasing info lost", Continue);
+ QEXPECT_FAIL("property_wrong", "visitCall uses declaration if no type", Continue);
+ QEXPECT_FAIL("property_setter", "very basic property support", Continue);
++ QEXPECT_FAIL("assignment_expr_context", "not implemented", Continue);
+ QCOMPARE(visitor->found, true);
+ }
+
+@@ -1302,6 +1303,21 @@ void PyDUChainTest::testTypes_data()
+ " def foo(self, ccc=aaa, ddd=bbb):\n" // self.bbb is visible here, Foo().aaa isn't.
+ " return ccc, ddd\n"
+ "checkme = Foo().Bar().foo()\n" << "tuple of (str, int)";
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ QTest::newRow("assignment_expr_while") <<
++ "file = open('foo.txt')\n"
++ "while q := file.readline():\n"
++ " checkme = q\n" << "str";
++ QTest::newRow("assignment_expr_comprehension") <<
++ "checkme = [z for q in (1, 2, 3) if (z := q % 2)]" << "list of int";
++ QTest::newRow("assignment_expr_context") <<
++ "a = [z for q in (1, 2, 3) if (z := q % 2)]\n"
++ "checkme = z" << "int";
++ QTest::newRow("positional_params") <<
++ "def foo(a, b, /, c, d):\n"
++ " return a, b, c, d\n"
++ "checkme = foo(10, 'x', 2.3, d='y')\n" << "tuple of (int, str, float, str)";
++#endif
+ }
+
+ typedef QPair<Declaration*, int> pair;
+@@ -1780,6 +1796,9 @@ void PyDUChainTest::testVariableCreation_data()
+ << QStringList{"int", "int", "float"};
+ QTest::newRow("for_loop_tuple") << "for a in 1, 2: pass" << QStringList{"a"} << QStringList{"int"};
+ QTest::newRow("for_loop_dict") << "for a in {'foo': 1}: pass" << QStringList{"a"} << QStringList{"str"};
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ QTest::newRow("assignment_expr") << "a = (b := 10)" << QStringList{"a", "b"} << QStringList{"int", "int"};
++#endif
+ }
+
+ void PyDUChainTest::testCleanupMultiplePasses()
+diff --git a/parser/ast.cpp b/parser/ast.cpp
+index 9892b184..cd570d36 100644
+--- a/parser/ast.cpp
++++ b/parser/ast.cpp
+@@ -163,6 +163,11 @@ ExpressionAst::ExpressionAst(Ast* parent, AstType type): Ast(parent, type), valu
+
+ }
+
++AssignmentExpressionAst::AssignmentExpressionAst(Ast* parent): ExpressionAst(parent, Ast::AssignmentExpressionAstType), value(nullptr)
++{
++
++}
++
+ YieldFromAst::YieldFromAst(Ast* parent) : ExpressionAst(parent, Ast::YieldFromAstType)
+ {
+
+@@ -248,7 +253,7 @@ NameConstantAst::NameConstantAst(Ast* parent): ExpressionAst(parent, Ast::NameCo
+
+ }
+
+-NumberAst::NumberAst(Ast* parent): ExpressionAst(parent, Ast::NumberAstType), value(0)
++NumberAst::NumberAst(Ast* parent): ExpressionAst(parent, Ast::NumberAstType), value(0), isInt(false)
+ {
+
+ }
+diff --git a/parser/ast.h b/parser/ast.h
+index 378af0bd..65fef1cd 100644
+--- a/parser/ast.h
++++ b/parser/ast.h
+@@ -131,6 +131,7 @@ class KDEVPYTHONPARSER_EXPORT Ast
+ SliceAstType,
+ EllipsisAstType,
+ IndexAstType,
++ AssignmentExpressionAstType,
+ LastExpressionType, // keep this at the end of the expr ast list
+
+ CodeAstType,
+@@ -457,6 +458,13 @@ class KDEVPYTHONPARSER_EXPORT ExpressionAst : public Ast {
+ ExpressionAst* value; // WARNING this is not set in most cases!
+ };
+
++class KDEVPYTHONPARSER_EXPORT AssignmentExpressionAst : public ExpressionAst {
++public:
++ AssignmentExpressionAst(Ast* parent);
++ ExpressionAst* target;
++ ExpressionAst* value;
++};
++
+ class KDEVPYTHONPARSER_EXPORT AwaitAst : public ExpressionAst {
+ public:
+ AwaitAst(Ast* parent);
+@@ -743,6 +751,7 @@ class KDEVPYTHONPARSER_EXPORT ArgumentsAst : public Ast {
+ ArgumentsAst(Ast* parent);
+ QList<ArgAst*> arguments;
+ QList<ArgAst*> kwonlyargs;
++ QList<ArgAst*> posonlyargs;
+ QList<ExpressionAst*> defaultValues;
+ ArgAst* vararg;
+ ArgAst* kwarg;
+diff --git a/parser/astbuilder.cpp b/parser/astbuilder.cpp
+index a1ccd68d..ad2e0dce 100644
+--- a/parser/astbuilder.cpp
++++ b/parser/astbuilder.cpp
+@@ -101,7 +101,13 @@ CodeAst::Ptr AstBuilder::parse(const QUrl& filename, QString &contents)
+ PythonInitializer pyIniter(pyInitLock);
+ PyArena* arena = pyIniter.arena;
+
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ PyCompilerFlags flags;
++ flags.cf_flags = PyCF_SOURCE_IS_UTF8 | PyCF_IGNORE_COOKIE | PyCF_ONLY_AST;
++ flags.cf_feature_version = 7;
++#else
+ PyCompilerFlags flags = {PyCF_SOURCE_IS_UTF8 | PyCF_IGNORE_COOKIE};
++#endif
+
+ CythonSyntaxRemover cythonSyntaxRemover;
+
+diff --git a/parser/astdefaultvisitor.cpp b/parser/astdefaultvisitor.cpp
+index 5db1f6f1..cdd31bbf 100644
+--- a/parser/astdefaultvisitor.cpp
++++ b/parser/astdefaultvisitor.cpp
+@@ -292,6 +292,12 @@ void AstDefaultVisitor::visitAnnotationAssignment(AnnotationAssignmentAst* node)
+ visitNode(node->value);
+ }
+
++void AstDefaultVisitor::visitAssignmentExpression(AssignmentExpressionAst* node)
++{
++ visitNode(node->target);
++ visitNode(node->value);
++}
++
+ void AstDefaultVisitor::visitBinaryOperation(BinaryOperationAst* node)
+ {
+ visitNode(node->lhs);
+diff --git a/parser/astdefaultvisitor.h b/parser/astdefaultvisitor.h
+index e8e0d3de..aa1f540c 100644
+--- a/parser/astdefaultvisitor.h
++++ b/parser/astdefaultvisitor.h
+@@ -49,6 +49,7 @@ class KDEVPYTHONPARSER_EXPORT AstDefaultVisitor : public AstVisitor
+ void visitAssignment(AssignmentAst* node) override;
+ void visitAugmentedAssignment(AugmentedAssignmentAst* node) override;
+ void visitAnnotationAssignment(AnnotationAssignmentAst* node) override;
++ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
+ void visitFor(ForAst* node) override;
+ void visitWhile(WhileAst* node) override;
+ void visitIf(IfAst* node) override;
+@@ -122,6 +123,7 @@ class KDEVPYTHONPARSER_EXPORT AstFreeVisitor : public AstDefaultVisitor {
+ void visitAssignment(AssignmentAst* node) override { AstDefaultVisitor::visitAssignment(node); delete node; }
+ void visitAugmentedAssignment(AugmentedAssignmentAst* node) override { AstDefaultVisitor::visitAugmentedAssignment(node); delete node; }
+ void visitAnnotationAssignment(AnnotationAssignmentAst* node) override { AstDefaultVisitor::visitAnnotationAssignment(node); delete node; }
++ void visitAssignmentExpression(AssignmentExpressionAst* node) override { AstDefaultVisitor::visitAssignmentExpression(node); delete node; }
+ void visitFor(ForAst* node) override { AstDefaultVisitor::visitFor(node); delete node; }
+ void visitWhile(WhileAst* node) override { AstDefaultVisitor::visitWhile(node); delete node; }
+ void visitIf(IfAst* node) override { AstDefaultVisitor::visitIf(node); delete node; }
+diff --git a/parser/astvisitor.cpp b/parser/astvisitor.cpp
+index ace7d619..51c5a1c5 100644
+--- a/parser/astvisitor.cpp
++++ b/parser/astvisitor.cpp
+@@ -47,6 +47,7 @@ void AstVisitor::visitNode(Ast* node)
+ case Ast::AssignmentAstType: this->visitAssignment(static_cast<AssignmentAst*>(node)); break;
+ case Ast::AugmentedAssignmentAstType: this->visitAugmentedAssignment(static_cast<AugmentedAssignmentAst*>(node)); break;
+ case Ast::AnnotationAssignmentAstType: this->visitAnnotationAssignment(static_cast<AnnotationAssignmentAst*>(node)); break;
++ case Ast::AssignmentExpressionAstType: this->visitAssignmentExpression(static_cast<AssignmentExpressionAst*>(node)); break;
+ case Ast::ForAstType: this->visitFor(static_cast<ForAst*>(node)); break;
+ case Ast::WhileAstType: this->visitWhile(static_cast<WhileAst*>(node)); break;
+ case Ast::IfAstType: this->visitIf(static_cast<IfAst*>(node)); break;
+diff --git a/parser/astvisitor.h b/parser/astvisitor.h
+index 1908e9dd..51aa47b4 100644
+--- a/parser/astvisitor.h
++++ b/parser/astvisitor.h
+@@ -61,6 +61,7 @@ class KDEVPYTHONPARSER_EXPORT AstVisitor
+ virtual void visitAssignment(AssignmentAst* node) { Q_UNUSED(node); };
+ virtual void visitAugmentedAssignment(AugmentedAssignmentAst* node) { Q_UNUSED(node); };
+ virtual void visitAnnotationAssignment(AnnotationAssignmentAst* node) { Q_UNUSED(node); };
++ virtual void visitAssignmentExpression(AssignmentExpressionAst* node) { Q_UNUSED(node); };
+ virtual void visitFor(ForAst* node) { Q_UNUSED(node); };
+ virtual void visitWhile(WhileAst* node) { Q_UNUSED(node); };
+ virtual void visitIf(IfAst* node) { Q_UNUSED(node); };
+diff --git a/parser/conversionGenerator.py b/parser/conversionGenerator.py
+index 9d65cc0d..66055953 100644
+--- a/parser/conversionGenerator.py
++++ b/parser/conversionGenerator.py
+@@ -9,7 +9,7 @@
+
+ import sys
+
+-contents = open('python36.sdef').read().replace("\n", "").split(';;')
++contents = open('python38.sdef').read().replace("\n", "").split(';;')
+
+ func_structure = '''
+ Ast* visitNode(%{RULE_FOR}* node) {
+@@ -45,7 +45,6 @@
+
+ switch_line = ''' case %{KIND}: {
+ %{ACTIONS}
+- result = v;
+ break;
+ }'''
+
+@@ -139,6 +138,7 @@ def pluginAstToPythonAstType(plugintypestr):
+ results[rule_for] = list()
+
+ current_actions = list()
++ created_v = False
+ for action in actions:
+ command = action.split('|')[0]
+ try:
+@@ -204,14 +204,17 @@ def pluginAstToPythonAstType(plugintypestr):
+ elif command == 'create':
+ astType = arguments
+ current_actions.append(create_ast_line.replace('%{AST_TYPE}', astType))
+-
++ created_v = True
++
+ if code:
+ current_actions.append(code);
+-
++
+ current_actions = "\n".join(current_actions)
+ if kind == 'any':
+ current_stmt = current_actions
+ else:
++ if created_v:
++ current_actions += "\n result = v;"
+ current_stmt = switch_line.replace('%{KIND}', kind).replace('%{ACTIONS}', current_actions)
+ if before_version:
+ version_cpp_if = ("#if PYTHON_VERSION < QT_VERSION_CHECK(%d, %d, 0)\n"
+diff --git a/parser/generated.h b/parser/generated.h
+index 9061deb0..e1136f84 100644
+--- a/parser/generated.h
++++ b/parser/generated.h
+@@ -76,12 +76,23 @@ class PythonAstTransformer {
+ Ast* visitNode(_arguments* node) {
+ bool ranges_copied = false; Q_UNUSED(ranges_copied);
+ if ( ! node ) return nullptr;
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ ArgumentsAst* v = new ArgumentsAst(parent());
+ nodeStack.push(v); v->vararg = static_cast<ArgAst*>(visitNode(node->vararg)); nodeStack.pop();
+ nodeStack.push(v); v->kwarg = static_cast<ArgAst*>(visitNode(node->kwarg)); nodeStack.pop();
+ nodeStack.push(v); v->arguments = visitNodeList<_arg, ArgAst>(node->args); nodeStack.pop();
+ nodeStack.push(v); v->defaultValues = visitNodeList<_expr, ExpressionAst>(node->defaults); nodeStack.pop();
+ nodeStack.push(v); v->kwonlyargs = visitNodeList<_arg, ArgAst>(node->kwonlyargs); nodeStack.pop();
++#endif
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ ArgumentsAst* v = new ArgumentsAst(parent());
++ nodeStack.push(v); v->vararg = static_cast<ArgAst*>(visitNode(node->vararg)); nodeStack.pop();
++ nodeStack.push(v); v->kwarg = static_cast<ArgAst*>(visitNode(node->kwarg)); nodeStack.pop();
++ nodeStack.push(v); v->arguments = visitNodeList<_arg, ArgAst>(node->args); nodeStack.pop();
++ nodeStack.push(v); v->defaultValues = visitNodeList<_expr, ExpressionAst>(node->defaults); nodeStack.pop();
++ nodeStack.push(v); v->kwonlyargs = visitNodeList<_arg, ArgAst>(node->kwonlyargs); nodeStack.pop();
++ nodeStack.push(v); v->posonlyargs = visitNodeList<_arg, ArgAst>(node->posonlyargs); nodeStack.pop();
++#endif
+ return v;
+ }
+
+@@ -280,18 +291,22 @@ class PythonAstTransformer {
+ break;
+ }
+ #endif
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ case Num_kind: {
+ NumberAst* v = new NumberAst(parent());
+ v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);
+ result = v;
+ break;
+ }
++#endif
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ case Str_kind: {
+ StringAst* v = new StringAst(parent());
+ v->value = PyUnicodeObjectToQString(node->v.Str.s);
+ result = v;
+ break;
+ }
++#endif
+ #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0)
+ case JoinedStr_kind: {
+ JoinedStringAst* v = new JoinedStringAst(parent());
+@@ -310,12 +325,14 @@ class PythonAstTransformer {
+ break;
+ }
+ #endif
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ case Bytes_kind: {
+ BytesAst* v = new BytesAst(parent());
+ v->value = PyUnicodeObjectToQString(node->v.Bytes.s);
+ result = v;
+ break;
+ }
++#endif
+ case Attribute_kind: {
+ AttributeAst* v = new AttributeAst(parent());
+ v->attribute = node->v.Attribute.attr ? new Python::Identifier(PyUnicodeObjectToQString(node->v.Attribute.attr)) : nullptr;
+@@ -374,23 +391,42 @@ class PythonAstTransformer {
+ result = v;
+ break;
+ }
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ case Ellipsis_kind: {
+ EllipsisAst* v = new EllipsisAst(parent());
+ result = v;
+ break;
+ }
++#endif
++#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
+ case NameConstant_kind: {
+ NameConstantAst* v = new NameConstantAst(parent());
+ v->value = node->v.NameConstant.value == Py_None ? NameConstantAst::None : node->v.NameConstant.value == Py_False ? NameConstantAst::False : NameConstantAst::True;
+ result = v;
+ break;
+ }
++#endif
+ case YieldFrom_kind: {
+ YieldFromAst* v = new YieldFromAst(parent());
+ nodeStack.push(v); v->value = static_cast<ExpressionAst*>(visitNode(node->v.YieldFrom.value)); nodeStack.pop();
+ result = v;
+ break;
+ }
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ case Constant_kind: {
++PyObject *value = node->v.Constant.value;if (value == Py_None) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::None; result = v;}else if (value == Py_True) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::True; result = v;}else if (value == Py_False) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::False; result = v;}else if (value->ob_type == &PyLong_Type) { NumberAst* v = new NumberAst(parent()); v->isInt = true; v->value = PyLong_AsLong(value); result = v;}else if (value->ob_type == &PyFloat_Type || value->ob_type == &PyComplex_Type) { result = new NumberAst(parent());}else if (value->ob_type == &PyUnicode_Type) { StringAst* v = new StringAst(parent()); v->value = PyUnicodeObjectToQString(value); result = v;}else if (value->ob_type == &PyBytes_Type) { result = new BytesAst(parent());}else if (value->ob_type == &PyEllipsis_Type) { result = new EllipsisAst(parent());}else { qWarning() << "Unhandled constant type: " << value->ob_type->tp_name; Q_ASSERT(false);};
++ break;
++ }
++#endif
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ case NamedExpr_kind: {
++ AssignmentExpressionAst* v = new AssignmentExpressionAst(parent());
++ nodeStack.push(v); v->target = static_cast<ExpressionAst*>(visitNode(node->v.NamedExpr.target)); nodeStack.pop();
++ nodeStack.push(v); v->value = static_cast<ExpressionAst*>(visitNode(node->v.NamedExpr.value)); nodeStack.pop();
++ result = v;
++ break;
++ }
++#endif
+ default:
+ qWarning() << "Unsupported _expr AST type: " << node->kind;
+ Q_ASSERT(false);
+diff --git a/parser/python36.sdef b/parser/python38.sdef
+similarity index 82%
+rename from parser/python36.sdef
+rename to parser/python38.sdef
+index f53ff1c7..30d9f95a 100644
+--- a/parser/python36.sdef
++++ b/parser/python38.sdef
+@@ -73,20 +73,62 @@ if (node->v.Call.kwargs) {
+ v->keywords.append(kwargs);
+ nodeStack.pop();
+ };;
+-RULE_FOR _expr;KIND Num_kind;ACTIONS create|NumberAst;CODE v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);;
+-RULE_FOR _expr;KIND Str_kind;ACTIONS create|StringAst set|value$>s;;
++RULE_FOR _expr;KIND Num_kind;ACTIONS create|NumberAst;BEFORE 3.8;CODE v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);;
++RULE_FOR _expr;KIND Str_kind;ACTIONS create|StringAst set|value$>s;BEFORE 3.8;;
+ RULE_FOR _expr;KIND JoinedStr_kind;ACTIONS create|JoinedStringAst set|values=>ExpressionAst,values;SINCE 3.6;;
+ RULE_FOR _expr;KIND FormattedValue_kind;ACTIONS create|FormattedValueAst set|value->ExpressionAst,value set|conversion:>conversion set|formatSpec->ExpressionAst,format_spec;SINCE 3.6;;
+-RULE_FOR _expr;KIND Bytes_kind;ACTIONS create|BytesAst set|value$>s;;
++RULE_FOR _expr;KIND Bytes_kind;ACTIONS create|BytesAst set|value$>s;BEFORE 3.8;;
+ RULE_FOR _expr;KIND Attribute_kind;ACTIONS create|AttributeAst set|attribute~>attr set|value->ExpressionAst,value set|context*>Context,ctx;;
+ RULE_FOR _expr;KIND Subscript_kind;ACTIONS create|SubscriptAst set|value->ExpressionAst,value set|slice->SliceAst,slice set|context*>Context,ctx;;
+ RULE_FOR _expr;KIND Starred_kind;ACTIONS create|StarredAst set|value->ExpressionAst,value set|context*>Context,ctx;;
+ RULE_FOR _expr;KIND Name_kind;ACTIONS create|NameAst set|identifier~>id set|context*>Context,ctx;;
+ RULE_FOR _expr;KIND List_kind;ACTIONS create|ListAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
+ RULE_FOR _expr;KIND Tuple_kind;ACTIONS create|TupleAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
+-RULE_FOR _expr;KIND Ellipsis_kind;ACTIONS create|EllipsisAst;;
+-RULE_FOR _expr;KIND NameConstant_kind;ACTIONS create|NameConstantAst set|value_>value;;
++RULE_FOR _expr;KIND Ellipsis_kind;ACTIONS create|EllipsisAst;BEFORE 3.8;;
++RULE_FOR _expr;KIND NameConstant_kind;ACTIONS create|NameConstantAst set|value_>value;BEFORE 3.8;;
+ RULE_FOR _expr;KIND YieldFrom_kind;ACTIONS create|YieldFromAst set|value->ExpressionAst,value;;
++RULE_FOR _expr;KIND Constant_kind;ACTIONS;SINCE 3.8;CODE
++PyObject *value = node->v.Constant.value;
++if (value == Py_None) {
++ NameConstantAst* v = new NameConstantAst(parent());
++ v->value = NameConstantAst::None;
++ result = v;
++}
++else if (value == Py_True) {
++ NameConstantAst* v = new NameConstantAst(parent());
++ v->value = NameConstantAst::True;
++ result = v;
++}
++else if (value == Py_False) {
++ NameConstantAst* v = new NameConstantAst(parent());
++ v->value = NameConstantAst::False;
++ result = v;
++}
++else if (value->ob_type == &PyLong_Type) {
++ NumberAst* v = new NumberAst(parent());
++ v->isInt = true;
++ v->value = PyLong_AsLong(value);
++ result = v;
++}
++else if (value->ob_type == &PyFloat_Type || value->ob_type == &PyComplex_Type) {
++ result = new NumberAst(parent());
++}
++else if (value->ob_type == &PyUnicode_Type) {
++ StringAst* v = new StringAst(parent());
++ v->value = PyUnicodeObjectToQString(value);
++ result = v;
++}
++else if (value->ob_type == &PyBytes_Type) {
++ result = new BytesAst(parent());
++}
++else if (value->ob_type == &PyEllipsis_Type) {
++ result = new EllipsisAst(parent());
++}
++else {
++ qWarning() << "Unhandled constant type: " << value->ob_type->tp_name;
++ Q_ASSERT(false);
++};;
++RULE_FOR _expr;KIND NamedExpr_kind;ACTIONS create|AssignmentExpressionAst set|target->ExpressionAst,target set|value->ExpressionAst,value;SINCE 3.8;;
+
+ RULE_FOR _slice;KIND Slice_kind;ACTIONS create|SliceAst set|lower->ExpressionAst,lower set|upper->ExpressionAst,upper set|step->ExpressionAst,step;;
+ RULE_FOR _slice;KIND ExtSlice_kind;ACTIONS create|ExtendedSliceAst set|dims=>SliceAst,dims;;
+@@ -95,7 +137,8 @@ RULE_FOR _slice;KIND Index_kind;ACTIONS create|IndexAst set|value->ExpressionAst
+
+ RULE_FOR _comprehension;KIND any;ACTIONS create|ComprehensionAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|conditions=>ExpressionAst,ifs;;
+ RULE_FOR _excepthandler;KIND ExceptHandler_kind;ACTIONS create|ExceptionHandlerAst set|type->ExpressionAst,type set|name~>name set|body=>Ast,body;;
+-RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs;;
++RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs;BEFORE 3.8;;
++RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs set|posonlyargs=>ArgAst,posonlyargs;SINCE 3.8;;
+ RULE_FOR _arg;KIND any;ACTIONS create|ArgAst set|argumentName~>arg set|annotation->ExpressionAst,annotation;;
+ RULE_FOR _keyword;KIND any;ACTIONS create|KeywordAst set|argumentName~>arg set|value->ExpressionAst,value;;
+ RULE_FOR _alias;KIND any;ACTIONS create|AliasAst set|name~>name set|asName~>asname;;
+diff --git a/parser/tests/pyasttest.cpp b/parser/tests/pyasttest.cpp
+index 4fd5f4eb..c28f6fce 100644
+--- a/parser/tests/pyasttest.cpp
++++ b/parser/tests/pyasttest.cpp
+@@ -238,6 +238,11 @@ void PyAstTest::testExpressions_data()
+ " **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions},\n"
+ "}";
+ #endif
++#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
++ QTest::newRow("assignment_expr_1") << "a = (b := 10)";
++ QTest::newRow("assignment_expr_2") << "a = [q for z in (1, 2, 3) if (q := 2*z)]";
++ QTest::newRow("positional_params") << "def foo(a, b, /, c, d, *, e): pass";
++#endif
+ }
+
+ void PyAstTest::testCorrectedFuncRanges()