Does python have an EXIT_SUCCESS constant? - python

I'm returning 0 all over the place in a python script but would prefer something more semantic, something more readable. I don't like that magic number. Is there an idea in python similar to how in C you can return EXIT_SUCCESS instead of just 0?
I was unable to find it here:
https://docs.python.org/3.5/library/errno.html

I'm returning 0
return is not how you set your script's exit code in Python. If you want to exit with an exit code of 0, just let your script complete normally. The exit code will automatically be set to 0. If you want to exit with a different exit code, sys.exit is the tool to use.
If you're using return values of 0 or 1 within your code to indicate whether functions succeeded or failed, this is a bad idea. You should raise an appropriate exception if something goes wrong.

Since you discuss return here, it seems like you may be programming Python like C. Most Python functions should ideally be written to raise an exception if they fail, and the calling code can determine how to handle the exceptional conditions. For validation functions it's probably best to return True or False - not as literals, usually, but as the result of some expression like s.isdigit().
When talking about the return value of a process into its environment you caonnt use return because a module isn't a function, so a return statement at top level would be flagged as a syntax error. Instead you should use sys.exit.
Python might seem a little minimalist in this respect, but a call to sys.exit with no arguments defaults to success (i.e. return code zero). So the easiest way to simplify your program might be to stop coding it with an argument where you don't want to indicate failure!
As the documentation reminds us, integer arguments are passed back, and string arguments result in a return code of 1 and the string is printed to stderr.
The language doesn't, as far as I am aware, contain any constants (while it does have features specific to some environments, if it provided exit codes their values might need to be implementation- or platform-specific and the language developers prefer to avoid this where possible.

Related

Why does the Python console repeat back what input into it?

