#๐Ÿ”’ "Local variable might be referenced before assignment"

67 messages ยท Page 1 of 1 (latest)

oak vigil
#

What does that hint mean?
It pops up every time I try to do a try/except

vale idolBOT
#

@oak vigil

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

oak vigil
#
def validate_path():
    try:
        while True:
            path = Path(input("Enter the path: "))
    except KeyboardInterrupt as e:
        print(e)
        if not path.is_dir():
            print("Please enter a valid path.")
        else:
            return path
#

this is the function if it helps

supple ember
#

The ctrl+c might happen before anything is inputted to be parsed as path

Meaning path variable might not exist when the line if not path.is_dir() is run...

#

Just like the warning said - "might be referenced (ie: used) before assignment (ie: before it gets created)"

oak vigil
#

Oh

weary lake
#

if the program crashes... ```py
path = Path(input("Enter the path: "))

^-----------------------^ here

Then it exits before anything is passed to Path, then `path` wouldn't be assigned
oak vigil
#

Ahhh

#

So basically if the KeyboardInterrupt happens then my if not condition has nothing to work with

#

hmm

#

I believe my try/except placement is wrong then

#

should i put the except lower ?

supple ember
supple ember
oak vigil
supple ember
#

I can highly recommend grabbing a pen and paper and just trying to make a simple decision chart what should happen when. It will be clear where you need the path check and whether you need the KeyboardInterrupt (hint: you do not, it's not an exception you normally want to catch, it closes the program anyways when it's not caught)

oak vigil
#

Oh, this is not about whether I need it or not.
I just want to practice try/excepts

supple ember
#

The chart here would look like:
Take input
Check if it's a dir --yes> return
|
no
V
loop back to taking input

No try/except here

supple ember
#

Or making a calculator and someone enters 0 as divisor
(bonus points: this actually does number parsing as well before you get to the 0)

oak vigil
supple ember
#

I don't think this code will have much of that. Paths are abstract concept - only when you start trying to access somethjng you'll encounter any possible errors (file doesn't exist, or isn't writeable, etc). And pathlib already allows you to check a lot of that stuff without doing stuff that throws an exception - e.g. path.exists()...

oak vigil
#

Actually Nicky

#

thank you

#

you gave me a nice idea to use try/except on

#

I basically answered my question myself.
Hang on, let me try the "not writable" stuff.

#
def scan_files_for_errors(file_groups):
    line_count = 0
    for file in [*file_groups['.txt'], *file_groups['.log']]:
        try:
            with open(file) as content:
                line_count += sum(
                    1 for line in content
                    if "error" in line.casefold().split()
                )
        except PermissionError:
            print(f"Skipping {file.name} as there are no permissions.")
    return line_count

@supple ember if you dont mind, could you please check this?
This would be correct now, no?

Im trying to open a file and if there is a permission error i throw an exception "PermissionError"

#

i also saw that some people do:

except Exception as e:
  print(e)

The "e" i dont quite understood yet- what exactly does it do?

Does python just pick a default error message? or what exactly happens ?

main moth
#

e is just a named variable that holds the exception object

#

you can name it however you like instead of e

oak vigil
main moth
#

whatever you just caught

oak vigil
#

Oh alright ๐Ÿ‘Œ

#

@main moth since Nicky isnt here right now, could you please check the code above whether I have handled the try/except properly?

#

I could also do a "not readable" if the content is in a weird, unreadable format or so. Like egypt hyroglyphs

#

but that means when i open(file) i need to specify the format im opening them in I THINK

#

not sure

main moth
#

that code will only catch PermissionError, not other types of exceptions

#

you may want to catch OSError if you want broader handling of I/O errors

oak vigil
#

Ill look into OSError now

main moth
#

since anything can happen when interfacing with the file system, it's often a good idea to handle OSError properly

oak vigil
#

Okay I've read through OSError, let me quickly rewrite something

#
def scan_files_for_errors(file_groups):
    line_count = 0
    for file in [*file_groups['.txt'], *file_groups['.log']]:
        try:
            with open(file) as content:
                line_count += sum(
                    1 for line in content
                    if "error" in line.casefold().split()
                )
        except OSError as e:
            if e.errno == errno.ENOENT:
                print("No such file or directory")
            elif e.errno == errno.EACCES:
                print("Permission denied")
            else:
                print(f"Error: {e}")
    return line_count

@main moth

I learned:
OSError is basically a "parent" exception of the "PermissionError" exception (and a few other exceptions).
So instead of throwing the "PermissionError" exception and other exceptions separately, i can use OSError instead as one exception and then specify each one of them in the if conditions.

Is that right?

main moth
#

I would do it differently

oak vigil
#

Oh

main moth
#
def scan_files_for_errors(file_groups):
    line_count = 0
    for file in [*file_groups['.txt'], *file_groups['.log']]:
        try:
            with open(file) as content:
                line_count += sum(
                    1 for line in content
                    if "error" in line.casefold().split()
                )
        except PermissionError:
            print("Permission denied")
        except FileNotFoundError:
            print("No such file or directory")
        except OSError as e:
            print(f"Error: {e}")
    return line_count
#

much more readable this way, wouldn't you agree?

oak vigil
#

Ohhhh

#

I think I understand why you have done it this way

#

You only want to focus on the PermissionError and FileNotFoundError, you specify those two exceptions

#

and then, as the 3rd exception you said "and anything unexpected i want to throw in the OSError exception"

main moth
#

yes

oak vigil
#

I think i had basically done the same BUT yours is more readable

main moth
#

yup

oak vigil
#

and it makes sense this way because exceptions are "executed" in chronological order.

#

so it makes sense to have the OSError as the "any" in the last position

#

COol cool, this makes a lot of sense thank you :D

north wind
#

The except blocks are considered in order of appearance, yeah.

#

(a linter would probably catch if you put them in the wrong order, at least for simple cases like this where there's a clear "wrong order")

oak vigil
#

Alrighty, thank you for the valuable input everyone!!
Try/except blocks arent too complicated after all - as long as you consider your options and think of what you truly want to test / handle when "obvious" things could go wrong

#

Will be closing the ticket then. Thank you again ๐Ÿ™

vale idolBOT
#
Python help channel closed using Discord native close action

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.