Skip to content

Commit

Permalink
Merge pull request #738 from python-rope/implement-os-pathlike
Browse files Browse the repository at this point in the history
Implement os.PathLike on Resource
  • Loading branch information
lieryan authored Jan 3, 2024
2 parents f21bbd0 + e747c39 commit 9d79c9a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- #733 skip directories with perm error when building autoimport index (@MrBago)
- #722, #723 Remove site-packages from packages search tree (@tkrabel)
- #738 Implement os.PathLike on Resource (@lieryan)

# Release 1.11.0

Expand Down
30 changes: 18 additions & 12 deletions rope/base/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from rope.base import change, exceptions, fscommands


class Resource:
class Resource(os.PathLike):
"""Represents files and folders in a project"""

def __init__(self, project, path):
Expand All @@ -49,6 +49,10 @@ def __repr__(self):
hex(id(self)),
)

def __fspath__(self) -> str:
"""Return the file system path of this resource"""
return self.project._get_resource_path(self.path)

def move(self, new_location):
"""Move resource to `new_location`"""
self._perform_change(
Expand All @@ -60,22 +64,25 @@ def remove(self):
"""Remove resource from the project"""
self._perform_change(change.RemoveResource(self), "Removing <%s>" % self.path)

def is_dir(self):
"""Alias for `is_folder()`"""

def is_folder(self):
"""Return true if the resource is a folder"""
"""Return True if the resource is a Folder"""

def create(self):
"""Create this resource"""

def exists(self):
return os.path.exists(self.real_path)
return os.path.exists(self)

@property
def parent(self):
parent = "/".join(self.path.split("/")[0:-1])
return self.project.get_folder(parent)

@property
def path(self):
def path(self) -> str:
"""Return the path of this resource relative to the project root
The path is the list of parent directories separated by '/' followed
Expand All @@ -84,19 +91,18 @@ def path(self):
return self._path

@property
def name(self):
def name(self) -> str:
"""Return the name of this resource"""
return self.path.split("/")[-1]

@property
def real_path(self):
"""Return the file system path of this resource"""
return self.project._get_resource_path(self.path)
def real_path(self) -> str:
return os.fspath(self)

@property
def pathlib(self):
def pathlib(self) -> Path:
"""Return the file as a pathlib path."""
return Path(self.real_path)
return Path(self)

def __eq__(self, obj):
return self.__class__ == obj.__class__ and self.path == obj.path
Expand Down Expand Up @@ -135,7 +141,7 @@ def read_bytes(self):
DeprecationWarning,
stacklevel=2,
)
with open(self.real_path, "rb") as handle:
with open(self, "rb") as handle:
return handle.read()
return self.project.fscommands.read(self.real_path)

Expand Down Expand Up @@ -165,7 +171,7 @@ def is_folder(self):
def get_children(self):
"""Return the children of this folder"""
try:
children = os.listdir(self.real_path)
children = os.listdir(self)
except OSError:
return []
result = []
Expand Down
8 changes: 3 additions & 5 deletions rope/contrib/autoimport/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def __init__(
autoimport = AutoImport(..., memory=True)
"""
self.project = project
project_package = get_package_tuple(Path(project.root.real_path), project)
project_package = get_package_tuple(project.root.pathlib, project)
assert project_package is not None
assert project_package.path is not None
self.project_package = project_package
Expand Down Expand Up @@ -175,9 +175,7 @@ def calculate_project_hash(data: str) -> str:
f"file:rope-{project_hash}:?mode=memory&cache=shared", uri=True
)
else:
return sqlite3.connect(
str(Path(project.ropefolder.real_path) / "autoimport.db")
)
return sqlite3.connect(project.ropefolder.pathlib / "autoimport.db")

@property
def connection(self):
Expand Down Expand Up @@ -627,7 +625,7 @@ def _resource_to_module(
) -> ModuleFile:
assert self.project_package.path
underlined = underlined if underlined else self.underlined
resource_path: Path = Path(resource.real_path)
resource_path: Path = resource.pathlib
# The project doesn't need its name added to the path,
# since the standard python file layout accounts for that
# so we set add_package_name to False
Expand Down
13 changes: 13 additions & 0 deletions ropetest/projecttest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from rope.base.libutils import path_to_resource
from rope.base.project import NoProject, Project, _realpath
from rope.base.resourceobserver import FilteredResourceObserver
from rope.base.resources import File, Folder
from ropetest import testutils


Expand Down Expand Up @@ -610,6 +611,18 @@ def test_multi_source_folders2(self):
self.assertEqual(2, len(source_folders))
self.assertTrue(self.project.root in source_folders and src in source_folders)

def test_folder_is_pathlike(self):
resource = self.project.root.create_folder("src")
self.assertIsInstance(resource, Folder)

self.assertIsInstance(os.fspath(resource), str)

def test_file_is_pathlike(self):
resource = self.project.root.create_file("mod.py")
self.assertIsInstance(resource, File)

self.assertIsInstance(os.fspath(resource), str)


class ResourceObserverTest(unittest.TestCase):
def setUp(self):
Expand Down

0 comments on commit 9d79c9a

Please sign in to comment.