1

When I execute a Python script(*) and the end of the file is reached, I get back to the command prompt without any additional messages displayed. I would like to know whether there's a statement I can insert somewhere in the source file in order to "exit the file" (end interpretation & compilation) at that point, i.e., ignore its contents from there up to the end of the file (or alternatively, to ignore a large region as I could do in C using an #if 0 preprocessor directive and the corresponding #endif), so I could leave notes and code snippets etc. below that point while I'm working on the earlier part of the file.

When I use quit(), exit(), raise SystemExit(...) etc., all of these throw an exception leading to a "Traceback" message. Is there something like \endinput in (La)TeX which tells the interpreter to simply ignore the rest of the file, as if the end-of-file was already reached, or the cpp directives #if 0 ... #endif?

The question "How to exit... without Traceback..." is many times asked and answered here on SO, but the answer is always "you can't"; "it must be that way to allow cleanup / debugging ..." (some mention os._exit() then others say "no-no because of incomplete cleanup"). Maybe this refers to exiting from "within something", but maybe I'm in that case because my file is read by some other python function. So I'm rather looking for a command which says "Here's the end of this file!" or "Ignore the subsequent lines of the input file up to the end (or up to the corresponding #endignore directive is such exists.)

PS: I know that I could put the rest of the file within """...""", but that would work only up to where I already have a multi-line comment in my "scratch area". Yes, I could [and do] use """ for multi-line commands and ''' to "comment out" the rest of the file. But I consider that as a workaround, and not answer to my question whether such a command or directive exists.

(*) To explain further my need for such a solution: I have this problem on pythonanywhere.com which I have to use for professional (educational) reasons. Clicking on "Run" executes a command _pa_run("filename") on their server (probably a custom command made by them), maybe that's why exit() or sys.exit() yield that Traceback.

EDIT: Upon request, I'll add a specific example (although unrealistic, for sake of brevity):

def Newton(f,x0,eps,N):
    """here I implement Newton's method"""
    #(...) iterations go here (...)
    return x
def f(x): #function for testing
   return ...

quit() # Unfortunately this raises a Traceback, at least when the file is "Run" 
# on pythonanywhere.com. I'd like to avoid this. I would simply like everything
# to be ignored after this point, let's say "for convenience", to simplify.
# I'd like to know whether this is possible, in the given configuration.

def f(x):# this is another function for testing
   return [something else]
[...] # another formula to try. This is just a snippet and might not compile.
def Newton(...):# the old version. Not yet trashed because maybe needed.
      # Would have to rename this if the whole file is read by the compiler.

