Skip to content
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

PyPortal: board.DISPLAY is None returns wrong value #6227

Open
bablokb opened this issue Apr 2, 2022 · 13 comments
Open

PyPortal: board.DISPLAY is None returns wrong value #6227

bablokb opened this issue Apr 2, 2022 · 13 comments
Labels
Milestone

Comments

@bablokb
Copy link

bablokb commented Apr 2, 2022

CircuitPython version

Adafruit CircuitPython 7.2.4 on 2022-03-31; Adafruit PyPortal with samd51j20

Code/REPL

Adafruit CircuitPython 7.2.4 on 2022-03-31; Adafruit PyPortal with samd51j20
>>> import board
>>> import displayio
>>> board.DISPLAY
<Display>
>>> displayio.release_displays()
>>> board.DISPLAY
None
>>> type(board.DISPLAY)
<class 'NoneType'>
>>> board.DISPLAY is None
False
>>> foo=None
>>> foo
>>> type(foo)
<class 'NoneType'>
>>> foo is None
True

Behavior

After displayio.release_displays() the attribute board.DISPLAY is None but "is None" returns False.

Note that I know I should not call this method for boards with integrated displays, but errors happen. But I expect "isNone" to always return True for variables of type 'NoneType'.

Description

No response

Additional information

No response

@bablokb bablokb added the bug label Apr 2, 2022
@jepler jepler added this to the 8.0.0 milestone Apr 2, 2022
@jepler jepler modified the milestones: 8.0.0, Long term Jul 6, 2022
@jepler
Copy link
Member

jepler commented Jul 6, 2022

The way we make the board.DISPLAY object "be None" is not quite correct, because it doesn't make it obey an "is" test. We need to define a proper way to check for the display being deinitialized that doesn't have this problem. For now, it is possible to use type(board.DISPLAY) is type(None), but we recognize it's not ideal.

@deshipu
Copy link

deshipu commented Jul 6, 2022

How about if not board.DISPLAY?

@jepler
Copy link
Member

jepler commented Jul 7, 2022

How about if not board.DISPLAY?

Unfortunately this fake-None is also treated as a true value in truthy contexts :-(

@deshipu
Copy link

deshipu commented Jul 7, 2022

Well, maybe that's what we should fix then.

@deshipu
Copy link

deshipu commented Jul 7, 2022

We don't even need to call it None, as long as it's false-y.

@dhalbert
Copy link
Collaborator

dhalbert commented Jul 7, 2022

Maybe we could make it an int zero instead of a pointer?

@tannewt
Copy link
Member

tannewt commented Jul 7, 2022

How about if not board.DISPLAY?

Unfortunately this fake-None is also treated as a true value in truthy contexts :-(

We could change this by having a custom unary op for NoneType.

Maybe we could make it an int zero instead of a pointer?

Make what an int zero? We can't modify the pointer because it is in a ROM table. That's why it changes the object type now.

@deshipu
Copy link

deshipu commented Jul 7, 2022

We could change this by having a custom unary op for NoneType.

Wouldn't it be just as simple as having a NoDisplay type with a __nonzero__() method that returns False?

@dhalbert
Copy link
Collaborator

dhalbert commented Jul 7, 2022

Not thinking well. But we could make it an empty list or tuple or bytearray, all of which are False-y?

@deshipu
Copy link

deshipu commented Jul 7, 2022

None should be False-y too? Not sure why this doesn't work?

@dhalbert
Copy link
Collaborator

dhalbert commented Jul 7, 2022

Because None is a singleton, and it does an address comparison only.

@deshipu
Copy link

deshipu commented Jul 7, 2022

Ideally, it should be board.DISPLAYS[0] — perhaps we could change to that eventually? Have both board.DISPLAY and board.DISPLAYS for a time...

@jepler
Copy link
Member

jepler commented Jul 7, 2022

Using a list (or function) board.DISPLAYS does help with the problem, because the list would reside in RAM and thus the object pointer could actually be updated. It would also help with the rare boards that have more than one display.

There's still the problem of what if you write d = board.DISPLAYS[0]; displayio.release_displays() and later refer to d. It needs a way to be turned into a deinitialized display object.

I have an incomplete and non-working branch that introduces the Deinitialized object, which might be of interest. It tries to solve the problem generally for other types of objects as well: https://github.com/adafruit/circuitpython/compare/main...jepler:circuitpython:deinited-type?expand=1

This needs to be elaborated on so that it builds and works. The object would always act False in a truthy context (so you could say 'if not board.DISPLAY`, unlike currently).

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

No branches or pull requests

5 participants