Andrew
Andrew

Reputation: 8480

How to prevent a part of arbitrary code to be compiled in Python?

According to python documentation assert statements aren't included in code if it is compiled with -O key. I wondering if it is possible to emulate this behavior with any arbitrary piece of code?

For example, if I have a logger which is called heavily during execution I can benefit from eliminating if DEBUG: ... statements with all the code associated to them.

Upvotes: 1

Views: 148

Answers (2)

5gon12eder
5gon12eder

Reputation: 25439

Since Python is an interpreted language, it can't jump around in its own code. But you don't need a "special tool" to strip off parts of your code -- use Python for it!

Here is a minimal example. You'll probably want to put the strip_debug() function in your __init__.py and let it process a list of modules. Also, you'd probably want to add some additional check that the user really wants to modify the code, not just run it. Probably, using a command line option like --purge would be nice. You can then either make a copy of your library and once run

python __init__.py --purge

before you publish the library or leave it up to your users to do so.

#!/usr/bin/env python3.2

# BEGIN DEBUG
def _strip_debug():
    """
    Generates an optimized version of its own code stripping off all debugging
    code.

    """
    import os
    import re
    import shutil
    import sys
    import tempfile
    begin_debug = re.compile("^\s*#+\s*BEGIN\s+DEBUG\s*$")
    end_debug = re.compile("^\s*#+\s*END\s+DEBUG\s*$")
    tmp = None
    debug = False
    try:
        tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False)
        with open(sys.argv[0]) as my_code:
            for line in my_code:
                if begin_debug.match(line):
                    debug = True
                    continue
                elif end_debug.match(line):
                    debug = False
                    continue
                else:
                    if not debug:
                        tmp.write(line)
        tmp.close()
        shutil.copy(tmp.name, sys.argv[0])
    finally:
        os.unlink(tmp.name)
# END DEBUG    

def foo(bar, baz):
    """
    Do something weired with bar and baz.

    """
    # BEGIN DEBUG
    if DEBUG:
        print("bar = {}".format(bar))
        print("baz = {}".format(baz))
    # END DEBUG
    return bar + baz


# BEGIN DEBUG
if __name__ == "__main__":
    _strip_debug()
# END DEBUG

After executed, this file will only contain the functional code of the foo() function. I have used the special comments

# BEGIN DEBUG

and

# END DEBUG

in this example which allows to strip off arbitrary code but if it's just for removing

if DEBUG:
    # stuff

sections, it would also be pretty easy to detect those without any additional comments.

Upvotes: 2

BlackHatSamurai
BlackHatSamurai

Reputation: 23503

Why don't you just comment out the code you don't want the the # symbol?

Upvotes: 0

Related Questions