Skip to content

Commit

Permalink
Merge from 4.x: PR #12792
Browse files Browse the repository at this point in the history
Fixes #12572
Fixes #12333
  • Loading branch information
ccordoba12 committed Jun 5, 2020
2 parents 2135228 + 06edb40 commit 6cf0ffe
Show file tree
Hide file tree
Showing 49 changed files with 659 additions and 304 deletions.
6 changes: 4 additions & 2 deletions .pep8speaks.yml
@@ -1,4 +1,6 @@
# File : .pep8speaks.yml

scanner:
diff_only: True # Errors caused by only the patch are shown
linter: pycodestyle

pycodestyle:
exclude: external-deps
4 changes: 2 additions & 2 deletions binder/environment.yml
Expand Up @@ -15,12 +15,12 @@ dependencies:
- diff-match-patch >=20181111
- intervaltree
- ipython >=4.0
- jedi =0.15.2
- jedi =0.17.0
- keyring
- nbconvert >=4.0
- numpydoc >=0.6.0
- paramiko >=2.4.0
- parso =0.5.2
- parso =0.7.0
- pexpect >=4.4.0
- pickleshare >=0.4
- psutil >=5.3
Expand Down
4 changes: 2 additions & 2 deletions external-deps/python-language-server/.circleci/config.yml
Expand Up @@ -14,7 +14,7 @@ jobs:

python3-test:
docker:
- image: "python:3.5-stretch"
- image: "python:3.6-stretch"
steps:
- checkout
# To test Jedi environments
Expand All @@ -35,7 +35,7 @@ jobs:

