unexpected from/import statement behaviour

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

    unexpected from/import statement behaviour

    Hi all !

    I'm trying to capture stderr of an external module I use in my python
    program. I'm doing this
    by setting up a class in my module overwriting the stderr file object
    method write.
    The external module outputs to stderr this way:

    from sys import std err

    .....

    print >stderr, "Some text"

    While in my module I use

    import sys

    ..... sys.stderr ... sys.stdout

    Well, as long as I do not change in the external module those from/
    import statements to just

    import sys

    .....

    print >sys.stderr, "Some text"

    I'm not able to capture its stderr and of course I would like not to
    do this kind of change.
    I've always been convinced of the equivalence of the two ways of using
    the import statement
    but it's clear I'm wrong :-(

    Please, someone can tell me what's going on ?

    Thanks in advance !
  • Diez B. Roggisch

    #2
    Re: unexpected from/import statement behaviour

    nisp schrieb:
    Hi all !
    >
    I'm trying to capture stderr of an external module I use in my python
    program. I'm doing this
    by setting up a class in my module overwriting the stderr file object
    method write.
    The external module outputs to stderr this way:
    >
    from sys import std err
    >
    ....
    >
    print >stderr, "Some text"
    >
    While in my module I use
    >
    import sys
    >
    ..... sys.stderr ... sys.stdout
    >
    Well, as long as I do not change in the external module those from/
    import statements to just
    >
    import sys
    >
    ....
    >
    print >sys.stderr, "Some text"
    >
    I'm not able to capture its stderr and of course I would like not to
    do this kind of change.
    I've always been convinced of the equivalence of the two ways of using
    the import statement
    but it's clear I'm wrong :-(
    >
    Please, someone can tell me what's going on ?


    Diez

    Comment

    • alex23

      #3
      Re: unexpected from/import statement behaviour

      nisp <emanuele.nesp. ..@gmail.comwro te:
      I've always been convinced of the equivalence of the two ways of using
      the import statement but it's clear I'm wrong :-(
      Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
      [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
      Type "help", "copyright" , "credits" or "license" for more information.
      >>from sys import stderr
      >>import sys
      >>sys.stderr is stderr
      True

      Behaviourly, I'm finding no difference between the two either.

      Could you cut & paste a minimal example that isn't producing the
      correct behaviour, and perhaps mention what type of OS you're using?

      Comment

      • Diez B. Roggisch

        #4
        Re: unexpected from/import statement behaviour

        alex23 schrieb:
        nisp <emanuele.nesp. ..@gmail.comwro te:
        >I've always been convinced of the equivalence of the two ways of using
        >the import statement but it's clear I'm wrong :-(
        >
        Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
        [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
        Type "help", "copyright" , "credits" or "license" for more information.
        >>>from sys import stderr
        >>>import sys
        >>>sys.stderr is stderr
        True
        >
        Behaviourly, I'm finding no difference between the two either.
        >
        Could you cut & paste a minimal example that isn't producing the
        correct behaviour, and perhaps mention what type of OS you're using?
        You did not read this part of the post:

        """
        I'm not able to capture its stderr and of course I would like not to
        do this kind of change.
        """

        He tries to set sys.stderr to a new stream and capture the print
        statements, but fails to do so because he created a local alias.


        Diez

        Comment

        • Peter Otten

          #5
          Re: unexpected from/import statement behaviour

          nisp wrote:
          Hi all !
          >
          I'm trying to capture stderr of an external module I use in my python
          program. I'm doing this
          by setting up a class in my module overwriting the stderr file object
          method write.
          The external module outputs to stderr this way:
          >
          from sys import std err
          >
          ....
          >
          print >stderr, "Some text"
          >
          While in my module I use
          >
          import sys
          >
          ..... sys.stderr ... sys.stdout
          >
          Well, as long as I do not change in the external module those from/
          import statements to just
          >
          import sys
          >
          ....
          >
          print >sys.stderr, "Some text"
          >
          I'm not able to capture its stderr and of course I would like not to
          do this kind of change.
          I've always been convinced of the equivalence of the two ways of using
          the import statement
          but it's clear I'm wrong :-(
          >
          Please, someone can tell me what's going on ?
          >
          Thanks in advance !
          A practical approach to complement Diez' link to the explanation:

          Instead of modifying the external module you can either redirect stderr
          before you import the external module

          import sys
          sys.stderr = whatever
          import external

          or monkey-patch:

          import sys
          import external

          sys.stderr = external.sterr = whatever

          Peter

          Comment

          • nisp

            #6
            Re: unexpected from/import statement behaviour

            On Aug 27, 9:56 am, Peter Otten <__pete...@web. dewrote:
            nisp wrote:
            Hi all !
            >
            I'm trying to capture stderr of an external module I use in my python
            program. I'm doing this
            by setting up a class in my module overwriting the stderr file object
            method write.
            The external module outputs to stderr this way:
            >
            from sys import std err
            >
            ....
            >
            print >stderr, "Some text"
            >
            While in my module I use
            >
            import sys
            >
            ..... sys.stderr ... sys.stdout
            >
            Well, as long as I do not change in the external module those from/
            import statements to just
            >
            import sys
            >
            ....
            >
            print >sys.stderr, "Some text"
            >
            I'm not able to capture its stderr and of course I would like not to
            do this kind of change.
            I've always been convinced of the equivalence of the two ways of using
            the import statement
            but it's clear I'm wrong :-(
            >
            Please, someone can tell me what's going on ?
            >
            Thanks in advance !
            >
            A practical approach to complement Diez' link to the explanation:
            >
            Instead of modifying the external module you can either redirect stderr
            before you import the external module
            >
            import sys
            sys.stderr = whatever
            import external
            >
            or monkey-patch:
            >
            import sys
            import external
            >
            sys.stderr = external.sterr = whatever
            >
            Peter
            Hi all !

            Thanks first of all ! I read the interesting Diez's link but something
            still remains to me unclear, on the other hand it's clear the my
            problem is concentrated there and on symbols.
            Here is what I'm trying to do

            HelloWorld.py: this is a real simplification of my external module
            though still reflecting its structure (commented out is the version
            that, let's say, works)

            from sys import stderr
            #import sys

            class Cheers:
            def __init__(self):
            self.cheersMsg = 'Hello World !!'
            print "Cheers stderr %s" % stderr
            #print "Cheers stderr %s" % sys.stderr
            def _putCheers(self ):
            print>>stderr, 'Here is my msg:', self.cheersMsg
            print>>stderr, 'This is a nice day today !!'
            #print>>sys.std err, 'Here is my msg:', self.cheersMsg
            #print>>sys.std err, 'This is a nice day today !!'
            def doSomeStuff(sel f):
            self._putCheers ()

            And below there is the module that uses the above one (mymodule.py):

            #!/usr/bin/python

            import sys
            from HelloWorld import *

            class StderrCatcher:
            def __init__(self):
            self.data = ''
            def write(self,stuf f):
            self.data = self.data + "\t" + stuff


            def main():

            print "mymodule stderr: %s" % sys.stderr

            sys.stderr = stderr = StderrCatcher()
            m = Cheers()
            m.doSomeStuff()
            print "stderr: \n%s" % sys.stderr.data

            if __name__ == '__main__':
            main()


            Below there is the output when it doesn't work:

            mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7d160b0>
            Cheers stderr <open file '<stderr>', mode 'w' at 0xb7d160b0>
            Here is my msg: Hello World !!
            This is a nice day today !!
            stderr:

            And here when it works:

            mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7dc40b0>
            Cheers stderr <__main__.Stder rCatcher instance at 0xb7d8bd4c>
            stderr:
            Here is my msg: Hello World !!
            This is a nice day today !!


            Thanks again!

            PS Sorry for having probably replied to somone of you directly :-(

            Comment

            • Diez B. Roggisch

              #7
              Re: unexpected from/import statement behaviour

              nisp wrote:
              On Aug 27, 9:56 am, Peter Otten <__pete...@web. dewrote:
              >nisp wrote:
              Hi all !
              >>
              I'm trying to capture stderr of an external module I use in my python
              program. I'm doing this
              by setting up a class in my module overwriting the stderr file object
              method write.
              The external module outputs to stderr this way:
              >>
              from sys import std err
              >>
              ....
              >>
              print >stderr, "Some text"
              >>
              While in my module I use
              >>
              import sys
              >>
              ..... sys.stderr ... sys.stdout
              >>
              Well, as long as I do not change in the external module those from/
              import statements to just
              >>
              import sys
              >>
              ....
              >>
              print >sys.stderr, "Some text"
              >>
              I'm not able to capture its stderr and of course I would like not to
              do this kind of change.
              I've always been convinced of the equivalence of the two ways of using
              the import statement
              but it's clear I'm wrong :-(
              >>
              Please, someone can tell me what's going on ?
              >>
              Thanks in advance !
              >>
              >A practical approach to complement Diez' link to the explanation:
              >>
              >Instead of modifying the external module you can either redirect stderr
              >before you import the external module
              >>
              >import sys
              >sys.stderr = whatever
              >import external
              >>
              >or monkey-patch:
              >>
              >import sys
              >import external
              >>
              >sys.stderr = external.sterr = whatever
              >>
              >Peter
              >
              Hi all !
              >
              Thanks first of all ! I read the interesting Diez's link but something
              still remains to me unclear, on the other hand it's clear the my
              problem is concentrated there and on symbols.
              Here is what I'm trying to do
              >
              HelloWorld.py: this is a real simplification of my external module
              though still reflecting its structure (commented out is the version
              that, let's say, works)
              >
              from sys import stderr
              This is your problem. You create a HelloWorld.stde rr-alias to the object
              bound to sys.stderr. Rebinding the latter won't affect the former. That is
              precisely what the link I gave you explains.

              The short answer to the whole issue is: dont' use the from-import syntax
              until you really know what you are doing. Or not at all.

              Diez

              Comment

              • nisp

                #8
                Re: unexpected from/import statement behaviour

                On Aug 27, 2:43 pm, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                nisp wrote:
                On Aug 27, 9:56 am, Peter Otten <__pete...@web. dewrote:
                nisp wrote:
                Hi all !
                >
                I'm trying to capture stderr of an external module I use in my python
                program. I'm doing this
                by setting up a class in my module overwriting the stderr file object
                method write.
                The external module outputs to stderr this way:
                >
                from sys import std err
                >
                ....
                >
                print >stderr, "Some text"
                >
                While in my module I use
                >
                import sys
                >
                ..... sys.stderr ... sys.stdout
                >
                Well, as long as I do not change in the external module those from/
                import statements to just
                >
                import sys
                >
                ....
                >
                print >sys.stderr, "Some text"
                >
                I'm not able to capture its stderr and of course I would like not to
                do this kind of change.
                I've always been convinced of the equivalence of the two ways of using
                the import statement
                but it's clear I'm wrong :-(
                >
                Please, someone can tell me what's going on ?
                >
                Thanks in advance !
                >
                A practical approach to complement Diez' link to the explanation:
                >
                Instead of modifying the external module you can either redirect stderr
                before you import the external module
                >
                import sys
                sys.stderr = whatever
                import external
                >
                or monkey-patch:
                >
                import sys
                import external
                >
                sys.stderr = external.sterr = whatever
                >
                Peter
                >
                Hi all !
                >
                Thanks first of all ! I read the interesting Diez's link but something
                still remains to me unclear, on the other hand it's clear the my
                problem is concentrated there and on symbols.
                Here is what I'm trying to do
                >
                HelloWorld.py: this is a real simplification of my external module
                though still reflecting its structure (commented out is the version
                that, let's say, works)
                >
                from sys import stderr
                >
                This is your problem. You create a HelloWorld.stde rr-alias to the object
                bound to sys.stderr. Rebinding the latter won't affect the former. That is
                precisely what the link I gave you explains.
                >
                The short answer to the whole issue is: dont' use the from-import syntax
                until you really know what you are doing. Or not at all.
                >
                Diez
                Hi Diez! I well understand the problem now, the fact is that
                unfortunately the external module is not mine and i doubt i can change
                it :-( Anyway as far as i'm concerned i've learned the lesson ! Thanks
                again and greetings,
                Nisp

                Comment

                • Peter Otten

                  #9
                  Re: unexpected from/import statement behaviour

                  nisp wrote:
                  Thanks first of all ! I read the interesting Diez's link but something
                  still remains to me unclear, on the other hand it's clear the my
                  problem is concentrated there and on symbols.
                  Read it again. If you have two modules

                  module1.py
                  from sys import stderr

                  module2.py
                  from module1 import stderr

                  you get three names 'stderr' in three different namespaces, and each name
                  may bind a different object.

                  Here is what I'm trying to do
                  >
                  HelloWorld.py: this is a real simplification of my external module
                  though still reflecting its structure (commented out is the version
                  that, let's say, works)
                  >
                  from sys import stderr
                  #import sys
                  >
                  class Cheers:
                          def __init__(self):
                                  self.cheersMsg = 'Hello World !!'
                                  print "Cheers stderr %s" % stderr
                                  #print "Cheers stderr %s" % sys.stderr
                          def _putCheers(self ):
                                  print>>stderr, 'Here is my msg:', self.cheersMsg
                                  print>>stderr, 'This is a nice day today !!'
                                  #print>>sys.std err, 'Here is my msg:', self.cheersMsg
                                  #print>>sys.std err, 'This is a nice day today !!'
                          def doSomeStuff(sel f):
                                  self._putCheers ()
                  >
                  And below there is the module that uses the above one (mymodule.py):
                  >
                  #!/usr/bin/python
                  >
                  import sys
                  This imports HelloWorld.stde rr:
                  from HelloWorld import *
                  You now have a global variable 'stderr' in module __main__, initialized to
                  the same value as HelloWorld.stde rr.
                  class StderrCatcher:
                          def __init__(self):
                                  self.data = ''
                          def write(self,stuf f):
                                  self.data = self.data + "\t" + stuff
                  >
                  >
                  def main():
                  >
                          print "mymodule stderr: %s" % sys.stderr
                  >
                  This rebinds sys.stderr and a local 'stderr' in main()
                          sys.stderr = stderr = StderrCatcher()
                  but both HelloWorld.stde rr and __main__.stderr are unaffected. What you need
                  is
                  import HelloWorld
                  sys.stderr = HelloWorld.stde rr = StderrCatcher()
                          m = Cheers()
                          m.doSomeStuff()
                          print "stderr: \n%s" % sys.stderr.data
                  >
                  if __name__ == '__main__':
                      main()
                  >
                  >
                  Below there is the output when it doesn't work:
                  >
                  mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7d160b0>
                  Cheers stderr <open file '<stderr>', mode 'w' at 0xb7d160b0>
                  Here is my msg: Hello World !!
                  This is a nice day today !!
                  stderr:
                  >
                  And here when it works:
                  >
                  mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7dc40b0>
                  Cheers stderr <__main__.Stder rCatcher instance at 0xb7d8bd4c>
                  stderr:
                          Here is my msg:         Hello World !!
                          This is a nice day today !!
                  >
                  >
                  Thanks again!
                  >
                  PS Sorry for having probably replied to somone of you directly :-(

                  Comment

                  • alex23

                    #10
                    Re: unexpected from/import statement behaviour

                    On Aug 27, 5:42 pm, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                    alex23 schrieb:
                    >
                    >
                    >
                    nisp <emanuele.nesp. ..@gmail.comwro te:
                    I've always been convinced of the equivalence of the two ways of using
                    the import statement but it's clear I'm wrong :-(
                    >
                    Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
                    [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
                    Type "help", "copyright" , "credits" or "license" for more information.
                    >>from sys import stderr
                    >>import sys
                    >>sys.stderr is stderr
                    True
                    >
                    Behaviourly, I'm finding no difference between the two either.
                    >
                    Could you cut & paste a minimal example that isn't producing the
                    correct behaviour, and perhaps mention what type of OS you're using?
                    >
                    You did not read this part of the post:
                    >
                    """
                    I'm not able to capture its stderr and of course I would like not to
                    do this kind of change.
                    """
                    >
                    He tries to set sys.stderr to a new stream and capture the print
                    statements, but fails to do so because he created a local alias.
                    No, I read it, I just totally didn't parse it that way :)

                    Sorry for the confusion, nisp.

                    Comment

                    • nisp

                      #11
                      Re: unexpected from/import statement behaviour

                      On Aug 27, 3:35 pm, Peter Otten <__pete...@web. dewrote:
                      nisp wrote:
                      Thanks first of all ! I read the interesting Diez's link but something
                      still remains to me unclear, on the other hand it's clear the my
                      problem is concentrated there and on symbols.
                      >
                      Read it again. If you have two modules
                      >
                      module1.py
                      from sys import stderr
                      >
                      module2.py
                      from module1 import stderr
                      >
                      you get three names 'stderr' in three different namespaces, and each name
                      may bind a different object.
                      >
                      >
                      >
                      Here is what I'm trying to do
                      >
                      HelloWorld.py: this is a real simplification of my external module
                      though still reflecting its structure (commented out is the version
                      that, let's say, works)
                      >
                      from sys import stderr
                      #import sys
                      >
                      class Cheers:
                      def __init__(self):
                      self.cheersMsg = 'Hello World !!'
                      print "Cheers stderr %s" % stderr
                      #print "Cheers stderr %s" % sys.stderr
                      def _putCheers(self ):
                      print>>stderr, 'Here is my msg:', self.cheersMsg
                      print>>stderr, 'This is a nice day today !!'
                      #print>>sys.std err, 'Here is my msg:', self.cheersMsg
                      #print>>sys.std err, 'This is a nice day today !!'
                      def doSomeStuff(sel f):
                      self._putCheers ()
                      >
                      And below there is the module that uses the above one (mymodule.py):
                      >
                      #!/usr/bin/python
                      >
                      import sys
                      >
                      This imports HelloWorld.stde rr:
                      >
                      from HelloWorld import *
                      >
                      You now have a global variable 'stderr' in module __main__, initialized to
                      the same value as HelloWorld.stde rr.
                      >
                      class StderrCatcher:
                      def __init__(self):
                      self.data = ''
                      def write(self,stuf f):
                      self.data = self.data + "\t" + stuff
                      >
                      def main():
                      >
                      print "mymodule stderr: %s" % sys.stderr
                      >
                      This rebinds sys.stderr and a local 'stderr' in main()
                      >
                      sys.stderr = stderr = StderrCatcher()
                      >
                      but both HelloWorld.stde rr and __main__.stderr are unaffected. What you need
                      is
                      import HelloWorld
                      sys.stderr = HelloWorld.stde rr = StderrCatcher()
                      >
                      m = Cheers()
                      m.doSomeStuff()
                      print "stderr: \n%s" % sys.stderr.data
                      >
                      if __name__ == '__main__':
                      main()
                      >
                      Below there is the output when it doesn't work:
                      >
                      mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7d160b0>
                      Cheers stderr <open file '<stderr>', mode 'w' at 0xb7d160b0>
                      Here is my msg: Hello World !!
                      This is a nice day today !!
                      stderr:
                      >
                      And here when it works:
                      >
                      mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7dc40b0>
                      Cheers stderr <__main__.Stder rCatcher instance at 0xb7d8bd4c>
                      stderr:
                      Here is my msg: Hello World !!
                      This is a nice day today !!
                      >
                      Thanks again!
                      >
                      PS Sorry for having probably replied to somone of you directly :-(
                      Hi Peter!

                      Definitely you are right ! May be this time I understood completely
                      the topic (or may be not ?... gosh !) ... I didn't considered well the
                      "from HelloWolrd import *" in mymodule.py.
                      Now my module is:

                      import sys
                      import HelloWorld

                      class StderrCatcher:
                      def __init__(self):
                      self.data = ''
                      def write(self,stuf f):
                      self.data = self.data + "\t" + stuff


                      def main():

                      print "mymodule stderr: %s" % sys.stderr

                      mystderr = sys.stderr = HelloWorld.stde rr = StderrCatcher()
                      m = HelloWorld.Chee rs()
                      m.doSomeStuff()
                      print >>sys.stderr, "mymodule prints something"
                      print "stderr: \n%s" % mystderr.data

                      if __name__ == '__main__':
                      main()

                      and its output is:

                      mymodule stderr: <open file '<stderr>', mode 'w' at 0xb7d2d0b0>
                      Cheers stderr <__main__.Stder rCatcher instance at 0xb7cf4e4c>
                      stderr:
                      Here is my msg: Hello World !!
                      This is a nice day today !!
                      mymodule prints something

                      now it works perfectly !

                      Great ! Thanks to all of you !

                      Nisp

                      Comment

                      Working...