Skip to content

Commit 0df4f28

Browse files
authored
Merge pull request #502 from asclepiusaka/issue-451
Fix mkdir so that no create_bucket is called when one already exists
2 parents 562ed04 + d865d40 commit 0df4f28

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

s3fs/core.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,15 @@ async def _find(self, path, maxdepth=None, withdirs=None, detail=False, prefix="
684684

685685
async def _mkdir(self, path, acl="", create_parents=True, **kwargs):
686686
path = self._strip_protocol(path).rstrip("/")
687+
if not path:
688+
raise ValueError
687689
bucket, key, _ = self.split_path(path)
688-
if not key or (create_parents and not await self._exists(bucket)):
690+
if await self._exists(bucket):
691+
if not key:
692+
# requested to create bucket, but bucket already exist
693+
raise FileExistsError
694+
# else: # do nothing as bucket is already created.
695+
elif not key or create_parents:
689696
if acl and acl not in buck_acls:
690697
raise ValueError("ACL not in %s", buck_acls)
691698
try:
@@ -705,7 +712,7 @@ async def _mkdir(self, path, acl="", create_parents=True, **kwargs):
705712
except ParamValidationError as e:
706713
raise ValueError("Bucket create failed %r: %s" % (bucket, e))
707714
else:
708-
# raises if bucket doesn't exist, but doesn't write anything
715+
# raises if bucket doesn't exist and doesn't get create flag.
709716
await self._ls(bucket)
710717

711718
mkdir = sync_wrapper(_mkdir)

s3fs/tests/test_s3fs.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,32 @@ def test_mkdir(s3):
575575
assert bucket in s3.ls("/")
576576

577577

578+
def test_mkdir_existing_bucket(s3):
579+
# mkdir called on existing bucket should be no-op and not calling create_bucket
580+
# creating a s3 bucket
581+
bucket = "test1_bucket"
582+
s3.mkdir(bucket)
583+
assert bucket in s3.ls("/")
584+
# a second call.
585+
with pytest.raises(FileExistsError):
586+
s3.mkdir(bucket)
587+
588+
589+
def test_mkdir_bucket_and_key_1(s3):
590+
bucket = "test1_bucket"
591+
file = bucket + "/a/b/c"
592+
s3.mkdir(file, create_parents=True)
593+
assert bucket in s3.ls("/")
594+
595+
596+
def test_mkdir_bucket_and_key_2(s3):
597+
bucket = "test1_bucket"
598+
file = bucket + "/a/b/c"
599+
with pytest.raises(FileNotFoundError):
600+
s3.mkdir(file, create_parents=False)
601+
assert bucket not in s3.ls("/")
602+
603+
578604
def test_mkdir_region_name(s3):
579605
bucket = "test2_bucket"
580606
s3.mkdir(bucket, region_name="eu-central-1")
@@ -598,6 +624,28 @@ def test_makedirs(s3):
598624
assert bucket in s3.ls("/")
599625

600626

627+
def test_makedirs_existing_bucket(s3):
628+
bucket = "test_makedirs_bucket"
629+
s3.mkdir(bucket)
630+
assert bucket in s3.ls("/")
631+
test_file = bucket + "/a/b/c/file"
632+
# no-op, and no error.
633+
s3.makedirs(test_file)
634+
635+
636+
def test_makedirs_pure_bucket_exist_ok(s3):
637+
bucket = "test1_bucket"
638+
s3.mkdir(bucket)
639+
s3.makedirs(bucket, exist_ok=True)
640+
641+
642+
def test_makedirs_pure_bucket_error_on_exist(s3):
643+
bucket = "test1_bucket"
644+
s3.mkdir(bucket)
645+
with pytest.raises(FileExistsError):
646+
s3.makedirs(bucket, exist_ok=False)
647+
648+
601649
def test_bulk_delete(s3):
602650
with pytest.raises(FileNotFoundError):
603651
s3.rm(["nonexistent/file"])
@@ -1693,7 +1741,6 @@ def test_requester_pays(s3):
16931741
fn = test_bucket_name + "/myfile"
16941742
s3 = S3FileSystem(requester_pays=True, client_kwargs={"endpoint_url": endpoint_uri})
16951743
assert s3.req_kw["RequestPayer"] == "requester"
1696-
s3.mkdir(test_bucket_name)
16971744
s3.touch(fn)
16981745
with s3.open(fn, "rb") as f:
16991746
assert f.req_kw["RequestPayer"] == "requester"

0 commit comments

Comments
 (0)