# Below follow more routines which are part of the final version of this file, 
# but I don't want to compile all of them each time, while I fiddle around with
# the latest addition, for now put the beginning of the file.
# OTOH I would like to have that code in the same file for easier copy-paste in
# case I need some parts of it while developing the new stuff at top of file.
Max
  • 415
  • 5
  • 12
  • It sounds like you should just comment out that stuff you want to leave at the end. It'll be much cleaner than trying to exit abruptly, and it'll avoid a few other issues you probably haven't thought of yet (like what happens if you do this in an imported module). – user2357112 Jan 16 '20 at 04:59
  • (Also, under normal circumstances, all those things you say cause a traceback actually *don't* cause a traceback.) – user2357112 Jan 16 '20 at 05:01
  • 1
    Does this answer your question? [How to exit from Python without traceback?](https://stackoverflow.com/questions/1187970/how-to-exit-from-python-without-traceback) `import os;os._exit(1)` – Prayson W. Daniel Jan 16 '20 at 05:10
  • If you reach the end of the file, there is no traceback because no exceptions are raised. If calling `exit()` raises an exception, you're probably in the middle of something that needs to be terminated in a more robust fashion. Without a more specific example, it's hard to say what that is in your case. – Grismar Jan 16 '20 at 05:17
  • @user23457112 Thanks but in case it's not obvious, I could use this mainly during the "development process". Yes, it's mainly for convenience, to avoid use of a second editor with the "notes and unfinished code" (and maybe a third for the full source file holding many other routines it must provide but of which only a few but not all need to be compiled each time while I'm experimenting with the latest addition. Anyway, I'm asking whether this is possible, not whether it is the best way to do things. Consider that it might be needed or at least handy in some situations. Thanks! :-) – Max Jan 16 '20 at 05:19
  • 1
    @PraysonW.Daniel: That's going to prevent any cleanup, and on a service like pythonanywhere, it's likely to kill a lot more than just "the script" you thought you were running. It's a very specialized tool with subtle and nasty consequences if you use it wrong, and this is definitely using it wrong. – user2357112 Jan 16 '20 at 05:33
  • @Max: Commenting out your unfinished code and notes should be *more* convenient and far more flexible than typing out an end-of-input marker in any decent editor. If it's not, you haven't learned how to use your editor properly, or you're using an unsuitable editor. – user2357112 Jan 16 '20 at 05:36
  • @user2357112supportsMonica As I explain, I have to use the editor on PythonAnywhere.com. It is for educational purpose. The students must be able to use it from home, and at university we did not yet manage to set up a better solution. – Max Jan 16 '20 at 06:42
  • To clarify: my question is similar to https://stackoverflow.com/questions/31969540/ignore-the-rest-of-the-python-file . But let's say it is specific to my need to use it on that web site, so "better use iPython" or Emacs or a shell script to put a `#` in front of each line, or any similar solution does not work. That's why __I'm asking whether such a directive exists__. – Max Jan 16 '20 at 06:46
  • 1
    @Max: PythonAnywhere's "comment selected code" shortcut is Ctrl-/, and you don't actually need to write your code in PythonAnywhere anyway. Also, if you're teaching university students, you should *definitely* avoid anything like what you're asking here (whether or not you plan to teach it to your students). Don't let PythonAnywhere's limitations shape your coding. – user2357112 Jan 16 '20 at 07:26
  • In contrast, commenting stuff out works whether you're doing it on pythonanywhere or in a more normal environment, and the only weird interaction you're likely to encounter with commenting stuff out is the fact that a comment isn't a valid block statement body. – user2357112 Jan 16 '20 at 07:50
  • 1
    (Also, `#if 0 ... #endif` has similar limitations to using multiline string literals. If you're worried about conflicts with multiline string literals in the ignored region, you could just use different quote types. `'''` for "real" strings and `"""` when you want to ignore stuff, for example.) – user2357112 Jan 16 '20 at 07:53

3 Answers3

4

Python is not like LaTeX though. It is possible to write a Python script in a style where there are no functions and no if __name__ == "__main__": so its flow of execution is from top to bottom, but that doesn't mean it's similar to LaTeX.

I would like to know whether there's a command to "exit" (end parsing / execution of) the script before the end of the file

I think your mental model of how a Python script is interpreted and executed is incongruent with what actually happens. First off, parsing the script isn't same as execution of it, so you need to consider them separately.

It seems like the LaTeX syntax being similar to a programming language is confusing you to search for a concept similar to \endinput where none exists. I don't think there is a way to stop the "parsing" of the script at any point and if you want part of the script not to "execute", you'll either need to call something like exit or return before you reach that part or wrap it in a comment block.

Emrah Diril
  • 1,687
  • 1
  • 19
  • 27
  • Emrah, I know this. That's why I put "exit" in quotes and (end parsing / execution) in parentheses. I wanted to express otherwise what I already expressed earlier, knowing that it would be less correct to say so. What I want, or more precisely: want to know whether it exists, is something equivalent to cutting off the rest of the file. I think in C it could be achieved using `#if 0`, telling cpp to ignore the rest. – Max Jan 16 '20 at 06:33
  • 1
    `#if` is a directive in C which is a way to talk to the compiler from the source code. As far as I know, there is no such built-in mechanism for Python. Doing a quick google search revealed this link with a few answers to replicate C directives in Python. Perhaps that will help you, please have a look: https://stackoverflow.com/questions/482014/how-would-you-do-the-equivalent-of-preprocessor-directives-in-python – Emrah Diril Jan 16 '20 at 17:48
  • Thanks, the link was interesting. (I know that Python is not like C nor like TeX. I cited these methods just to explain the desired result / feature.) But it's OK, I "give up", it seems the answer to my question (is _this_ possible in Python) is "no". Not a problem, I can work around. Thx again! – Max Jan 17 '20 at 02:22
  • 1
    In Perl, there are [`__END__`, `__DATA__`](https://perldoc.perl.org/perldata#Special-Literals) special literals for stop parsing the script or use the rest of file as filehandle. – Hans Ginzel Mar 03 '21 at 19:45
1

Treating this as an xy-problem

You want to do literate python programming

Literate Programming(LP)

My simple(istic) definition of LP is that LP inverts the "defaultiness" of code and comment.

Take C for example:

  • If you choose // to comment you need to put it n times for n lines
  • If you choose /* you've to be careful to avoid inside */

Why not say everything is a comment except lines starting with some character? This is the LP option. eg LiterateHaskell uses >

Python Literate programming

I don't really recommend these options since a literate programming model needs better to be supported by the language itself. See literate haskell

LP systems

A better option is to use an LP system. Eg

  • Jupyter
  • Emacs -> org mode -> babel

Taking your question "literally"(!!)

The problem is parsing — since python parses the whole program file before any execution you will almost certainly get SyntaxErrors if you throw random text at the interpreter. Python gives enough hooks for customizing the interpreter.

Rusi
  • 1,054
  • 10
  • 21
  • Yes, what I was looking for might have been a hook, but it seems that such an `@ignorethrest` hook does not exist. Yes, I know that Python parses the whole program, therefore the idea was to have some "preprocessor directive" that tells the parser where the program ends. – Max Apr 07 '21 at 20:52
0

In sys module, exit function is there. It will smoothly exit from the code.

Try using sys.exit(0)

rajeshkumargp
  • 105
  • 1
  • 11
  • When I use this it gives the message "Traceback (most recent call last): File "/home/.../NumberTheory.py", line 8, in sys.exit(0) SystemExit: 0 >>> [where I have put to indicate a newline]. – Max Jan 16 '20 at 06:27