3

Background

I use assert statement to check if certain files in a list exist in my computer, then I would like to do further work if these files are all there. I've referenced to this thread, so I do something like this:

from pathlib import Path

# The list containing several filepaths
files = ['folder/file1', 'folder/file2', 'folder/file3']

# check if all of these files are exist
assert all(Path(n).exists() for n in files)

# Do something else ...
# ...

This piece of code is runnable. If one file does not exist, the program will raise AssertionError.

Question

Now I would like to all the file(s) that not exist, instead of a simple AssertionError.

Is there any one-liner solution for this?

What I have tried

I've tried the following:

assert all(Path(n).exists() for n in files), f"file {n} not exist!"

Runing this code will report NameError: name 'n' is not defined.

Sean_Syue
  • 555
  • 7
  • 14
  • 1
    I don't get the question. What are you trying to do? – absolutelydevastated Jul 02 '19 at 07:25
  • 1
    `assert` should only be used for **debugging** purposis. If you run python with "optimizations enabled" all assertions are removed. Anyway in python3.8 *maybe* this would work: `assert all(Path(m := n).exists for n in files), f"file {m} does not exist"` I'm not sure how the expressions assignment would be scoped in this case... I believe it wont work since I'd guess it would be local to the genexp and would not bleed to the outer scope but I have no python3.8 to test on – Giacomo Alzetta Jul 02 '19 at 07:28

3 Answers3

0

You'll need to use a loop:

for file in files:
    assert Path(file).exists(), f"{file} does not exist!"

In Python 3.8+, you can do it in one line by using the walrus operator:

assert not (missing_files := [n for n in files if not Path(n).exists()]), f"files missing: {missing_files}"
L3viathan
  • 26,748
  • 2
  • 58
  • 81
0

n from comprehension isn't in scope where you do f'{n}'

You can show all not exists files

not_exists = [f for f in files if not Path(f).exists()]
assert not not_exists, f'Files {not_exists} not exist'

Or, only the first one

for f in files:
  assert Path(f).exists(), f'{f} not exists'

Sav
  • 616
  • 3
  • 9
0

As already pointed out in comments, assert is strictly a development tool. You should use an exception which cannot be turned off for any proper run-time checks; maybe create your own exception for this. (Assertions will be turned off in production code under some circumstances.)

Secondly, the requirement to do this in a single line of code is dubious. Code legibility should trump the number of lines everywhere, except possibly in time-critical code, where execution time trumps both.

class MissingFilesException(Exception):
   pass


missing = {x for x in files if not Path(x).exists()}
if missing:
    raise MissingFilesException(
        'Missing files: {}'.format(", ".join(missing))
tripleee
  • 175,061
  • 34
  • 275
  • 318