Python Pathlib: "with_suffix" - Object has no attribute

79 Views Asked by At

I am trying to write a small program to find all audio files in a specific folder (and subsequent subfolders), then check if that audio file already has a .vtt or an .srt file associated with it, and if not, it should create a list of said audio files. This list is then passed to a program to create transcriptions. Here is my code so far:

import pathlib
import posixpath

# Search for all audio files, recursively
extentions = [".ogg", ".wav", ".mp3"]
folder_path = "/tmp/audiofiles/"
files = [f for f in pathlib.Path(folder_path).rglob('*') if f.suffix in extentions]


for x in files:
    abs_name = posixpath.abspath(x)
    print(abs_name)
    filename_without_ext = abs_name.with_suffix('')
    print(filename_without_ext)

The abs_name comes back as /tmp/audiofiles/2/2.ogg. So I am trying to test if /tmp/audiofiles/2/2.vtt or /tmp/audiofiles/2/2.srt exists, and if not, add /tmp/audiofiles/2/2.ogg to a the list.

I have looked at this link, especially the answer by JS, but I get the following error:

Traceback (most recent call last):
  File "./get_file_list.py", line 15, in <module>
    filename_without_ext = abs_name.with_suffix('')
AttributeError: 'str' object has no attribute 'with_suffix'

What am I missing here?

2

There are 2 best solutions below

0
BashNewbie On

For beginners like me, who may need something like this in future, this is how I solved this part of my problem.

import pathlib
import os

def generate_file_list():
    # Search for all audio files, recursively
    extentions = [".ogg", ".wav", ".mp3"]
    folder_path = "/tmp/audiofiles/"
    files = [f for f in pathlib.Path(folder_path).rglob('*') if f.suffix in extentions]
    to_be_transcribed = []

    for x in files:
        filename_vtt = x.with_suffix('.vtt')
        filename_srt = x.with_suffix('.srt')
        x = str(x)
        if os.path.isfile(filename_vtt) or os.path.isfile(filename_srt):
            print('File: ' + x + ' has a transcription already')
        else:
            to_be_transcribed.append(x)

    return to_be_transcribed

if __name__ == "__main__":
    file_list = generate_file_list()
    print(file_list)
2
ShadowRanger On

You don't want to mix pathlib and posixpath here; the moment you call a posixpath method on a Path, you get back a str, not a new Path. Path objects generally have the same functionality as what os.path (posixpath is just a non-Windows-specific module supporting os.path) offers, so you just use the equivalent Path method instead. In this case, you don't have to do the complete refactor your performed, all you need to do is change:

abs_name = posixpath.abspath(x)

to:

abs_name = x.absolute()

As a side-note: While posixpath is technically documented, it's needlessly non-portable to use it directly. When you do need that functionality (and don't want pathlib's high-level Path objects), use import os.path instead.