exception handling in complex Python programs

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lie

    #31
    Re: exception handling in complex Python programs

    On Aug 21, 12:59 am, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com .auwrote:
    On Wed, 20 Aug 2008 09:23:22 -0700, dbpoko...@gmail .com wrote:
    On Aug 19, 4:12 pm, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com .auwrote:
    On Tue, 19 Aug 2008 11:07:39 -0700, dbpoko...@gmail .com wrote:
      def do_something(fi lename):
        if not os.access(filen ame,os.R_OK):
          return err(...)
        f = open(filename)
        ...
    >
    You're running on a multitasking modern machine, right? What happens
    when some other process deletes filename, or changes its permissions,
    in the time after you check for access but before you actually open it?
    >
    This is a good point - if you want to use the correct way of opening
    files, and
    you don't want to worry about tracking down exception types, then we can
    probably
    agree that the following is the simplest, easiest-to-remember way:
    >
      def do_something(fi lename):
        try:
          f = open(filename)
        except:
          <handle exception>
    >
    No, we don't agree that that is the correct way of opening files. Simple
    it might be, but correct it is not.
    >
    If you're using Python 2.6 or greater, then you should be using a with
    block to handle file opening.
    >
    And regardless of which version of Python, you shouldn't use a bare
    except. It will mask exceptions you *don't* want to catch, including
    programming errors, typos and keyboard interrupts.
    >
    Opening files is a special case where EAFP is the only correct solution
    (AFAIK). I still liberally sprinkle LBYL-style "assert isinstance(...) "
    >
    Oh goodie. Another programmer who goes out of his way to make it hard for
    other programmers, by destroying duck-typing.
    >
    BTW, assertions aren't meant for checking data, because assertions can be
    turned off. Outside of test frameworks (e.g. unit tests), assertions are
    meant for verifying program logic:
    >
    def foo(x):
        # This is bad, because it can be turned off at runtime,
        # destroying your argument checking.
        assert isinstance(x, int)
        # And it raises the wrong sort of exception.
    >
        # This is better (but not as good as duck-typing).
        if not isinstance(x, int):
            raise TypeError('x not an int')
            # And it raises the right sort of error.
    >
        y = some_function(x )
        # y should now be between -1 and 1.
        assert -1 < y < 1
        do_something_wi th(y)
    >
    and other similar assertions in routines. The point is that EAFP
    conflicts with the interest of reporting errors as soon as possible
    >
    Not necessarily. Tell me how this conflicts with reporting errors as soon
    as possible:
    >
    def do_something(fi lename):
        try:
            f = open(filename)
        except IOError, e:
            report_exceptio n(e)  # use a GUI, log to a file, whatever...
    >
    How could you report the exception any earlier than immediately?
    I'm sure different people would have different view on what
    immediately means. The LBYL supporters define immediately as
    immediately after a definite potential problem is detected (by ifs or
    assertion), while the EAFP supporters define immediately as
    immediately after a problem arises. No side is right or wrong, both
    have weakness and strength, but python-style programs are encouraged
    to use EAFP-style exception handling whenever feasible, but with the
    spirit of the Zen: "Special cases aren't special enough to break the
    rules, although practicality beats purity", if LBYL makes things much
    easier in that case, and doing EAFP would just convolute the code,
    then practicality beats purity.
    --
    Steven

    Comment

    • Bruno Desthuilliers

      #32
      Re: exception handling in complex Python programs

      Maric Michaud a écrit :
      Le Thursday 21 August 2008 09:34:47 Bruno Desthuilliers, vous avez écrit :
      >>The point
      >>is that EAFP conflicts with the interest of reporting errors as soon
      >>as possible (on which much has been written see, for instance Ch. 8 -
      >>Defensive Programming in Code Complete),
      >Defensive programming makes sense in the context of a low-level language
      > like C where errors can lead to dramatic results. In high-level
      >languages like Python, the worse thing that an unhandled exception can
      >cause is an abrupt termination of the process and a nice traceback on
      >screen.
      >
      ... and leave your datas in inconsistent state.
      Not all applications persist data, so this is an application-specific
      problem, to be solved at the application level - IOW, there's no
      one-size-fits-all solution here. Anyway: transactions management is not
      what I meant when talking about defensive programming.

      As far as I'm concerned, the only place where the defensive approach
      really makes sense whatever the language is when dealing with external
      datas (user inputs etc).
      So, what C or any other
      language could do worse to your application ?
      An error in a C program can do *way* worse than leave an application's
      data in inconsistent state. See ART for more on this:

      >In this context, defensive programming is mostly a waste of time
      >- if you can't *correctly* handle the exception where it happens, then
      >doing nothing is the better solution.
      >
      If I don't buy the argument
      cf above - maybe you buy it after all ?-)
      I actually agree with the conclusion. Each
      component of a program should try to manage only errors tied to their own
      logic and let pass others up to the gui logic for rendering errors the good
      way, persistence logic to rollback unwanted changes, and application logic to
      continue execution the right way. This is hard to do in C because you have no
      way to trap an error which happen randomly in the program, ie. a segfault
      will interrupt the execution anyway.
      Indeed.

      Comment

      • Lie

        #33
        Re: exception handling in complex Python programs

        On Aug 21, 2:34 pm, Bruno Desthuilliers <bruno.
        42.desthuilli.. .@websiteburo.i nvalidwrote:
        dbpoko...@gmail .com a écrit :
        >
        >
        >
        On Aug 19, 4:12 pm, Steven D'Aprano <st...@REMOVE-THIS-
        cybersource.com .auwrote:
        On Tue, 19 Aug 2008 11:07:39 -0700, dbpoko...@gmail .com wrote:
        >  def do_something(fi lename):
        >    if not os.access(filen ame,os.R_OK):
        >      return err(...)
        >    f = open(filename)
        >    ...
        You're running on a multitasking modern machine, right? What happens when
        some other process deletes filename, or changes its permissions, in the
        time after you check for access but before you actually open it?
        >
        This is a good point - if you want to use the correct way of opening
        files, and
        you don't want to worry about tracking down exception types, then we
        can probably
        agree that the following is the simplest, easiest-to-remember way:
        >
          def do_something(fi lename):
            try:
              f = open(filename)
            except:
              <handle exception>
            ...
        >
        Still not correct IMHO - bare except clauses are BAD. You want:
        >
              try:
                f = open(filename)
              except IOError, e:
                <handle exception>
        >
        Opening files is a special case where EAFP is the only correct
        solution (AFAIK). I still liberally sprinkle LBYL-style "assert
        isinstance(...) "
        >
        Which defeats the whole point of dynamic typing...
        >
        and other similar assertions in routines.
        The point
        is that EAFP conflicts with the interest of reporting errors as soon
        as possible (on which much has been written see, for instance Ch. 8 -
        Defensive Programming in Code Complete),
        >
        Defensive programming makes sense in the context of a low-level language
           like C where errors can lead to dramatic results. In high-level
        languages like Python, the worse thing that an unhandled exception can
        cause is an abrupt termination of the process and a nice traceback on
        screen. In this context, defensive programming is mostly a waste of time
        - if you can't *correctly* handle the exception where it happens, then
        doing nothing is the better solution.
        Ah... now I understand what the Zen is talking about when it said:
        "Now is better then never, although never is often better than *right*
        now." If you don't have all the necessary resources to fix an
        exception right now, don't try to fix it, instead let it propagate,
        and allow it to be handled in a level where there is enough
        information how to fix it.
        My 2 cents...
        Steven D'Aprano says:
        Exceptions can and often are anticipated. E.g. if you write code that
        opens a URL, you better anticipate that the server might reject your
        connection. You better expect to be asked for a cookie, or
        authentication. If you check for robots.txt, you better expect that it
        might not exist. That's all normal execution.
        I think we should change except: into expect:, it would confuse less,
        would it? It signifies that the program expects so and so kinds of
        exceptional situations. The try: should also be changed to... perhaps
        in:, block:, onthiscode:, etc (this paragraph is written with my taste
        buds on the part of my face below my eye and above my jaw)

        Comment

        • Wojtek Walczak

          #34
          Re: exception handling in complex Python programs

          On Fri, 22 Aug 2008 06:43:58 -0700 (PDT), Lie wrote:
          I think we should change except: into expect:, it would confuse less,
          would it? It signifies that the program expects so and so kinds of
          exceptional situations. The try: should also be changed to... perhaps
          in:, block:, onthiscode:, etc (this paragraph is written with my taste
          buds on the part of my face below my eye and above my jaw)
          IMO it's not even worth considering. Breaking all the python
          software that exists and moreover breaking the habits of programmists
          to gain *nothing* is a waste of time of so many people, that
          we should just forget it.


          --
          Regards,
          Wojtek Walczak,

          Comment

          • Maric Michaud

            #35
            Re: exception handling in complex Python programs

            Le Friday 22 August 2008 15:03:21 Bruno Desthuilliers, vous avez écrit :
            Maric Michaud a écrit :
            Le Thursday 21 August 2008 09:34:47 Bruno Desthuilliers, vous avez écrit :
            >The point
            >is that EAFP conflicts with the interest of reporting errors as soon
            >as possible (on which much has been written see, for instance Ch. 8 -
            >Defensive Programming in Code Complete),
            >
            Defensive programming makes sense in the context of a low-level language
            like C where errors can lead to dramatic results. In high-level
            languages like Python, the worse thing that an unhandled exception can
            cause is an abrupt termination of the process and a nice traceback on
            screen.
            ... and leave your datas in inconsistent state.
            >
            Not all applications persist data, so this is an application-specific
            problem, to be solved at the application level - IOW, there's no
            one-size-fits-all solution here.
            ... or lose open connection, reset sessions, etc.. it doesn't really matter
            what is lost when a program crash, if it can be restarted without changes it
            is hardly what I'd qualify a "dramatic result". It doesn't depend on the
            language what implications of an unhandled error are, It is always
            application-specific.
            Anyway: transactions management is not
            what I meant when talking about defensive programming.
            >
            As far as I'm concerned, the only place where the defensive approach
            really makes sense whatever the language is when dealing with external
            datas (user inputs etc).
            >
            I agree, this is my whole point, "whatever the language is".
            So, what C or any other
            language could do worse to your application ?
            >
            An error in a C program can do *way* worse than leave an application's
            data in inconsistent state. See ART for more on this:

            >
            I didn't read "dramatic results" in that sense, but with the meaning of a
            result that the program itself cannot handle.

            If the whole system crash due to an unhandled error in a program, once
            missile's dropped it doesn't really matter in which language it was written.
            Reliability of a system, as high-availability of an application, is mostly a
            problem beyond the scope of application level error checking.
            In this context, defensive programming is mostly a waste of time
            - if you can't *correctly* handle the exception where it happens, then
            doing nothing is the better solution.
            If I don't buy the argument
            >
            cf above - maybe you buy it after all ?-)
            >
            I actually agree with the conclusion. Each
            component of a program should try to manage only errors tied to their own
            logic and let pass others up to the gui logic for rendering errors the
            good way, persistence logic to rollback unwanted changes, and application
            logic to continue execution the right way. This is hard to do in C
            because you have no way to trap an error which happen randomly in the
            program, ie. a segfault will interrupt the execution anyway.
            >
            Indeed.
            --
            http://mail.python.org/mailman/listinfo/python-list


            --
            _____________

            Maric Michaud

            Comment

            • Gabriel Genellina

              #36
              Re: exception handling in complex Python programs

              En Thu, 21 Aug 2008 14:48:45 -0300, magloca <magloca@mailin ater.com>
              escribió:
              Bruno Desthuilliers @ Thursday 21 August 2008 17:31:
              >
              >Java's "checked exception" system has proven to be a total disaster.
              >
              Could you elaborate on that? I'm not disagreeing with you (or agreeing,
              for that matter); I'd just really like to know what you mean by
              a "total disaster."
              Please allow me to share a few links:


              and see also a message from Richard Levasseur today in this very thread
              explaining why checked exceptions are just an annoyance that buys you
              nothing.

              --
              Gabriel Genellina

              Comment

              Working...