#๐Ÿ”’ Variable magically becomes None when trying to assign it

43 messages ยท Page 1 of 1 (latest)

analog aurora
#

Hi, I never encountered something like this, any ideas?

print(self.global_target_image != None) # is not None
print(dir(self.global_target_image)) # calibration_data in dir
print(self.global_target_image.calibration_data) # yup, it exists
data = self.global_target_image.calibration_data # global_target_image is now None?

Log:

True
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', 'asset_folder', 'blockSignals', 'calibration_data', 'camera_number', 'childEvent', 'children', 'connect', 'connectNotify', 'crop', 'customEvent', 'deleteLater', 'destroyed', 'disconnect', 'disconnectNotify', 'dumpObjectInfo', 'dumpObjectTree', 'dynamicPropertyNames', 'emit', 'event', 'eventFilter', 'export', 'export_path', 'findChild', 'findChildren', 'format', 'generate_preview', 'get_export_path', 'get_target_calibration_data', 'global_target_image', 'image_type', 'inherits', 'installEventFilter', 'isQuickItemType', 'isSignalConnected', 'isWidgetType', 'isWindowType', 'iteration', 'killTimer', 'mark', 'metaObject', 'moveToThread', 'name', 'objectName', 'objectNameChanged', 'original_path', 'parent', 'property', 'raw_path', 'receivers', 'removeEventFilter', 'scale_factor', 'scan', 'scan_finished', 'sender', 'senderSignalIndex', 'sequence', 'setObjectName', 'setParent', 'setProperty', 'set_mark', 'set_status', 'signalsBlocked', 'src_grey', 'startTimer', 'staticMetaObject', 'status', 'target_image', 'thread', 'timerEvent', 'tr', 'tree_item']
<api.calibration_data.CalibrationData object at 0x00000201F6F71FD0>
ERROR:root:'NoneType' object has no attribute 'calibration_data'
rose reefBOT
#

@analog aurora

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.

ripe crane
#

Is this from a public library? that way i could take a looko at it

analog aurora
# ripe crane Is this from a public library? that way i could take a looko at it

Nope, this is my own code, I'm assigning global_target_image once at the start, from another Class.

def assign_calibration_targets(self):
        targets = self.calibration_folder.targets

        for img in self.calibration_folder.image_list:
            img.global_target_image = self.calibration_folder.image_list[0]
        ...
        for non_target in non_targets:
            non_target.target_image = get_first_by(
                targets, lambda x: x.camera_number == non_target.camera_number and x.iteration == 1
            )

It never gets re-assigned or touched again

jaunty crow
jaunty crow
#

also, is .calibration_data an attribute or a property of the api.calibration_data.CalibrationData class?

analog aurora
#
class Image(QObject):
    scan_finished = Signal(ImageStatus)

    def __init__(self, raw_path: Path):
        super().__init__()
        ...

        self.target_image: Image = None
        self.global_target_image: Image = None
        self.calibration_data: CalibrationData = None

Here's target_image and global_target_image

For some reason, when I also assign target_image, global_target_image, no longer throws the error, which confuses me more

def assign_calibration_targets(self):
    targets = self.calibration_folder.targets

    for img in self.calibration_folder.image_list:
        img.global_target_image = self.calibration_folder.image_list[0]
        img.target_image = self.calibration_folder.image_list[0]
jaunty crow
analog aurora
#

yeah I have no idea
both target_image and global_target_image are pretty much the same thing, I don't see why one causes issues and not the other ๐Ÿ™

jaunty crow
#

it's very hard for us to troubleshoot the issue when only getting bits and pieces of the code without much context, if you are prepared to share much more of your code it would be a lot easier to be able to spot any potential issues

rose reefBOT
#
Pasting large amounts of code

If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/

After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.

jaunty crow
#

@analog aurora i think one of the most important files might be api/calibration_data.py that isn't included

#

as that one contains the class that might be the one that is acting up

jaunty crow
#

oh, now i see it, their wasn't much code in that file (or class for that matter)

#

@analog aurora probably not the issue, but i see a lot of function calls like

calibrate_and_export(self, data, override_swatches)
```and
```py
return generate_preview(self, data)
```from within the class
don't you mean to call them as
```py
self.calibrate_and_export(data, override_swatches)
```and
```py
return self.generate_preview(data)
```instead?
analog aurora
#

Now this is giving me both a None exception, but it's also printing the supposedly None data??

data = self.all_calibration.image_list[0].calibration_data
print(data)
<api.calibration_data.CalibrationData object at 0x0000023098FD2120>
ERROR:root:'NoneType' object has no attribute 'calibration_data'
analog aurora
jaunty crow
analog aurora
#

I guess I'll try to find another way of getting a reference to that CalibrationData, it should be the same for all images

This might be my new personal record on the weirdest bug I've found so far

Thanks for the help

jaunty crow
jaunty crow
analog aurora
jaunty crow
#

@analog aurora this doesn't really check out (but should work anyways as it's "just" a type hinting "issue")

data: CalibrationData = None
```should probably be written as
```py
data: CalibrationData | None = None
```if it's allowed to ever be `None` (if it's an optional field)
#

you could skip it all together and just do

data = self.global_target_image.calibration_data
```or even
```py
data: CalibrationData = self.global_target_image.calibration_data
```if you want to type hint that variable there to something stricter then what `self.global_target_image.calibration_data` is defined as
#

@analog aurora this above is really also a potential issue with all of the attributes in your classes that you type hint and then initialize to None without including | None in the type hint

analog aurora
#

you mean not explicitly type-hinting that a variable can also be None could be the issue?

jaunty crow
#

if you run a tool such as ty or pyright it will complain about this code

#

another tool that can be good to use is ruff and using ruff check --diff and ruff format --diff on your file to spot potential bugs and issues with your code (and also automatically reformat the code to follow some standards if you leave out the --diff flag)

analog aurora
#

Thanks I'll take a look at these

jaunty crow
#

@analog aurora if you don't want to initialize a variable in __init__ to anything other then None you could just have it as a attribute on the class with type hinting that doesn't allow for None, in that case it's "allowed", since the attribute doesn't come into existence for that class instance until that attribute is assigned to the first time (and all assignments must be of that type then)

#

might be able to catch the bug that way, but getting an error about trying to access a attribute before it has been assigned to
either that or add | None to the type hint so that you make it optional and can contain None

analog aurora
#

I'll try fixing the type hinting and see if that causes it to work, thanks

jaunty crow
rose reefBOT
#
Python help channel closed for inactivity

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.