This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients David MacIver, Kevin Shweh, Tijs Van Oevelen, abarry, arigo, donmez, ezio.melotti, fijall, mark.dickinson, ncoghlan, r.david.murray, rhettinger, serhiy.storchaka, torsten, vstinner
Date 2016-01-20.14:15:03
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1453299304.84.0.626182935135.issue25843@psf.upfronthosting.co.za>
In-reply-to
Content
Let me try to explain this issue again.

"f1, f2 = lambda: 1, lambda: 1.0" is compiled to two MAKE_FUNCTION instructions, MAKE_FUNCTION takes a code object as parameter (and a name). The Python compiler merges constants which are seen as "equal", with exceptions to not merge values of different types, or float of different sign.

Merging duplicate code objects is a cool micro optimization, I prefer to keep it. My patch keeps this micro optimization, but fix the bug: it ensures that equal constants having different types are not seen as equal. For example, 0 is equal to 0.0, but if when used for code constants, the code objects are seen a different.

Patch version 3:

* as suggested by Armin Rigo & Serhiy Storchaka: use id(obj) in the constant key for unknown constant types -- in practice, this patch is never taken, it's just to be extra safe (I checked manually by running the whole test suite when an assertion, assertion not in the posted patch)
* add a lot of unit tests
* add a documentation to _PyCode_ConstantKey()

@Serhiy: does it look good to you now?

> Would option (1) work if wrap 1 and 1.0 in a tuple? In a list? In a custom collection?

My patch now uses id(obj) in the "constant key" for unknown types. The compiler only emits simple type (int, str, ...), tuple, frozenset and code objects.

You *can* other types if you patch manually constants with custom objects, since code_richcomp() now uses the "constant key" function to compare constants. For example, my fat project has a replace_consts() function to inject builtin functions in constants:
http://fatoptimizer.readthedocs.org/en/latest/fat.html#replace_consts

There is also @asconstants decorator of codetransformer which allow to inject arbitrary types in function constants:
https://pypi.python.org/pypi/codetransformer
History
Date User Action Args
2016-01-20 14:15:05vstinnersetrecipients: + vstinner, arigo, rhettinger, mark.dickinson, ncoghlan, donmez, ezio.melotti, r.david.murray, torsten, fijall, serhiy.storchaka, David MacIver, abarry, Kevin Shweh, Tijs Van Oevelen
2016-01-20 14:15:04vstinnersetmessageid: <1453299304.84.0.626182935135.issue25843@psf.upfronthosting.co.za>
2016-01-20 14:15:04vstinnerlinkissue25843 messages
2016-01-20 14:15:04vstinnercreate