Skip to content

__debug__ enhancement and parse time constants #100339

Open
@nblzv

Description

@nblzv

In the spirit of the efforts being made by the faster-cpython team to improve performance, I think there is some low hanging fruit it terms of improving runtime performance by... not running code in the first place, since the fastest code is the one that never runs!

The lowest of all the hanging fruits would be turning debug into an int, allowing it to take on multiple values and as such allowing multiple debug levels to checked for. This would require minimal change to the codebase and command line option to support a number after the -O argument and the same number being stored for the .opt part of the .pyc files, i.e. -O3 would replace __debug__ with 3 instead of the current bool approach. This approach would allow developers to write as much debug code as they need, while also having it get compiled out completely when it's no needed, as opposed to the current approach of toggling if 0: blocks everywhere or commenting out the different tiers of debug code when not in use.

if __debug__:
    print("Debug mode")
if __debug__ >= 2:
    print("Verbose debug mode")
if __debug__ >= 3:
    print("Paranoid debug mode")

And while that would already bring a lot of value by itself with minimal changes, the natural extension to it is actual compile time constants, i.e. __debug__ but with different names, which would make things a lot more readable. This fruit is a few branches higher on the tree. One approach to implementing these compile time constants would be to add a const keyword which declares all the compile time constants used in the file, which would be used for syntax error purposes. And during compilation they would get turned into an actual constant similarly to __debug__, with the caveat that consts would evaluate to False if not explicitly defined. As to how they would be defined, might as well use the -O option again, i.e. -OFOO would define FOO as True during compilation, i.e.:

const FOO, BAZ

# Only one of the code paths should remain, based on whether -OFOO was passed when running python
if FOO:
    print("Foo defined")
else:
    print("Foo not defined")

# If not declared by -OBAZ, should be treated as False and the if should be compiled out completely
if BAZ:
    print("We got baz")

This change would also require changes to the .pyc files, either by storing a hash/all the compile time constants used in the file itself, or just generating a completely different .pyc with a hash of all the compile time constants in place of the .opt part of the filename.


And the natural extension to that would be supporting integer constants similar to the debug extension, or better yet and builtin type -- int, float or string (constants only of course). These again require a change to the command line option in the form of -OFOO=3, but if the previous two changes are implemented, shouldn't require too much compiler changes.


All of these changes combined would more of less bring python on par with C's #if/#ifdef statements and allow for copious amounts of debug code to remain in the codebases with zero cost for the (optimized) runtime, while only incurring a small overhead for the startup (unless already cached).

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions