Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
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 appveyor.yml
Original file line number Diff line number Diff line change
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
48 changes: 48 additions & 0 deletions pyls/plugins/jedi_rename.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2020 Palantir Technologies, Inc.
import logging

from pyls import hookimpl, uris, _utils

log = logging.getLogger(__name__)


@hookimpl
def pyls_rename(config, workspace, document, position, new_name): # pylint: disable=unused-argument
log.debug('Executing rename of %s to %s', document.word_at_position(position), new_name)
kwargs = _utils.position_to_jedi_linecolumn(document, position)
kwargs['new_name'] = new_name
try:
refactoring = document.jedi_script().rename(**kwargs)
except NotImplementedError:
raise Exception('No support for renaming in Python 2/3.5 with Jedi. '
'Consider using the rope_rename plugin instead')
log.debug('Finished rename: %s', refactoring.get_diff())

return {
'documentChanges': [
{
'textDocument': {
'uri': uris.uri_with(document.uri, path=file_path),
'version': workspace.get_document(document.uri).version,
},
'edits': [
{
'range': {
'start': {'line': 0, 'character': 0},
'end': {
'line': _num_lines(changed_file.get_new_code()),
'character': 0,
},
},
'newText': changed_file.get_new_code(),
}
],
}
for file_path, changed_file in refactoring.get_changed_files().items()
],
}


def _num_lines(file_contents):
'Count the number of lines in the given string.'
return len(file_contents.splitlines())
6 changes: 6 additions & 0 deletions pyls/plugins/rope_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
log = logging.getLogger(__name__)


@hookimpl
def pyls_settings():
# Default rope_rename to disabled
return {'plugins': {'rope_rename': {'enabled': False}}}


@hookimpl
def pyls_rename(config, workspace, document, position, new_name):
rope_config = config.settings(document_path=document.path).get('rope', {})
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
'jedi_hover = pyls.plugins.hover',
'jedi_highlight = pyls.plugins.highlight',
'jedi_references = pyls.plugins.references',
'jedi_rename = pyls.plugins.jedi_rename',
'jedi_signature_help = pyls.plugins.signature',
'jedi_symbols = pyls.plugins.symbols',
'mccabe = pyls.plugins.mccabe_lint',
Expand Down
21 changes: 21 additions & 0 deletions test/fixtures.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2017 Palantir Technologies, Inc.
import os
import sys
from mock import Mock
import pytest
Expand Down Expand Up @@ -50,3 +51,23 @@ def config(workspace): # pylint: disable=redefined-outer-name
@pytest.fixture
def doc(workspace): # pylint: disable=redefined-outer-name
return Document(DOC_URI, workspace, DOC)


@pytest.fixture
def temp_workspace_factory(workspace): # pylint: disable=redefined-outer-name
'''
Returns a function that creates a temporary workspace from the files dict.
The dict is in the format {"file_name": "file_contents"}
'''
def fn(files):
def create_file(name, content):
fn = os.path.join(workspace.root_path, name)
with open(fn, 'w') as f:
f.write(content)
workspace.put_document(uris.from_fs_path(fn), content)

for name, content in files.items():
create_file(name, content)
return workspace

return fn
48 changes: 48 additions & 0 deletions test/plugins/test_jedi_rename.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2020 Palantir Technologies, Inc.
import os
import sys

import pytest
from pyls import uris
from pyls.plugins.jedi_rename import pyls_rename
from pyls.workspace import Document

LT_PY36 = sys.version_info.major < 3 or (sys.version_info.major == 3 and sys.version_info.minor < 6)

DOC_NAME = 'test1.py'
DOC = '''class Test1():
pass

class Test2(Test1):
pass
'''


@pytest.fixture
def tmp_workspace(temp_workspace_factory):
return temp_workspace_factory({DOC_NAME: DOC})


@pytest.mark.skipif(LT_PY36, reason='Jedi refactoring isnt supported on Python 2.x/3.5')
def test_jedi_rename(tmp_workspace, config): # pylint: disable=redefined-outer-name
# rename the `Test1` class
position = {'line': 0, 'character': 6}
DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC_NAME))
doc = Document(DOC_URI, tmp_workspace)

result = pyls_rename(config, tmp_workspace, doc, position, 'ShouldBeRenamed')
assert len(result.keys()) == 1

changes = result.get('documentChanges')
assert len(changes) == 1
changes = changes[0]

assert changes.get('edits') == [
{
'range': {
'start': {'line': 0, 'character': 0},
'end': {'line': 5, 'character': 0},
},
'newText': 'class ShouldBeRenamed():\n pass\n\nclass Test2(ShouldBeRenamed):\n pass\n',
}
]
16 changes: 5 additions & 11 deletions test/plugins/test_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,11 @@


@pytest.fixture
def tmp_workspace(workspace):
def create_file(name, content):
fn = os.path.join(workspace.root_path, name)
with open(fn, 'w') as f:
f.write(content)
workspace.put_document(uris.from_fs_path(fn), content)

create_file(DOC1_NAME, DOC1)
create_file(DOC2_NAME, DOC2)

return workspace
def tmp_workspace(temp_workspace_factory):
return temp_workspace_factory({
DOC1_NAME: DOC1,
DOC2_NAME: DOC2,
})


def test_references(tmp_workspace): # pylint: disable=redefined-outer-name
Expand Down
11 changes: 2 additions & 9 deletions test/plugins/test_rope_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,8 @@ class Test2(Test1):


@pytest.fixture
def tmp_workspace(workspace):
def create_file(name, content):
fn = os.path.join(workspace.root_path, name)
with open(fn, "w") as f:
f.write(content)
workspace.put_document(uris.from_fs_path(fn), content)

create_file(DOC_NAME, DOC)
return workspace
def tmp_workspace(temp_workspace_factory):
return temp_workspace_factory({DOC_NAME: DOC})


def test_rope_rename(tmp_workspace, config): # pylint: disable=redefined-outer-name
Expand Down