When I write something into the python console, it repeats back what I write.
Like if I write 1, it displays 1 in output, and if I write True it gives True.
Why is this?
Example:
>>1
1
>>True
True
What actually happens in background?
You're typing into a REPL. It Reads input, Evaluates it, Prints the result, then Loops back and starts again.
You're having it read the number 1, evaluate it (although it's just a number), then print the result of the evaluation (the number). After that it waits for more input to be entered so it can run again.
If you typed a more complicated expression, it would be evaluated as well. 1 + 1 will show 2, and [1] * 5 will show [1, 1, 1, 1, 1] for example.
If you want to think about how this is achieved in terms of code, the most basic implementation of a REPL would be something along the lines of:
while True:
user_input = input(">> ")
result = eval(user_input) # eval evaluates a string as code
print(result)
Code similar to this (although likely far more complicated) is just running in the background.
You're talking about one way to invoke the Python interpreter.
This is a computer program designed to accept Python statements, and to print the evaluated result of each one.
In your examples, your statements are simple expressions that evaluate to pretty much what you typed in.
More complex examples include expressions like 1+1, or function calls.
How this works "in [the] background" is far too large a topic for a Stack Overflow answer, but you could study the Python project's source code if you really wanted to know what kind of programming constructs have been used to produce this computer program.
Short answer:
Jeffrey Elkner in his book says that:
When you type a statement on the command line, Python executes it. The interpreter does not display any results....
An expression is a combination of values, variables, operators, and calls to functions. If you type an expression at the Python prompt, the interpreter evaluates it and displays the result, which is always a value
More details:
You know, what a computer really understands is consecutive zero's and one's.
Your hardware is the one who specifies the format of these one's and zero's.
it is hard for people to know about how to order a hardware to do a task. To solve this problem,high level languages and VHLL(very high-level programming languages) such as Python are created.
How do they solve the problem?
These languages are more similar to human languages. In addition, each of these languages has some tool to convert the code to a machine-readable format! (of course, without this, they were worth nothing)
Actually the tools used to convert a human-readable format to machine-readable format, fall into one of these categories: Interpreters, Compilers, Hybrid approach(used in languages like C# and Java).
Python code is executed using an Interpreter!
So when you type an expression or an statement, in python shell, the interpreter comes and executes the statements and evaluates the expressions in your code!
One final point:
Python docs considers expressions, just as a subset of statements(look at the link).

Python newbie problems

I just finished watching this video https://www.youtube.com/watch?v=qO4ZN5uZSVg, and even though it teaches 2.0 edition Python, some notes pop up for the 3.0 uses of python. Nevertheless, in the end, some challenges are provided, one of them is this:
def returnTwo():
return 20,30
x,y = returnTwo()
print(x,y)
Whenever i try to see what the conclusion will be, this is what comes up
def returnTwo():
return 20,30
(red X in the 3.5 Shell) x,y = returnTwo()
SyntaxError: invalid syntax.
What can I do?
The python shell allows to interactively run commands. This is very useful when doing quick calculations of to quickly check some small pieces of code.
In this case, you want to define a function. Defining a function is just that: a definition. Later on, you actually call the function and make it run. The issue here is that a function is (often) defined in more than one line. That means, you actually hit enter before you finish to define the function. For that reason, you tell the shell that you finished with an extra enter:
This also applies if you define your function in a single line:
And that's the reason why you get a SyntaxError: The line x, y = returnTwo() is supposed to be in the function, but for that, it would need to indented (to the level of return 20, 30):
Like #jim said, just try pressing enter until you get the >>> prompt again!
Remember that the three little dots do have a meaning too.
This question was already answered in the comments by #helios35 and #jim!
I just elaborate and post as an answer here for future users.

Python failure injection

Is there a neat way to inject failures in a Python script? I'd like to avoid sprinkling the source code with stuff like:
failure_ABC = True
failure_XYZ = True
def inject_failure_ABC():
raise Exception('ha! a fake error')
def inject_failure_XYZ():
# delete some critical file
pass
# some real code
if failure_ABC:
inject_failure_ABC()
# some more real code
if failure_XYZ:
inject_failure_XYZ()
# even more real code
Edit:
I have the following idea: insert "failure points" as specially-crafted comments. The write a simple parser that will be called before the Python interpreter, and will produce the actual instrumented Python script with the actual failure code. E.g:
#!/usr/bin/parser_script_producing_actual_code_and_calls python
# some real code
# FAIL_123
if foo():
# FAIL_ABC
execute_some_real_code()
else:
# FAIL_XYZ
execute_some_other_real_code()
Anything starting with FAIL_ is considered as a failure point by the script, and depending on a configuration file the failure is enabled/disabled. What do you think?
You could use mocking libraries, for example unittest.mock, there also exist many third party ones as well. You can then mock some object used by your code such that it throws your exception or behaves in whatever way you want it to.
When testing error handling, the best approach is to isolate the code that can throw errors in a new method which you can override in a test:
class ToTest:
def foo(...):
try:
self.bar() # We want to test the error handling in foo()
except:
....
def bar(self):
... production code ...
In your test case, you can extend ToTest and override bar() with code that throws the exceptions that you want to test.
EDIT You should really consider splitting large methods into smaller ones. It will make the code easier to test, to understand and to maintain. Have a look at Test Driven Development for some ideas how to change your development process.
Regarding your idea to use "Failure Comments". This looks like a good solution. There is one small problem: You will have to write your own Python parser because Python doesn't keep comments when it produces bytecode.
So you can either spend a couple of weeks to write this or a couple of weeks to make your code easier to test.
There is one difference, though: If you don't go all the way, the parser will be useless. Also, the time spent won't have improved one bit of your code. Most of the effort will go into the parser and tools. So after all that time, you will still have to improve the code, add failure comments and write the tests.
With refactoring the code, you can stop whenever you want but the time spent so far will be meaningful and not wasted. Your code will start to get better with the first change you make and it will keep improving.
Writing a complex tool takes time and it will have it's own bugs which need to fix or work around. None of this will improve your situation in the short term and you don't have a guarantee that it will improve the long term.
If you only want to stop your code at some point, and fall back to interactive interpreter, one can use:
assert 1==0
But this only works if you do not run python with -O
Edit
Actually, my first answer was to quick, without really understanding what you want to do, sorry.
Maybe your code becomes already more readable if you do parameterization through parameters, not through variable/function suffices. Something like
failure = {"ABC": False, "XYZ":False}
#Do something, maybe set failure
def inject_failure(failure):
if not any(failure.values()):
return
if failure["ABC"]:
raise Exception('ha! a fake error')
elif failure["XYZ"]:
# delete some critical file
pass
inject_failure(failure)

Python REPL: issuing commands in advance to execute after block

This is a bit of an odd question; it came up in the context of a tool that exposes a Python API, which we spend a lot of time querying interactively from the REPL. The particular idiom causing issues is something like this:
for var in slow_generator_of_giant_list():
stats = update(stats, var)
print stats
To enter this at the REPL, I can type this:
>>> for var in slow_generator_of_giant_list():
... stats = update(stats, var)
...
If I now attempt to type the print, I get a syntax error due to improper indentation. (Or else I put the print inside the loop and do it on every iteration.)
But if I hit enter to go to the next line, the loop runs immediately, and I have to wait for it to finish, or type the print command in the face of possible output coming at me, etc.
Obviously I can define a function containing the above, and it might be worth saving into a file anyway, but in the general case we're constructing these on the fly, and it would be nice to have a way to "schedule" a command to run after the end of a loop from the REPL. In a language with block delimiters, I could of course put it after the ending delimiter (and any necessary statement separator). But my coworkers and I were stumped trying to do something similar here.
Is there perhaps an ugly abuse of Pythonic syntax that will do the trick that my coworkers and I couldn't think of? Or a recommended way to avoid the problem while still making it easy to throw together ad hoc interactive queries?
Thanks for any pointers.
Not beautiful, but this should work:
>>> mygen = slow_generator_of_giant_list()
>>> try:
... while True: stats = update(stats, mygen.next())
... except StopIteration:
... print stats
...
I would just say that you would find it easier just to not use the interactive shell for this.
It's not much effort to save a file and run it. You only have to keep it around for as long as you use it.
I actually have found this answering on SO. I keep a file open in my text editor with a terminal in the right directory, and just use it as a scratchpad for mocking up answers in.

When would `if False` execute in Python?

While browsing some code, I came across this line:
if False: #shedskin
I understand that Shedskin is a kind of Python -> C++ compiler, but I can't understand that line.
Shouldn't if False: never execute? What's going on here?
For context:
This is the whole block:
if False: # shedskin
AStar(SQ_MapHandler([1], 1, 1)).findPath(SQ_Location(1,1), SQ_Location(1,1))
More context is on Google Code (scroll down all the way).
It won't execute, because it isn't supposed to. The if False: is there to intentionally prevent the next line from executing, because that code's only purpose is seemingly to help Shed Skin infer type information about the argument to the AStar() function.
You can see another example of this in httplib:
# Useless stuff to help type info
if False :
conn._set_tunnel("example.com")
It will never get executed. It's one way to temporarily disable part of the code.
Theoretically, it could get executed:
True, False = False, True
if False: print 'foo'
But typically this will be used to temporarily disable a code path.
You are correct in assuming that this will never evaluate to true. This is sometimes done when the programmer has a lot of debugging code but does not want to remove the debugging code in a release, so they just put if False: above it all.
not enough reputation to comment yet apparently, but tim stone's answer is correct. suppose we have a function like this:
def blah(a,b):
return a+b
now in order to perform type inference, there has to be at least one call to blah, or it becomes impossible to know the types of the arguments at compile-time.
for a stand-alone program, this not a problem, since everything that has to be compiled for it to run is called indirectly from somewhere..
for an extension module, calls can come from the 'outside', so sometimes we have to add a 'fake' call to a function for type inference to become possible.. hence the 'if False'.
in the shedskin example set there are a few programs that are compiled as extension modules, in order to be combined with for example pygame or multiprocessing.

Categories

Resources