I need help with a "is" with a literal error


how do I fix this error? I am following a video tutorial from 3 years ago. The bullet will not shoot.

The tutorial is probably wrong, but that happens, unfortunately. This kind of error is very common, which is why you’re now getting this warning. The warning is exactly correct though - replace is (an identity comparison) with == (an equality comparison) and you should be fine.

Well, first off, it isn’t an error, it’s a warning - which is why it says SyntaxWarning and not SyntaxError. But right after this, it tells you what is wrong: "is" with a literal. It highlights code that tries to use is; do you understand what “literal” means here? If not, here is a reference. Then, it suggests: Did you mean "=="? So, it seems that it is trying to tell you to use == instead of is on that line of code. Did you try doing that? If you try doing that, does it fix the problem?

What do you think is means in Python? (If you don’t know, did you try to find out?) How about ==? If you are not familiar with these tools, you should study a tutorial for the Python language itself first, before trying to follow a “video tutorial” to make a game using third-party libraries like Pygame. These tutorials are not actually a useful way to learn. They are only a way to feel like you are learning, because you follow some steps and get (when the tutorial creator didn’t make a mistake) some interesting result. But when you actually learn, you understand concepts as you go, can come up with more ideas to try, notice mistakes in others’ work, and develop skills such as reading error messages and understanding what they are trying to tell you.

1 Like

Please make sure that you understand why == should be used here rather than is.

The following may underscore the danger of using is to compare strings, even though you may often have gotten away with it:

>>> fi = "fi"
>>> re = "re"
>>> fire = "fire"
>>> fi + re is fire
False
>>> fi + re
'fire'
>>> fire
'fire'
>>> fi + re == fire
True

In particular, note this …

>>> fi + re is fire
False

… compared to this …

>>> fi + re == fire
True

EDIT:

The following may provide additional insight:

>>> id(fire)
4319671920
>>> id('fire')
4319671920
>>> id(fi + re)
4311982960
>>> fire2 = fi + re
>>> id(fire2)
4314947632
1 Like

In case it’s helpful, I just made a small improvement to this syntax warning: https://github.com/python/cpython/pull/103493 :slight_smile:

2 Likes

“is” tests object identity; it just compares two unique identifiers for two objects in memory. That unique identifier can be an address in memory, or just an arbitrary number.

“==” tests object equality; it compares (usually) two different objects to see if their associated memory has the same stuff in them. (OK, really it’s using __eq__).

“is” is a little faster than ==, but more often than not isn’t what you want.

“is” is unfortunately something that feels right when you first see it, but it should only be used for things that have very few actual values of a given type (or are interned in memory) - like “var is None” (except in a SQLAlchemy context) or “var is True”, because there is only one value of NoneType (None), and there are only two boolean values (True and False). It’ll also work for very small integers, but this should not be relied upon, and can be thought of as a Python implementation detail to avoid assuming. IOW, use == for int’s, even though “is” sometimes works for them.

“is” is also nice for testing object identity of a sentinel value, created with something like “sentinel = object()”. You can then do something like:

if value is sentinel:
   print('this is the only thing that is sentinel')

If some of this makes no sense, feel free to ignore - it won’t hurt you much. And apart from the sentinel use I think you can probably always use == instead of “is”.

I think that’s maybe going a little far.