AssertionError if running code in Python prompt but not if running as file

2024/9/20 2:09:09

Why trying to explain here on stackoverflow what the Python command id() does and how can it be used to reveal how Python works under the hood I had run into following strange behavior I am struggling to understand how it comes:

TERMINAL-PROMPT $ python3.9 -V
Python 3.9.13
TERMINAL-PROMPT $ cat       "list_and_int_1.py"
i = 12345
assert id(i) == id( 12345 )
TERMINAL-PROMPT $ python3.9 "list_and_int_1.py"
TERMINAL-PROMPT $ python3.9
Python 3.9.13 (main, May 20 2022, 21:21:14) 
[GCC 5.4.1 20160904] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> i = 12345
>>> assert id(i) == id( 12345 )
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AssertionError

So my question is why there is an AssertionError if I run the Python script code from within Python prompt but not if running the code executing it from file?

Seeing my question closed without trying to pay attention to what it is about I suggest: PLEASE read the question.

I am fully aware of the issue with cached integers. So my question is NOT about that. My question is why in the Python prompt there is another behavior of same code compared to running that code from the file? The Python version is exactly the same. So how does it come that it gives different results depending from where it is run?

My question is definitely NOT a duplicate of: https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers .

And ... YES, I was aware of the possibility that I don't see the assertion error messages when running the file so I have checked this out and changed the assert statement in the file so that it will raise AssertionError to see if the Error shows up in the console and it did show up excluding this kind of issue from the possible reasons.

TERMINAL-PROMPT $ cat       "list_and_int.py"
i = 12345
assert id(i) == id( 12345 )
TERMINAL-PROMPT $ python3.9 "list_and_int.py"
TERMINAL-PROMPT $ cat       "list_and_int.py"
i = 12345
assert id(i) != id( 12345 )
TERMINAL-PROMPT $ python3.9 "list_and_int.py"
Traceback (most recent call last):File "/home/.../list_and_int.py", line 2, in <module>assert id(i) != id( 12345 )
AssertionError

P.S. I have seen the urge to close questions here on stackoverflow many times being sometimes myself not able to post an answer because the question was closed very fast and the reason given for closing it was a wrong one. I understand the time pressure of the modern world ... but ... this is not an excuse for not spending a short thought of why actually the question is there and what is it really about.

P.S. P.S. Source: https://docs.python.org/3.10/library/functions.html

id(object)
Return the “identity” of an object. 
This is an integer which is guaranteed to be unique and constant
for this object during its lifetime. Two objects with 
non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

So is this documentation WRONG? Does the id() not give an insight of different memory area if the id()s are different? Is the same id() possible when the objects are stored at different positions in memory?

Answer

The people in the comments are correct – don't use is to compare anything unless you really know why you'd do that.

Anyway, the answer is that CPython optimizes constants when it compiles code objects.

The disassembly for the module

a = 123456
b = 234567
c = 345678
d = 123456

is

  1           0 LOAD_CONST               0 (123456)2 STORE_NAME               0 (a)2           4 LOAD_CONST               1 (234567)6 STORE_NAME               1 (b)3           8 LOAD_CONST               2 (345678)10 STORE_NAME               2 (c)4          12 LOAD_CONST               0 (123456)14 STORE_NAME               3 (d)16 LOAD_CONST               3 (None)18 RETURN_VALUE

As you can see, the constant 123456 from "constant slot" 0 is used twice when assigning to a name.

In the REPL, each line (well, each entry, since you know you can enter full suites in the REPL too) is compiled separately, so the same constant can't be reused.

You can inspect the constants for a compiled code object via co_consts.

>>> source = """
... a = 123456
... b = 234567
... c = 345678
... d = 123456
... """
>>> code = compile(source, "<>", "exec")
>>> code.co_consts
(123456, 234567, 345678, None)
https://en.xdnf.cn/q/119408.html

Related Q&A

Remove values before and after special character

I have a dataframe, df, where I would like to remove the values that come before the underscore _ and after the underscore _ , essentially, keeping the middle. Also keeping the digits at the end and co…

Python selection sort

Question: The code is supposed to take a file (that contains one integer value per line), print the (unsorted) integer values, sort them, and then print the sorted values.Is there anything that doesnt…

Simple inheritance issue with Django templates

just getting started in Django, and I have some problems with the inheritances. It just seems that the loop for doesnt work when inheriting other template. Heres my code in base.html:<!DOCTYPE html&…

Replacing values in a list [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.This question was caused by a typo or a problem that can no longer be reproduced. While similar q…

Azure Release Pipeline - Environment variables on python script

Lately Ive been requested to run a python script on my Azure Release Pipeline. This script needs some environment variables for being executed, as Ive seen that in the build pipeline, the task include …

Problem with python prepared stmt parameter passing

File C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\mysql\connector\cursor.py, line 1149, in execute elif len(self._prepared[parameters]) != len(params): TypeError: object of ty…

list of lists to list of tuples without loops or list comprehensions [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 6 years ago.Improve…

How can I merge CSV rows that have the same value in the first cell?

This is the file: https://drive.google.com/file/d/0B5v-nJeoVouHc25wTGdqaDV1WW8/view?usp=sharingAs you can see, there are duplicates in the first column, but if I were to combine the duplicate rows, no…

i usually get this error : ValueError: invalid literal for int() with base 10

I have loaded a csv file and as i try to print it i get this error Traceback (most recent call last):File "C:\Users\FSTC\Downloads\spaceproject\main.py", line 389, in <module>world_data…

How to Draw a triangle shape in python? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 1…