Object of type "None" is not subscriptable error using dictionary get()

255 views Asked by At

Seems like I cannot even understand the basics of Python....

 current_price: float = current_items.get(item)[0]

When running pyright I get the following error complaining about the above line.

  D:\Git\pvp\main.py:71:36 - error: Object of type "None" is not subscriptable (reportOptionalSubscript)

current_items is a dictionary of list of values and all I wanted to do was get the first item in the returned value. Type(current_items.get(item)[0]) gives me a float type and get() always returns the correct float value.

This code gives my desired result but clearly I need to code in a different way just not sure why.

enter image description here

2

There are 2 answers

1
Mahboob Nur On

You can check if the key exists like this

if item in current_items:
    current_price: float = current_items[item][0]
    # Rest of your code
else:
    # as per your logic codes 
0
Dmitry On

reportOptionalSubscript indicates an attempt to subscript (index) a variable with an Optional type, which could be illustrated by the sample from pyright tests:

c = None
if 1:
    c = [3, 4, 5]

# If "reportOptionalSubscript" is enabled,
# this should generate an error.
c[2]

Dictionary's get() method may return None, and that triggers the inspection regardless of actual data.

The first solution as mentioned by @Ry- is to get rid of get() and use square brackets to access the value. pyright stays silent with:

current_price: float = current_items[item][0]

It could also be a good habit to assume possibility of exceptions and reflect that in the code. Also useful while working with external data (e.g. JSON) directly (without pydantic or similar):

try:
    current_price: float = current_items[item][0]
except (KeyError, TypeError, IndexError):
    pass  # or handle these exceptions

The second solution is to suppress a false positive diagnostic on that specific line with # type: ignore or # pyright: ignore:

try:
    # here despite all exceptions being handled pyright still raises an error
    # assuming this is a false positive - ignore it
    current_price: float = current_items.get(item)[0]  # pyright: ignore
except (TypeError, IndexError):
    pass