Skip to content

Commit

Permalink
fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
berquist committed Jun 9, 2024
1 parent ca94b98 commit 6f181e6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 13 deletions.
14 changes: 12 additions & 2 deletions exdir/core/exdir_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,24 @@ def __init__(self, directory, mode=None, allow_remove=False,
else:
self.io_mode = OpenMode.READ_WRITE

parent_path = pathlib.PurePosixPath("")
super().__init__(
root_directory=directory,
parent_path=pathlib.PurePosixPath(""),
parent_path=parent_path,
object_name="",
file=self
)

already_exists = directory.exists()
# If we have name validation, we need to check for uniqueness. The
# directory may exist but with a different case, in which case we
# don't want to say that is already exists so that it matches the
# correct checks for the requested mode.
if name_validation != validation.none:
already_exists = utils.path.case_insensitive_path_already_exists(
directory.parent, directory.name, directory.name.lower()
)
else:
already_exists = directory.exists()
if already_exists:
if not exob.is_nonraw_object_directory(directory):
raise RuntimeError(
Expand Down
27 changes: 16 additions & 11 deletions exdir/core/validation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from enum import Enum
import os
import os.path
import sys
from tempfile import NamedTemporaryFile
from unicodedata import category
from exdir.utils.path import case_insensitive_path_already_exists
from . import constants as exob

# `ntpath.isreserved` forbids ASCII control characters
Expand Down Expand Up @@ -108,6 +109,7 @@ def strict(parent_path, name):
_assert_unique(parent_path, name)
_assert_valid_characters(name)


def thorough(parent_path, name):
_assert_nonempty(parent_path, name)
_assert_nonreserved(name)
Expand All @@ -118,20 +120,14 @@ def thorough(parent_path, name):
name_lower = name_str.lower()
_assert_valid_characters(name_lower)

# TODO investigate replacing with sys.platform
# Use _assert_unique if we're already on Windows or macOS, because it
# is much faster than the test below after the first check for
# filesystem case-sensitivity.
if not _is_fs_case_sensitive(parent_path):
# use _assert_unique if we're already on Windows, because it is much faster
# than the test below
_assert_unique(parent_path, name)
return

# os.listdir is much faster here than os.walk or parent_path.iterdir
for item in os.listdir(str(parent_path)):
if name_lower == item.lower():
raise RuntimeError(
"A directory with name (case independent) '{}' already exists "
" and cannot be made according to the naming rule 'thorough'.".format(name)
)
_assert_unique_slow(parent_path, name, name_lower)


def none(parent_path, name):
Expand All @@ -146,3 +142,12 @@ def _is_fs_case_sensitive(source_dir=None):
"case_sensitive",
not os.path.exists(tmp_file.name.lower()))
return _is_fs_case_sensitive.case_sensitive


def _assert_unique_slow(parent_path, name, name_lower):
if case_insensitive_path_already_exists(parent_path, name, name_lower):
raise RuntimeError(
"A directory with name (case independent) '{}' already exists "
" and cannot be made according to the naming rule 'thorough'.".format(name)
)

13 changes: 13 additions & 0 deletions exdir/utils/path.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import pathlib


Expand All @@ -22,3 +23,15 @@ def remove_root(name):
if path.is_absolute():
path = path.relative_to(path.root)
return path


def path_already_exists_case_insensitive(parent_path, name, name_lower):
# os.listdir is much faster here than os.walk or parent_path.iterdir
for item in os.listdir(str(parent_path)):
if name_lower == item.lower():
return True
return False


# def path_already_exists_different_case(parent_path, name):

1 change: 1 addition & 0 deletions tests/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def test_validate_name_thorough(setup_teardown_folder):
f.close()

with pytest.raises(RuntimeError):
breakpoint()
File(setup_teardown_folder[0] / "Test.exdir", name_validation=fv.thorough)
with pytest.raises(NameError):
File(setup_teardown_folder[0] / "tes#.exdir", name_validation=fv.thorough)
Expand Down

0 comments on commit 6f181e6

Please sign in to comment.