# Os.path.isempty() & pathlib.Path.is\_empty()

**URL:** <https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337>\
**Category:** Ideas\
**Created:** [April 5, 2024, 2:28pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337 "2024-04-05T14:28:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 5, 2024, 2:28pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/1 "2024-04-05T14:28:30Z")

</div>

Currently there’s no way to safely delete or overwrite a file or folder without losing data.

I propose a function that allows you to check for this:

```python
def isempty(path: StrOrBytesPath, *, follow_symlinks: bool = True) -> bool:
    """Test whether a file or directory is empty."""
    if not follow_symlinks and (islink(path) or isjunction(path)):
        return True

    if isfile(path):
        return not getsize(path)

    if not isdir(path):
        return True

    return not listdir(path)

```

Additionally `check_empty` parameter could be added to functions that delete / overwrite files.  
Raising a FileNotEmptyError or returning False when it’s not empty.

Not empty:

- A directory containing a file or subdirectory (excluding `.` & `..`)
- A non zero-byte file

Empty:

- A directory containing no files nor subdirectories (excluding `.` & `..`)
- A zero-byte file
- A junction (if follow\_symlinks is disabled)
- A symlink (if follow\_symlinks is disabled)

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [April 5, 2024, 2:34pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/2 "2024-04-05T14:34:39Z")

</div>

Why don’t you put these helper functions into a PyPI package and see if other people find them useful.

Personally I have never needed to check like this before deleting stuff.

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [April 5, 2024, 2:35pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/3 "2024-04-05T14:35:08Z")

</div>

Similar to your last suggestion, this is a pretty application-specific function. In addition to the general objection you have already seen in the previous discussion, for this suggestion there are a few opinions where we can disagree about, most notably, I wouldn’t consider a directory only containing (an?) empty file to be save to delete. These are decisions every application has to make on their own, and I don’t think the python stdlib should provide an opinion on this.

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 5, 2024, 3:07pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/4 "2024-04-05T15:07:48Z")

</div>

> Why don’t you put these helper functions into a PyPI package and see if other people find them useful.

I would first like to finalise the details.

> Personally I have never needed to check like this before deleting stuff.

In an interactive program, you can delete such files without asking for confirmation.

> There are a few opinions where we can disagree about, most notably, I wouldn’t consider a directory only containing (an?) empty file to be save to delete. These are decisions every application has to make on their own, and I don’t think the python stdlib should provide an opinion on this.

OK, updated the implementation.

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [April 5, 2024, 3:10pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/5 "2024-04-05T15:10:08Z")

</div>

> [@Nineteendo](#):
>
> I would first like to finalise the details.

I had assumed that this is somthing that you are using in an application and therefore know the details.

Are you guessing at a needed function rather then solving an actual use-case you have?  
That is not productive use of any ones time (as proved by academic research).

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 5, 2024, 3:23pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/6 "2024-04-05T15:23:57Z")

</div>

I was using a similar function in the old file manager I wrote, but I wasn’t happy about the interface library it’s built on, so now I’m redesigning everything from scratch. At the moment, nothing is final.

I was simply wondering if these functions could be useful for other people too.

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [April 5, 2024, 3:54pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/7 "2024-04-05T15:54:44Z")

</div>

