0

I'm getting weird NameError! i have a bash script who checks CPU status, puts it inside file (linux, btw), then executes python script who's doing the math, then runs another script that checks which core in working too hard, creates a file with the core number (so I can later check if the right core is still working too hard) and then sends mail if its the first time the core reaches over 90%.

Now, here's the problem! when i'm running the "SendMail.py" script (will add it below) i'm getting NameError: global name 'smtplib' is not defined. Yes, i've imported it. and when I run the script without the other script lunches it - everything works well and i'm getting my email!

so - here's my script... will be glad if anyone might help :)

Ofek.

#!/usr/bin/python
import os
import smtplib
with open("/linux/sendmail",'r') as nas_file:
    success=nas_file.read()

print(success)
def send_mail(msg):
    fromaddr = 'XXXXX'
    toaddrs  = 'XXXXX'


    # Credentials (if needed)
    username = 'XXXXX'
    password = 'XXXXX'

    # The actual mail send
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddrs, msg)
    server.quit()
    return
if True:
    send_mail(success)

Traceback:

Traceback (most recent call last):
  File "cpu_check.py", line 51, in <module>
    scancores()
  File "cpu_check.py", line 35, in scancores
    execfile("SendMail.py")
  File "SendMail.py", line 25, in <module>
    send_mail(success)
  File "SendMail.py", line 18, in send_mail
    server = smtplib.SMTP('smtp.gmail.com:587')
NameError: global name 'smtplib' is not defined
Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127
Ofek Ortal
  • 27
  • 1
  • 1
  • 7
  • 1
    Post the complete traceback. – Ilja Everilä Jun 13 '16 at 06:56
  • Traceback (most recent call last): File "cpu_check.py", line 51, in scancores() File "cpu_check.py", line 35, in scancores execfile("SendMail.py") File "SendMail.py", line 25, in send_mail(success) File "SendMail.py", line 18, in send_mail server = smtplib.SMTP('smtp.gmail.com:587') NameError: global name 'smtplib' is not defined – Ofek Ortal Jun 13 '16 at 06:59
  • So the error is raised by your other script, and you're not importing `smtplib` there, right? – Tim Pietzcker Jun 13 '16 at 07:05
  • indeed. thank you :) can you explain why it happens? I mean, i didn't used smtplib at the second file... – Ofek Ortal Jun 13 '16 at 07:08
  • 2
    Out of interest. Why are you using `execfile` to run the above code? You should really put all the code in functions so that you can just import it and call the functions when needed. – SiHa Jun 13 '16 at 08:01

1 Answers1

1

It does not work for the same reason the following code:

class Test:
  import math
  def fn():
    print(math.sin(1))
  fn() # NameError: name 'math' is not defined

From the documentation of execfile:

execfile(filename[, globals[, locals]])

...

The arguments are a file name and two optional dictionaries. The file is parsed and evaluated as a sequence of Python statements (similarly to a module) using the globals and locals dictionaries as global and local namespace. If provided, locals can be any mapping object. Remember that at module level, globals and locals are the same dictionary. If two separate objects are passed as globals and locals, the code will be executed as if it were embedded in a class definition.

Changed in version 2.4: formerly locals was required to be a dictionary.

If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where execfile() is called. The return value is None.

I assume you did not specify any additional parameters to execfile, so globals and locals default to the current execution environment, which basically behaves like the Test class above.

How to solve this? Don't use execfile. Use modules or subprocess.call instead:

# SendMail.py

#!/usr/bin/python
import os
import smtplib

def send_mail(msg):
    ...

def run():
    with open("/linux/sendmail",'r') as nas_file:
        success=nas_file.read()
    print(success)
    send_mail(success)

if __name__ == "__main__":
    run()

# cpu_check.py

import SendMail
...

SendMail.run() # instead of execfile("SendMail.py")
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97