Skip to content

Fixing bug #180 #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Conversation

elechapt
Copy link
Contributor

Catch Exceptions in the _PicoscopeBase() class (picobase.py) that are raised when not connected. They do not convey useful information, as they are typical error happening with the garbage collector and disappearing attributes.

# _lowLevelCloseUnit raise: libps5000a.so not found if not connected
pass
except OSError:
# self.handle doesn't exist when not connected
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this raise an attribute error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, I switched the comments ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does "handle does not exist" mean? isn't the handle None in that case? in which case the if statement takes care of it.

Copy link
Contributor Author

@elechapt elechapt Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought, but I ended up writing some code where I get an AttributeError stating that PS5000a does not have an attribute named handle, which means at some point, the garbage collector has destroyed the attribute, but can still call the __del__ method. It already happened to me in an unrelated piece of code, I was handling threads and somehow, at deletion, methods could be called but attributes weren't there anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a common issue with adding definitions outside the init method.

Let's then define handle as None in the init method and then we can get rid of this one except issue.

Copy link
Contributor Author

@elechapt elechapt Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's already defined in the __init__. After some looking up, I conclude that it is linked to the behaviour of __del__, where the simple attributes are already destroyed when arriving in the __del__ method. To quote the __del__ doc :

It is not guaranteed that del() methods are called for objects that still exist when the interpreter exits.

After some extra reading, it turns out that __del__ is at best a makeshift, at worse completely useless, it's better to call the close() method anyway. __del__ is intrinsically unreliable.

@hmaarrfk
Copy link
Collaborator

I'm not sure i agree with the fix.

I think the issue is that:

https://github.com/colinoflynn/pico-python/blob/master/picoscope/ps5000a.py#L172

c_handle.value

could return 0x0 and not Null. therefore we should be "checking" for that in the case of errors and handling that correctly.

@elechapt
Copy link
Contributor Author

elechapt commented Jun 28, 2023

That sure can be a source of error, which raises maybe an OSError. I 'll try to fix that too.

But the AttributeError is very specific, and well documented. We actually should always call explicitly the close() method, and not rely on the __del__ method :

there is no guarantee that __del__() will be called: it's just for memory manager use, not for resource handling.

And after some testing, the real problem with the line you mention is that the next function is doing it's job, the close unit function raises after trying to connect to a given picoscope and failing. Actually, this happens :

  • Try to open a picoscope, _lowLevelOpenUnit failing because it's not connected
  • _lowLevelOpenUnit function raises
  • The object is destroyed, calling __del__, calling close(), calling _lowLevelCloseUnit
  • _lowLevelCloseUnit raises too because c_handle.value is wrong (for a good reason) since the beginning.
    And we ended up with two raised exception for one information (we're no connected), and that generates ignored exceptions in my code. The fix allow for the last raised exception to be truly ignored, and the AttributeError one to never show up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants