Commit 06fca69a authored by Francis Herne's avatar Francis Herne

Merge branch '5.1'

parents 8f155990 e4aedbb2
......@@ -30,15 +30,31 @@ endif()
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.6 3.5 3.4)
find_package(PythonInterp 3.4.3 REQUIRED)
foreach(_PYTHON_V ${Python_ADDITIONAL_VERSIONS})
find_package(PythonInterp ${_PYTHON_V})
if ( PYTHONINTERP_FOUND )
break()
endif()
endforeach()
# Must unset before searching for libs, otherwise these are checked before the required version...
unset(Python_ADDITIONAL_VERSIONS)
find_package(PythonLibs ${PYTHON_VERSION_STRING} REQUIRED EXACT) # No, we don't support mismatched versions
configure_file( "${kdevpython_SOURCE_DIR}/kdevpythonversion.h.cmake" "${kdevpython_BINARY_DIR}/kdevpythonversion.h" @ONLY )
if ( (NOT PYTHON_LIBRARIES) OR "${PYTHON_VERSION_MINOR}" GREATER 6 )
if ( PYTHONINTERP_FOUND AND PYTHON_VERSION_STRING VERSION_GREATER "3.4.2" )
# Find libraries that match the found interpreter (mismatched versions not supported).
# This assumes libs are available for the newest Python version on the system.
# KDevelop should _always_ be built against the newest possible version, so notabug.
find_package(PythonLibs "${PYTHON_VERSION_STRING}" REQUIRED EXACT)
endif()
if ( NOT PYTHONLIBS_FOUND )
message(FATAL_ERROR "Python >= 3.4.3 but < 3.7 with --enable-shared is required to build kdev-python")
endif()
configure_file( "${kdevpython_SOURCE_DIR}/kdevpythonversion.h.cmake" "${kdevpython_BINARY_DIR}/kdevpythonversion.h" @ONLY )
find_package(Qt5 CONFIG REQUIRED Core Widgets Test)
find_package(KF5 REQUIRED I18n NewStuff ItemModels ThreadWeaver TextEditor KCMUtils)
find_package(KDevPlatform ${KDEVPLATFORM_VERSION} REQUIRED)
......
......@@ -38,6 +38,7 @@ while True:
# writes directly to stdout, so catch it ...
c.check_all()
output = output.getvalue()
output = output[:2**15]
stdout.write("{0:>10}".format(len(output)))
stdout.write(output)
......
......@@ -27,8 +27,6 @@
#include <interfaces/icore.h>
#include <QBoxLayout>
#include <QMimeType>
#include <QMimeDatabase>
#include <QFileSystemModel>
#include <QDialogButtonBox>
#include <QTreeView>
......@@ -40,12 +38,12 @@
#include <QDebug>
#include <QTemporaryFile>
#include <QStandardPaths>
#include <QDesktopServices>
#include <QIcon>
#include <QUrl>
#include <KMessageBox>
#include <KLocalizedString>
#include <KRun>
#include <KTextEditor/Document>
DocfileManagerWidget::DocfileManagerWidget(QWidget* parent)
......@@ -137,9 +135,9 @@ void DocfileManagerWidget::showSearchPaths()
void DocfileManagerWidget::openDocfilePath()
{
auto docfileDirectory = QUrl::fromLocalFile(docfilePath());
QMimeDatabase db;
KRun::runUrl(docfileDirectory, db.mimeTypeForUrl(docfileDirectory).name(), this);
if ( QDir(docfilePath()).exists() ) {
QDesktopServices::openUrl(QUrl::fromLocalFile(docfilePath()));
}
}
void DocfileManagerWidget::copyEditorContents()
......
......@@ -561,8 +561,16 @@ def id(obj):
"""Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value."""
return 0
def input(prompt = None):
"""Equivalent to eval(raw_input(prompt))."""
return None
"""
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
"""
return ""
def isinstance(obj, cls):
"""Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof."""
return True
......@@ -615,9 +623,6 @@ def property(fget = 0, fset = 0, fdel = 0, doc = 0):
def range(start = 0, stop = 0, step = 0):
"""This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops. The arguments must be plain integers."""
return [0]
def raw_input(prompt = ""):
""" The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that."""
return ""
def reduce(function, iterable, init = None):
"""Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value."""
return None
......
......@@ -129,18 +129,8 @@ class groupby(object):
""" x.next() -> the next value, or raise StopIteration """
return None
class ifilter(object):
""" ifilter(function or None, sequence) --> ifilter object
Return those items of sequence for which function(item) is true.
If function is None, return the items that are true. """
def next(self):
""" x.next() -> the next value, or raise StopIteration """
return None
class ifilterfalse(object):
""" ifilterfalse(function or None, sequence) --> ifilterfalse object
class filterfalse(object):
""" filterfalse(function or None, sequence) --> ifilterfalse object
Return those items of sequence for which function(item) is false.
If function is None, return the items that are false. """
......@@ -149,21 +139,8 @@ class ifilterfalse(object):
""" x.next() -> the next value, or raise StopIteration """
return None
class imap(object):
""" imap(func, *iterables) --> imap object
Make an iterator that computes the function using arguments from
each of the iterables. Like map() except that it returns
an iterator instead of a list and that it stops when the shortest
iterable is exhausted instead of filling in None for shorter
iterables. """
def next(self):
""" x.next() -> the next value, or raise StopIteration """
return None
class islice(object):
""" islice(iterable, [start,] stop [, step]) --> islice object
class slice(object):
""" slice(iterable, [start,] stop [, step]) --> islice object
Return an iterator whose next() method returns selected values from an
iterable. If start is specified, will skip all preceding elements;
......@@ -176,24 +153,10 @@ class islice(object):
""" x.next() -> the next value, or raise StopIteration """
return None
class izip(object):
""" izip(iter1 [,iter2 [...]]) --> izip object
Return a izip object whose .next() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .next()
method continues until the shortest iterable in the argument sequence
is exhausted and then it raises StopIteration. Works like the zip()
function but consumes less memory by returning an iterator instead of
a list. """
def next(self):
""" x.next() -> the next value, or raise StopIteration """
return None
class izip_longest(object):
""" izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object
class zip_longest(object):
""" zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object
Return an izip_longest object whose .next() method returns a tuple where
Return a zip_longest object whose .next() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .next()
method continues until the longest iterable in the argument sequence
is exhausted and then it raises StopIteration. When the shorter iterables
......
set(duchain_SRCS
declarations/functiondeclaration.cpp
types/nonetype.cpp
types/hintedtype.cpp
types/unsuretype.cpp
types/indexedcontainer.cpp
......
......@@ -24,6 +24,7 @@
#include "types/hintedtype.h"
#include "types/unsuretype.h"
#include "types/nonetype.h"
#include "types/indexedcontainer.h"
#include "contextbuilder.h"
#include "expressionvisitor.h"
......@@ -1226,7 +1227,6 @@ void DeclarationBuilder::assignToAttribute(AttributeAst* attrib, const Declarati
DUChainWriteLocker lock;
previousContext->createUse(dec->ownIndex(), editorFindRange(attrib, attrib));
}
else qCWarning(KDEV_PYTHON_DUCHAIN) << "No declaration created for " << attrib->attribute << "as parent is not a class";
closeInjectedContext();
}
......@@ -1526,7 +1526,7 @@ void DeclarationBuilder::visitFunctionDefinition( FunctionDefinitionAst* node )
type->setReturnType(currentType<AbstractType>());
}
if ( ! type->returnType() ) {
type->setReturnType(AbstractType::Ptr(new IntegralType(IntegralType::TypeVoid)));
type->setReturnType(AbstractType::Ptr(new NoneType()));
}
dec->setType(type);
}
......@@ -1710,7 +1710,7 @@ void DeclarationBuilder::adjustExpressionsForTypecheck(Python::ExpressionAst* ad
void DeclarationBuilder::visitReturn(ReturnAst* node)
{
static auto noneType = AbstractType::Ptr(new IntegralType(IntegralType::TypeVoid));
static auto noneType = AbstractType::Ptr(new NoneType());
if ( auto function = currentType<FunctionType>() ) {
// Statements with no explicit value return `None`.
......
......@@ -19,6 +19,7 @@
*/
#include "expressionvisitor.h"
#include "types/nonetype.h"
#include "types/indexedcontainer.h"
#include "declarations/functiondeclaration.h"
#include "pythonduchainexport.h"
......@@ -63,7 +64,7 @@ ExpressionVisitor::ExpressionVisitor(const DUContext* ctx)
if ( m_defaultTypes.isEmpty() ) {
m_defaultTypes.insert(NameConstantAst::True, AbstractType::Ptr(new IntegralType(IntegralType::TypeBoolean)));
m_defaultTypes.insert(NameConstantAst::False, AbstractType::Ptr(new IntegralType(IntegralType::TypeBoolean)));
m_defaultTypes.insert(NameConstantAst::None, AbstractType::Ptr(new IntegralType(IntegralType::TypeVoid)));
m_defaultTypes.insert(NameConstantAst::None, AbstractType::Ptr(new NoneType()));
}
Q_ASSERT(context());
Q_ASSERT(context()->topContext());
......
......@@ -881,9 +881,9 @@ void PyDUChainTest::testTypes_data()
QTest::newRow("funccall_string") << "def foo(): return 'a'; \ncheckme = foo();" << "str";
QTest::newRow("funccall_list") << "def foo(): return []; \ncheckme = foo();" << "list";
QTest::newRow("funccall_dict") << "def foo(): return {}; \ncheckme = foo();" << "dict";
QTest::newRow("funccall_no_return") << "def foo(): pass\ncheckme = foo()" << "void";
QTest::newRow("funccall_def_return") << "def foo(): return\ncheckme = foo()" << "void";
QTest::newRow("funccall_maybe_def_return") << "def foo():\n if False: return\n return 7\ncheckme = foo()" << "unsure (void, int)";
QTest::newRow("funccall_no_return") << "def foo(): pass\ncheckme = foo()" << "None";
QTest::newRow("funccall_def_return") << "def foo(): return\ncheckme = foo()" << "None";
QTest::newRow("funccall_maybe_def_return") << "def foo():\n if False: return\n return 7\ncheckme = foo()" << "unsure (None, int)";
QTest::newRow("tuple1") << "checkme, foo = 3, \"str\"" << "int";
QTest::newRow("tuple2") << "foo, checkme = 3, \"str\"" << "str";
......@@ -1362,7 +1362,7 @@ void PyDUChainTest::testFunctionHints_data()
QTest::addColumn<QString>("code");
QTest::addColumn<QString>("expectedType");
QTest::newRow("func_return_type") << "def myfun(arg) -> int: pass\ncheckme = myfun(\"3\")" << "unsure (void, int)";
QTest::newRow("func_return_type") << "def myfun(arg) -> int: pass\ncheckme = myfun(\"3\")" << "unsure (None, int)";
QTest::newRow("argument_type") << "def myfun(arg : int): return arg\ncheckme = myfun(foobar)" << "int";
QTest::newRow("argument_type_only_if_typeof") << "def myfun(arg : 3): return arg\ncheckme = myfun(foobar)" << "mixed";
}
......
/**
This file is part of KDevelop
Copyright (C) 2011 Sven Brauch <svenbrauch@googlemail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "nonetype.h"
#include <language/duchain/types/typesystemdata.h>
#include <language/duchain/types/typeregister.h>
using namespace KDevelop;
namespace Python {
REGISTER_TYPE(NoneType);
NoneType::NoneType() : IntegralType(createData<NoneType>())
{
d_func_dynamic()->setTypeClassId<NoneType>();
setDataType(TypeVoid);
}
NoneType::NoneType(const NoneType& rhs) : IntegralType(copyData<NoneType>(*rhs.d_func())) {}
NoneType::NoneType(IntegralTypeData& data) : IntegralType(data) {}
AbstractType* NoneType::clone() const {
return new NoneType(*this);
}
QString NoneType::toString() const { return QStringLiteral("None"); };
}
/**
This file is part of KDevelop
Copyright (C) 2017 Francis Herne <mail@flherne.uk>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received az copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef PYTHON_NONETYPE_H
#define PYTHON_NONETYPE_H
#include <language/duchain/types/integraltype.h>
#include "pythonduchainexport.h"
using namespace KDevelop;
namespace Python {
typedef IntegralTypeData NoneTypeData;
/**
* The only purpose of this class is to override IntegralType::toString().
* TODO: improve kdevplatform API to allow custom strings sanely.
*/
class KDEVPYTHONDUCHAIN_EXPORT NoneType: public IntegralType
{
public:
/// Default constructor
explicit NoneType();
/// Copy constructor. \param rhs type to copy
NoneType(const NoneType& rhs);
/// Constructor using raw data. \param data internal data.
explicit NoneType(IntegralTypeData& data);
AbstractType* clone() const override;
enum { Identity = 64 };
QString toString() const override;
};
}
#endif // PYTHON_NONETYPE_H
......@@ -62,7 +62,9 @@
"X-KDevelop-Interfaces": [
"ILanguageSupport"
],
"X-KDevelop-Language": "Python",
"X-KDevelop-Languages": [
"Python"
],
"X-KDevelop-Mode": "NoGUI",
"X-KDevelop-SupportedMimeTypes": [
"text/x-python"
......
......@@ -59,7 +59,7 @@ void PEP8KCModule::reset()
{
m_ui.enableErrors->setText(configGroup.readEntry("enableErrors", QString()));
m_ui.disableErrors->setText(configGroup.readEntry("disableErrors", pep8DefaultIgnoreErrors()));
m_ui.maxLineLength->setValue(configGroup.readEntry("maxLineLength", 80));
m_ui.maxLineLength->setValue(configGroup.readEntry("maxLineLength", 79));
m_ui.enableChecking->setChecked(configGroup.readEntry("pep8enabled", false));
}
......@@ -67,7 +67,7 @@ void PEP8KCModule::defaults()
{
m_ui.enableErrors->setText("");
m_ui.disableErrors->setText(pep8DefaultIgnoreErrors());
m_ui.maxLineLength->setValue(80);
m_ui.maxLineLength->setValue(79);
m_ui.enableChecking->setChecked(false);
}
......
......@@ -110,8 +110,8 @@ void StyleChecking::addErrorsToContext(const QVector<QString>& errors)
}
QString error = match.captured(4);
KDevelop::Problem* p = new KDevelop::Problem();
p->setFinalLocation(DocumentRange(document, KTextEditor::Range(lineno - 1, qMax(colno - 4, 0),
lineno - 1, colno + 4)));
p->setFinalLocation(DocumentRange(document, KTextEditor::Range(lineno - 1, qMax(colno - 1, 0),
lineno - 1, colno)));
p->setSource(KDevelop::IProblem::Preprocessor);
p->setSeverity(error.startsWith('W') ? KDevelop::IProblem::Hint : KDevelop::IProblem::Warning);
p->setDescription(i18n("PEP8 checker error: %1", error));
......@@ -133,6 +133,7 @@ void StyleChecking::processOutputStarted()
size_d = m_checkerProcess.read(10);
bool ok;
auto size = size_d.toInt(&ok);
auto origSize = size;
if ( !ok || size < 0 ) {
addSetupErrorToContext("Got invalid size: " + size_d);
m_mutex.unlock();
......@@ -142,11 +143,13 @@ void StyleChecking::processOutputStarted()
// read actual output
QByteArray buf;
QTimer t;
t.setSingleShot(true);
t.start(100);
while ( size > 0 && t.isActive() ) {
auto d = m_checkerProcess.read(size);
while ( size > 0 && t.remainingTime() > 0 ) {
auto d = m_checkerProcess.read(qMin(4096, size));
buf.append(d);
size -= d.size();
qDebug() << "remaining:" << size << d.size();
}
// process it
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment