diff --git a/rope/base/ast.py b/rope/base/ast.py index 67c35db47..b457e2367 100644 --- a/rope/base/ast.py +++ b/rope/base/ast.py @@ -3,15 +3,10 @@ from rope.base import fscommands -try: - unicode -except NameError: - unicode = str - def parse(source, filename=""): # NOTE: the raw string should be given to `compile` function - if isinstance(source, unicode): + if isinstance(source, str): source = fscommands.unicode_to_file_data(source) if b"\r" in source: source = source.replace(b"\r\n", b"\n").replace(b"\r", b"\n") diff --git a/rope/base/change.py b/rope/base/change.py index cf1d9f3be..eadb0c561 100644 --- a/rope/base/change.py +++ b/rope/base/change.py @@ -2,9 +2,11 @@ import difflib import os import time +from typing import Union import rope.base.fscommands -from rope.base import taskhandle, exceptions, utils +from rope.base import exceptions, taskhandle, utils +from rope.base.fscommands import FileContent class Change: @@ -329,11 +331,15 @@ def _get_fscommands(self, resource): return self.direct_commands return self.fscommands - def write_file(self, resource, contents): - data = rope.base.fscommands.unicode_to_file_data( - contents, - newlines=resource.newlines, - ) + def write_file(self, resource, contents: Union[str, FileContent]): + data: FileContent + if not isinstance(contents, bytes): + data = rope.base.fscommands.unicode_to_file_data( + contents, + newlines=resource.newlines, + ) + else: + data = contents fscommands = self._get_fscommands(resource) fscommands.write(resource.real_path, data) for observer in list(self.project.observers): diff --git a/rope/base/fscommands.py b/rope/base/fscommands.py index bf928eaf5..f69b172e7 100644 --- a/rope/base/fscommands.py +++ b/rope/base/fscommands.py @@ -12,11 +12,10 @@ import subprocess import rope.base.utils.pycompat as pycompat +import typing -try: - unicode -except NameError: - unicode = str + +FileContent = typing.NewType("FileContent", bytes) def create_fscommands(root): @@ -214,19 +213,18 @@ def _execute(args, cwd=None): return process.returncode -def unicode_to_file_data(contents, encoding=None, newlines=None): - if not isinstance(contents, unicode): - return contents +def unicode_to_file_data(contents: str, encoding=None, newlines=None) -> FileContent: + assert isinstance(contents, str) if newlines and newlines != "\n": contents = contents.replace("\n", newlines) if encoding is None: encoding = read_str_coding(contents) if encoding is not None: - return contents.encode(encoding) + return FileContent(contents.encode(encoding)) try: - return contents.encode() + return FileContent(contents.encode()) except UnicodeEncodeError: - return contents.encode("utf-8") + return FileContent(contents.encode("utf-8")) def file_data_to_unicode(data, encoding=None): @@ -242,7 +240,7 @@ def file_data_to_unicode(data, encoding=None): def _decode_data(data, encoding): - if isinstance(data, unicode): + if isinstance(data, str): return data if encoding is None: encoding = read_str_coding(data) diff --git a/rope/base/pyobjects.py b/rope/base/pyobjects.py index f0929e9cc..820fc2d1b 100644 --- a/rope/base/pyobjects.py +++ b/rope/base/pyobjects.py @@ -1,4 +1,5 @@ -from rope.base.fscommands import _decode_data +from typing import Optional + from rope.base import ast, exceptions, utils @@ -224,13 +225,14 @@ def get_module(self): current_object = current_object.parent return current_object - def get_doc(self): + def get_doc(self) -> Optional[str]: if len(self.get_ast().body) > 0: expr = self.get_ast().body[0] if isinstance(expr, ast.Expr) and isinstance(expr.value, ast.Str): docstring = expr.value.s - coding = self.get_module().coding - return _decode_data(docstring, coding) + assert isinstance(docstring, str) + return docstring + return None def _get_defined_objects(self): if self.defineds is None: diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index 2ab301910..5f6bf9271 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -17,11 +17,6 @@ ) from rope.base.utils import pycompat -try: - unicode -except NameError: - unicode = str - class PyFunction(pyobjects.PyFunction): def __init__(self, pycore, ast_node, parent): @@ -204,7 +199,7 @@ def _init_source(self, pycore, source_code, resource): source_bytes = resource.read_bytes() source_code, _ = fscommands.file_data_to_unicode(source_bytes) else: - if isinstance(source_code, unicode): + if isinstance(source_code, str): source_bytes = fscommands.unicode_to_file_data(source_code) else: source_bytes = source_code diff --git a/ropetest/contrib/codeassisttest.py b/ropetest/contrib/codeassisttest.py index 8d09e08f2..7d07bc2a0 100644 --- a/ropetest/contrib/codeassisttest.py +++ b/ropetest/contrib/codeassisttest.py @@ -16,11 +16,6 @@ ) from ropetest import testutils -try: - unicode -except NameError: - unicode = str - class CodeAssistTest(unittest.TestCase): def setUp(self): @@ -731,7 +726,7 @@ def test_get_pydoc_unicode(self): def foo(): u"юникод-объект"''') doc = get_doc(self.project, src, src.index("foo") + 1) - self.assertTrue(isinstance(doc, unicode)) + self.assertTrue(isinstance(doc, str)) self.assertTrue("юникод-объект" in doc) def test_get_pydoc_utf8_bytestring(self): @@ -740,7 +735,7 @@ def test_get_pydoc_utf8_bytestring(self): def foo(): "байтстринг"''') doc = get_doc(self.project, src, src.index("foo") + 1) - self.assertTrue(isinstance(doc, unicode)) + self.assertTrue(isinstance(doc, str)) self.assertTrue("байтстринг" in doc) def test_get_pydoc_for_functions(self):