Is there a way to do the following preprocessor directives in Python?
#if DEBUG
< do some code >
#else
< do some other code >
#endif
Is there a way to do the following preprocessor directives in Python?
#if DEBUG
< do some code >
#else
< do some other code >
#endif
There's __debug__
, which is a special value that the compiler does preprocess.
if __debug__:
print "If this prints, you're not running python -O."
else:
print "If this prints, you are running python -O!"
__debug__
will be replaced with a constant 0 or 1 by the compiler, and the optimizer will remove any if 0:
lines before your source is interpreted.
-O
there. :-) I didn't think this was possible before reading this! –
Lancinate assert
uses __debug__
which makes development assertions even more tangible: docs.python.org/2/reference/simple_stmts.html#assert –
Lancinate -O
stands for “optimize”; not that turn on debugging. –
Felizio I wrote a python preprocessor called pypreprocessor that does exactly what you're describing.
The source and documentation is available on GitHub.
The package can also be downloaded/installed through the PyPI.
Here's an example to accomplish what you're describing.
from pypreprocessor import pypreprocessor
pypreprocessor.parse()
#define debug
#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
pypreprocessor is capable of a lot more than just on-the-fly preprocessing. To see more use case examples check out the project on Google Code.
Update: More info on pypreprocessor
The way I accomplish the preprocessing is simple. From the example above, the preprocessor imports a pypreprocessor object that's created in the pypreprocessor module. When you call parse() on the preprocessor it self-consumes the file that it is imported into and generates a temp copy of itself that comments out all of the preprocessor code (to avoid the preprocessor from calling itself recursively in an infinite loop) and comments out all of the unused portions.
Commenting out the lines is, as opposed to removing them, is necessary to preserve line numbers on error tracebacks if the module throws an exception or crashes. And I've even gone as far as to rewrite the error traceback to report reflect the proper file name of the module that crashed.
Then, the generated file containing the postprocessed code is executed on-the-fly.
The upside to using this method over just adding a bunch of if statements inline in the code is, there will be no execution time wasted evaluating useless statements because the commented out portions of the code will be excluded from the compiled .pyc files.
The downside (and my original reason for creating the module) is that you can't run both python 2x and python 3x in the same file because pythons interpreter runs a full syntax check before executing the code and will reject any version specific code before the preprocessor is allowed to run ::sigh::. My original goal was to be able to develop 2x and 3x code side-by-side in the same file that would create version specific bytecode depending on what it is running on.
Either way, the preprocessor module is still very useful for implementing common c-style preprocessing capabilities. As well as, the preprocessor is capable of outputting the postprocessed code to a file for later use if you want.
Also, if you want to generate a version that has all of the preprocessor directives as well as any of the #ifdefs that are excluded removed it's as simple as setting a flag in the preprocessor code before calling parse(). This makes removing unwanted code from a version specific source file a one step process (vs crawling through the code and removing if statements manually).
pip install
is working (someone else already documented this issue in the repo). –
Grantley I suspect you're gonna hate this answer. The way you do that in Python is
# code here
if DEBUG:
#debugging code goes here
else:
# other code here.
Since python is an interpreter, there's no preprocessing step to be applied, and no particular advantage to having a special syntax.
You can use the preprocessor in Python. Just run your scripts through the cpp (C-Preprocessor) in your bin directory. However I've done this with Lua and the benefits of easy interpretation have outweighed the more complex compilation IMHO.
You can just use the normal language constructs:
DEBUG = True
if DEBUG:
# Define a function, a class or do some crazy stuff
def f():
return 23
else:
def f():
return 42
An alternative method is to use a bash script to comment out portions of code which are only relevant to debugging. Below is an example script which comments out lines that have a '#DEBUG' statement in it. It can also remove these comment markers again.
if [ "$1" == "off" ]; then
sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
echo "Debug mode to $1"
elif [ "$1" == "on" ]; then
sed -e '/#DEBUG/ s/^#//' -i *.py
echo "Debug mode to $1"
else
echo "usage: $0 on | off"
fi
Use a common m4 instead, like this:
ifelse(DEBUG,True,dnl`
< do some code >
dnl,dnl`
< do some other code >dnl
')
ifelse(
M4_CPU,x86_64,`
< do some code specific for M4_CPU >
',M4_CPU,arm,`
< do some code specific for M4_CPU >
',M4_CPU,ppc64le,`
< do some code specific for M4_CPU >
')
ifelse(
M4_OS,windows,`
< do some code specific for M4_OS >
',M4_OS,linux,`
< do some code specific for M4_OS >
',M4_OS,android,`
< do some code specific for M4_OS >
')
m4 -D DEBUG=True -D M4_OS=android -D M4_CPU=arm test.py.m4 > test.py
I use PIE. PIE is the best way to preprocess in Python 3. PIE allows you to do any sort of preprocessing in Python.
Here's an example to accomplish what you're describing.
#define debug
#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
© 2022 - 2024 — McMap. All rights reserved.