publish:
docker:
- image: "python:3.5-stretch"
- image: "python:3.6-stretch"
steps:
- checkout
- run: ./scripts/circle/pypi.sh
Expand Down
4 changes: 2 additions & 2 deletions external-deps/python-language-server/.gitrepo
Expand Up @@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/palantir/python-language-server.git
branch = develop
commit = fdb8b3dbc5df7d12729d135932bf2264e0883061
parent = 0798ff6e51f6d1c353b8278469a32adab54b874f
commit = 9b5cb2197405b2290161deb2abd8e2b139a53691
parent = dbb0398cd7e309e6de7a7740c57a03ecbb26ac11
method = merge
cmdver = 0.4.1
4 changes: 4 additions & 0 deletions external-deps/python-language-server/README.rst
Expand Up @@ -72,6 +72,10 @@ To enable pydocstyle for linting docstrings add the following setting in your LS
"pyls.plugins.pydocstyle.enabled": true
```

See `vscode-client/package.json`_ for the full set of supported configuration options.

.. _vscode-client/package.json: vscode-client/package.json

Language Server Features
------------------------

Expand Down
4 changes: 2 additions & 2 deletions external-deps/python-language-server/appveyor.yml
Expand Up @@ -6,8 +6,8 @@ environment:
PYTHON_VERSION: "2.7.15"
PYTHON_ARCH: "64"

- PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.7"
- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.8"
PYTHON_ARCH: "64"

matrix:
Expand Down
25 changes: 20 additions & 5 deletions external-deps/python-language-server/pyls/_utils.py
@@ -1,5 +1,4 @@
# Copyright 2017 Palantir Technologies, Inc.
from distutils.version import LooseVersion
import functools
import inspect
import logging
Expand Down Expand Up @@ -140,18 +139,34 @@ def format_docstring(contents):
"""
contents = contents.replace('\t', u'\u00A0' * 4)
contents = contents.replace(' ', u'\u00A0' * 2)
if LooseVersion(JEDI_VERSION) < LooseVersion('0.15.0'):
contents = contents.replace('*', '\\*')
return contents


def clip_column(column, lines, line_number):
# Normalise the position as per the LSP that accepts character positions > line length
# https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#position
"""
Normalise the position as per the LSP that accepts character positions > line length
https://microsoft.github.io/language-server-protocol/specification#position
"""
max_column = len(lines[line_number].rstrip('\r\n')) if len(lines) > line_number else 0
return min(column, max_column)


def position_to_jedi_linecolumn(document, position):
"""
Convert the LSP format 'line', 'character' to Jedi's 'line', 'column'
https://microsoft.github.io/language-server-protocol/specification#position
"""
code_position = {}
if position:
code_position = {'line': position['line'] + 1,
'column': clip_column(position['character'],
document.lines,
position['line'])}
return code_position


if os.name == 'nt':
import ctypes

Expand Down
Expand Up @@ -15,6 +15,7 @@
('ignore', 'plugins.pycodestyle.ignore', list),
('max-line-length', 'plugins.pycodestyle.maxLineLength', int),
('select', 'plugins.pycodestyle.select', list),
('aggressive', 'plugins.pycodestyle.aggressive', int),
]


Expand Down
7 changes: 7 additions & 0 deletions external-deps/python-language-server/pyls/lsp.py
Expand Up @@ -24,6 +24,13 @@ class CompletionItemKind(object):
Color = 16
File = 17
Reference = 18
Folder = 19
EnumMember = 20
Constant = 21
Struct = 22
Event = 23
Operator = 24
TypeParameter = 25


class DocumentHighlightKind(object):
Expand Down
Expand Up @@ -57,6 +57,7 @@ def _autopep8_config(config):
'ignore': settings.get('ignore'),
'max_line_length': settings.get('maxLineLength'),
'select': settings.get('select'),
'aggressive': settings.get('aggressive'),
}

# Filter out null options
Expand Down
@@ -1,16 +1,18 @@
# Copyright 2017 Palantir Technologies, Inc.
import logging
from pyls import hookimpl, uris
from pyls import hookimpl, uris, _utils

log = logging.getLogger(__name__)


@hookimpl
def pyls_definitions(config, document, position):
settings = config.plugin_settings('jedi_definition')
definitions = document.jedi_script(position).goto_assignments(
code_position = _utils.position_to_jedi_linecolumn(document, position)
definitions = document.jedi_script().goto(
follow_imports=settings.get('follow_imports', True),
follow_builtin_imports=settings.get('follow_builtin_imports', True))
follow_builtin_imports=settings.get('follow_builtin_imports', True),
**code_position)

return [
{
Expand Down
17 changes: 11 additions & 6 deletions external-deps/python-language-server/pyls/plugins/flake8_lint.py
Expand Up @@ -58,11 +58,10 @@ def run_flake8(args):
cmd = ['python', '-m', 'flake8']
cmd.extend(args)
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
stderr = p.stderr.read().decode()
(stdout, stderr) = p.communicate()
if stderr:
log.error("Error while running flake8 '%s'", stderr)
stdout = p.stdout
return stdout.read().decode()
log.error("Error while running flake8 '%s'", stderr.decode())
return stdout.decode()


def build_args(options, doc_path):
Expand Down Expand Up @@ -119,10 +118,16 @@ def parse_stdout(document, stdout):
diagnostics = []
lines = stdout.splitlines()
for raw_line in lines:
parsed_line = re.match(r'(.*):(\d*):(\d*): (\w*) (.*)', raw_line).groups()
if not parsed_line or len(parsed_line) != 5:
parsed_line = re.match(r'(.*):(\d*):(\d*): (\w*) (.*)', raw_line)
if not parsed_line:
log.debug("Flake8 output parser can't parse line '%s'", raw_line)
continue

parsed_line = parsed_line.groups()
if len(parsed_line) != 5:
log.debug("Flake8 output parser can't parse line '%s'", raw_line)
continue

_, line, character, code, msg = parsed_line
line = int(line) - 1
character = int(character) - 1
Expand Down
@@ -1,13 +1,14 @@
# Copyright 2017 Palantir Technologies, Inc.
import logging
from pyls import hookimpl, lsp
from pyls import hookimpl, lsp, _utils

log = logging.getLogger(__name__)


@hookimpl
def pyls_document_highlight(document, position):
usages = document.jedi_script(position).usages()
code_position = _utils.position_to_jedi_linecolumn(document, position)
usages = document.jedi_script().get_references(**code_position)

def is_valid(definition):
return definition.line is not None and definition.column is not None
Expand Down
71 changes: 34 additions & 37 deletions external-deps/python-language-server/pyls/plugins/hover.py
@@ -1,5 +1,5 @@
# Copyright 2017 Palantir Technologies, Inc.
from distutils.version import LooseVersion

import logging

from pyls import hookimpl, _utils
Expand All @@ -9,43 +9,40 @@

@hookimpl
def pyls_hover(document, position):
definitions = document.jedi_script(position).goto_definitions()
code_position = _utils.position_to_jedi_linecolumn(document, position)
definitions = document.jedi_script().infer(**code_position)
word = document.word_at_position(position)

if LooseVersion(_utils.JEDI_VERSION) >= LooseVersion('0.15.0'):
# Find first exact matching definition
definition = next((x for x in definitions if x.name == word), None)

# Ensure a definition is used if only one is available
# even if the word doesn't match. An example of this case is 'np'
# where 'numpy' doesn't match with 'np'. Same for NumPy ufuncs
if len(definitions) == 1:
definition = definitions[0]

if not definition:
return {'contents': ''}

# raw docstring returns only doc, without signature
doc = _utils.format_docstring(definition.docstring(raw=True))

# Find first exact matching signature
signature = next((x.to_string() for x in definition.get_signatures() if x.name == word), '')

contents = []
if signature:
contents.append({
'language': 'python',
'value': signature,
})
if doc:
contents.append(doc)
if not contents:
return {'contents': ''}
return {'contents': contents}
else:
# Find an exact match for a completion
for d in definitions:
if d.name == word:
return {'contents': _utils.format_docstring(d.docstring()) or ''}
# Find first exact matching definition
definition = next((x for x in definitions if x.name == word), None)

# Ensure a definition is used if only one is available
# even if the word doesn't match. An example of this case is 'np'
# where 'numpy' doesn't match with 'np'. Same for NumPy ufuncs
if len(definitions) == 1:
definition = definitions[0]

if not definition:
return {'contents': ''}

# raw docstring returns only doc, without signature
doc = _utils.format_docstring(definition.docstring(raw=True))

# Find first exact matching signature
signature = next((x.to_string() for x in definition.get_signatures()
if x.name == word), '')

contents = []
if signature:
contents.append({
'language': 'python',
'value': signature,
})

if doc:
contents.append(doc)

if not contents:
return {'contents': ''}

return {'contents': contents}

0 comments on commit 6cf0ffe

Please sign in to comment.