exec(code) not allowing import on top level?

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

    exec(code) not allowing import on top level?


    if I define a simple string code, with the following contents:

    import math
    def foo(x):
    return math.sqrt(x)

    and i run it using exec(code) in python, math is not known. But when I
    recode the string as:

    def foo(x):
    import math
    return math.sqrt(x)

    it works fine. That seemed like an inconsistency, since it works
    fine otherwise, as expected. It's easy to work around, but
    just odd to find this out.

    thanks

    peter
  • Gary Herron

    #2
    Re: exec(code) not allowing import on top level?

    Peter Teuben wrote:
    >
    if I define a simple string code, with the following contents:
    >
    import math
    def foo(x):
    return math.sqrt(x)
    What? You have not told us something important here. First, that code
    won't fail because it does not even execute the function foo -- it just
    defines it. Second, if I exend your string with one more line
    "foo(123)" to actually execute the code, it still works as expected.

    So let's try this again... and this time please please also show us the
    full text of the error message.

    Gary Herron

    >
    and i run it using exec(code) in python, math is not known. But when I
    recode the string as:
    >
    def foo(x):
    import math
    return math.sqrt(x)
    >
    it works fine. That seemed like an inconsistency, since it works
    fine otherwise, as expected. It's easy to work around, but
    just odd to find this out.
    >
    thanks
    >
    peter
    --
    http://mail.python.org/mailman/listinfo/python-list

    Comment

    • Gary Herron

      #3
      Re: exec(code) not allowing import on top level?

      Peter Teuben wrote:
      >
      if I define a simple string code, with the following contents:
      >
      import math
      def foo(x):
      return math.sqrt(x)
      What? You have not told us something important here. First, that code
      won't fail because it does not even execute the function foo -- it just
      defines it. Second, if I extended your string with one more line
      "foo(123)" to actually execute the code, it still works as expected.

      So let's try this again... and this time please please also show us the
      full text of the error message.

      Gary Herron

      >
      and i run it using exec(code) in python, math is not known. But when I
      recode the string as:
      >
      def foo(x):
      import math
      return math.sqrt(x)
      >
      it works fine. That seemed like an inconsistency, since it works
      fine otherwise, as expected. It's easy to work around, but
      just odd to find this out.
      >
      thanks
      >
      peter
      --
      http://mail.python.org/mailman/listinfo/python-list

      Comment

      • Steven D'Aprano

        #4
        Re: exec(code) not allowing import on top level?

        On Tue, 29 Jul 2008 03:26:45 +0000, Peter Teuben wrote:
        if I define a simple string code, with the following contents:
        >
        import math
        def foo(x):
        return math.sqrt(x)
        >
        and i run it using exec(code) in python, math is not known.

        Works for me.

        >>code = """import math
        .... def foo(x):
        .... return math.sqrt(x)
        .... """
        >>>
        >>exec code
        >>foo(25)
        5.0

        By the way, exec is a statement, not a function, so you don't need the
        brackets.



        --
        Steven

        Comment

        • Peter Otten

          #5
          Re: exec(code) not allowing import on top level?

          Peter Teuben wrote:
          >
          if I define a simple string code, with the following contents:
          >
          import math
          def foo(x):
          return math.sqrt(x)
          The

          import math

          statement puts 'math' in the local namespace, and foo looks it up in the
          global namespace. This can only work when these namespaces are the same:
          >>code = """
          .... import math
          .... def foo(x):
          .... return math.sqrt(x)
          .... print foo(2)
          .... """
          >>exec code in {}
          1.41421356237
          >>exec code in {}, {}
          Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "<string>", line 5, in <module>
          File "<string>", line 4, in foo
          NameError: global name 'math' is not defined

          You could argue that Python should always look into the local namespace and
          then fall back to the global namespace but that would be fruitless extra
          work in most cases. I think it can only hapen with exec/eval, and as you
          have seen in the other responses even there it works on the module level
          because -- tada!
          >>globals() is locals()
          True
          and i run it using exec(code) in python, math is not known. But when I
          recode the string as:
          >
          def foo(x):
          import math
          return math.sqrt(x)
          Here Python "guesses" that math is a local variable and that guess is
          correct. If you wrote

          import math
          def foo(x):
          return math.sqrt(x)
          math = 42

          Python would still guess that math is a local name and you would end up with
          a runtime exception.

          Peter

          Comment

          Working...