> [@Nineteendo](#):
>
> OK, updated the implementation.

That wasn’t the point. You are writing an application. You have to make these decisions. Think about them, potentially asks users, make a survey of what other programs do, etc… If there is an overwhelming agreement between these factors, that is ofcourse a clear decision to make. But if that isn’t the case (which I strongly suspect), then they don’t belong in the stdlib and instead each application should make their own decisions.

> [@Nineteendo](#):
>
> I would first like to finalise the details.

Great! Do that. This isn’t the correct place for such discussions. This is about adding stuff to the stdlib, not designing a third party library. Look at something like `platformdirs`. They also have to make these kinds of opinionated decisions. Once they have made decisions, one can discuss adding it to the stdlib (which was recently suggested, not clear if that is still in the works). But trying to discuss multiple layers at the same time (“how should this function behave”, “is this function useful”, “does it belong in the stdlib”, “where does it belong”) is not going to lead to a productive result. If you nail down at the very least the first point and are willing to defend your decisions (preferably with a well formulated pre-PEP), then it might make sense to discuss whether they belong in the stdlib.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [April 5, 2024, 5:03pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/8 "2024-04-05T17:03:06Z")

</div>

> [@Nineteendo](#):
>
> “No data”:
> 
> - A directory containing an empty file
> - An empty directory
> - An empty file
> - A hardlink
> - A junction
> - A symlink

That is a rather bizarre definition of “no data”. This does NOT belong in the stdlib; it is tied very closely to your specific needs and belongs in your application.

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 5, 2024, 5:25pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/9 "2024-04-05T17:25:34Z")

</div>

I modified this list 2 hours ago, because MegaIng didn’t agree with me:

- An empty directory
- An empty file
- A hardlink (with the second implementation)
- A junction
- A symlink

---

<div class="post-metadata">

**Author:** ![jamestwebber](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jamestwebber/32/12799_2.png) [@jamestwebber](https://discuss.python.org/u/jamestwebber)\
**Post date:** [April 5, 2024, 6:00pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/10 "2024-04-05T18:00:09Z")

</div>

> [@Nineteendo](#):
>
> I modified this list 2 hours ago, because MegaIng didn’t agree with me:

I think you’re missing the point. There isn’t a “right answer” that will make people suddenly agree with this proposal. The correct behavior is application-specific and therefore the function is not appropriate for the standard library.

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 5, 2024, 7:31pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/11 "2024-04-05T19:31:17Z")

</div>

I believe it makes more sense the other way around: `isempty`.  
I also removed the hardlinks implementation as it was subjective.  
Is this new classification of empty files and directories more intuitive?

- A directory containing no files nor subdirectories (excluding `.` & `..`)
- A zero-byte file
- A junction (if follow\_symlinks is disabled)
- A symlink (if follow\_symlinks is disabled)

---

<div class="post-metadata">

**Author:** ![zware](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/zware/32/58_2.png) [@zware](https://discuss.python.org/u/zware)\
**Post date:** [April 5, 2024, 8:02pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/12 "2024-04-05T20:02:15Z")

</div>

A meta note: please avoid repeatedly changing the topic title, as it makes it much harder to follow the conversation via email. As you’ve also found, constantly editing previous posts makes it hard to respond to those posts since they’re a moving target, and email participants won’t even notice the changes.

* * *

I would highly recommend to follow @barry-scott’s advice from above:

> [@barry-scott](#):
>
> Why don’t you put these helper functions into a PyPI package and see if other people find them useful.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [April 5, 2024, 10:08pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/13 "2024-04-05T22:08:23Z")

</div>

> [@Nineteendo](#):
>
> I was simply wondering if these functions could be useful for other people too.

Not for me, no.

---

<div class="post-metadata">

**Author:** ![kknechtel](https://avatars.discourse-cdn.com/v4/letter/k/e47c2d/32.png) [@kknechtel](https://discuss.python.org/u/kknechtel)\
**Post date:** [April 5, 2024, 11:12pm UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/14 "2024-04-05T23:12:09Z")

</div>

> [@Nineteendo](#):
>
> In an interactive program, you can delete such files without asking for confirmation.

Maybe _your_ program can do this. There will be others that have a meaningful reason to care about the presence or absence of a specific file in a specific location, even if it’s empty. (Perhaps you’ve seen some examples named ` __init__.py` 😉 )

---

<div class="post-metadata">

**Author:** ![cameron](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/cameron/32/2658_2.png) [@cameron](https://discuss.python.org/u/cameron)\
**Post date:** [April 6, 2024, 12:25am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/15 "2024-04-06T00:25:08Z")

</div>

> I was using a similar function in the old file manager I wrote, but I  
> wasn’t happy about the interface library it’s built on, so now I’m  
> redesigning everything from scratch. At the moment, nothing is final.

Very sound. But this _isn’t_ for the stdlib. Have this discussion in the  
“Help/users” category instead. Your criteria are _inherently_  
application specific.

> I was simply wondering if these functions could be useful for other  
> people too.

They may be (but I’d choose a less… vague name than `hasdata`,  
myself). So write yourself a module where you keep this kind of thing  
and publish it on PyPI. If others find it useful, then they _can_ use  
it!

Glaring example: I’ve got a `cs.fileutils` module on PyPI filled with all  
sorts of things I’ve found (and find) useful. Anyone could use it if  
they like. Also its lower level companion, `cs.fs`.

If you’re encountering lots of bikeshedding, give your function various  
optional flags to set/unset particular behaviours.

Personally, if I expect to remove a directory I expect it to _already_  
be empty, and just us `os.rmdir`. Making it empty enough for that is my  
app’s job.

---

<div class="post-metadata">

**Author:** ![cameron](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/cameron/32/2658_2.png) [@cameron](https://discuss.python.org/u/cameron)\
**Post date:** [April 6, 2024, 12:31am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/16 "2024-04-06T00:31:15Z")

</div>

Still the side note, it’s all grouped nicely in my mail reader because  
the messages have correct `In-Reply-To` headers:

```
 06Apr2024 10:22 Karl Knechtel v - ┌>[Py] [Ideas] Os.path.isempty() & pathlib.Path.is_empty()
 06Apr2024 09:18 Paul Moore via - │ ┌>[Py] [Ideas] Os.path.isempty() & pathlib.Path.is_empty()
 06Apr2024 02:34 Nice Zombies vi r │┌>
 06Apr2024 02:20 Barry Scott via - ├>
 06Apr2024 03:04 Cornelius Krupp - ├>
 06Apr2024 02:17 Nice Zombies vi - ┌>
 06Apr2024 07:12 Zachary Ware vi r │┌>[Py] [Ideas] Os.path.isempty() & pathlib.Path.is_empty()
 06Apr2024 01:44 Barry Scott via - ├>[Py] [Ideas] Os.path.hasdata() & pathlib.Path.hasdata()
 06Apr2024 06:41 Nice Zombies vi - ├>[Py] [Ideas] Os.path.isempty() & pathlib.Path.is_empty()
 06Apr2024 05:10 James Webber vi - │ ┌>
 06Apr2024 04:35 Nice Zombies vi - │┌>
 06Apr2024 04:13 Chris Angelico - ├>
 06Apr2024 01:45 Cornelius Krupp - ├>
 06Apr2024 01:38 Nice Zombies vi - [Py] [Ideas] Os.path.hasdata() & pathlib.Path.hasdata()

```

I can even see the subject line changes.

What’re you using to read the list? (Or do you delete messages once  
read, which I don’t.)

OTOH, as an email user I find retrospective editing of posts very  
annoying. Unless the author’s fixing up stupid typos (I do this myself,  
I make them all the time), we never see the revised versions and even  
people on the forum have to go back and try to figure out what’s been  
changed. Posting a followup correction/response is much better.

---

<div class="post-metadata">

**Author:** ![eryksun](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/eryksun/32/697_2.png) [@eryksun](https://discuss.python.org/u/eryksun)\
**Post date:** [April 6, 2024, 12:40am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/17 "2024-04-06T00:40:10Z")

</div>

An empty directory or empty file might have extended attributes. On Windows, either might also have alternate data streams.

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 6, 2024, 5:22am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/18 "2024-04-06T05:22:32Z")

</div>

I’m afraid you still missed my reply about changing the name of the function to `ìsempty` because I renamed the post title.

---

<div class="post-metadata">

**Author:** ![Nineteendo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/nineteendo/32/19122_2.png) [@Nineteendo](https://discuss.python.org/u/Nineteendo)\
**Post date:** [April 6, 2024, 5:38am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/19 "2024-04-06T05:38:13Z")

</div>

> There will be others that have a meaningful reason to care about the presence or absence of a specific file in a specific location, even if it’s empty. (Perhaps you’ve seen some examples named ` __init__.py` 😉 )

OK, maybe it’s better to always ask for confirmation.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [April 6, 2024, 5:57am UTC](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337/20 "2024-04-06T05:57:58Z")

</div>

> [@Nineteendo](#):
>
> because I renamed the post title.

That’s not his problem, that’s yours. Please don’t make substantive edits and assume that people will just notice them. Post responses in the thread so we can actually see them.

[Next page](https://discuss.python.org/t/os-path-isempty-pathlib-path-is-empty/50337.md?page=2)
