global name not defined

N

NetKev

I added a function 'warn_Admin' and defined it just before another
function 'process_log'. 'process_log' calls this warn_Admin' function.
However, when it gets called i get the following error every time:
---
Traceback (most recent call last):
File "/usr/bin/denyhosts.py", line 202, in ?
first_time, noemail, daemon)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
86, in __init__
last_offset)
File "/usr/lib/python2.3/site-packages/DenyHosts/daemon.py", line 74,
in createDaemon
apply(func, args)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
137, in runDaemon
purge_time, purge_sleep_ratio)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
178, in daemonLoop
last_offset = self.process_log(logfile, last_offset)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
380, in process_log
[warn_Admin(ip) for ip in new_denied_hosts]
NameError: global name 'warn_Admin' is not defined
--
If I take the two functions out of their current environment and store
them in test file and run it, it doesn't complain. I'm new to python
so I'm guessing there is some weird scope rule I am missing. I did try
'self.warn_Admin(ip)' just to be safe but then I got a 'too many
arguments' error?

I'm lost :)

the added function plus the header of the existing function(its too
large):
------------
def warn_Admin(warn_ip):
SENDMAIL = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % SENDMAIL, "w")
p.write("To: (e-mail address removed)\n")
p.write("Subject: test from denyhosts\n")
p.write("\n") # blank line separating headers from body
p.write("Some text\n")
p.write(warn_ip)
sts = p.close()
if sts != 0:
info("Sendmail exit status: %s", sts)
return sts


def process_log(self, logfile, offset):
-------------

the call to warn_Admin from process_log:
---
if new_denied_hosts:
info("new denied hosts: %s", str(new_denied_hosts))
#[info(ip) for ip in new_denied_hosts]
[warn_Admin(ip) for ip in new_denied_hosts]
else:
debug("no new denied hosts")

-kevin
 
P

Paul McGuire

NetKev said:
I added a function 'warn_Admin' and defined it just before another
function 'process_log'. 'process_log' calls this warn_Admin' function.
However, when it gets called i get the following error every time:
---
Traceback (most recent call last):
File "/usr/bin/denyhosts.py", line 202, in ?
first_time, noemail, daemon)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
86, in __init__
last_offset)
File "/usr/lib/python2.3/site-packages/DenyHosts/daemon.py", line 74,
in createDaemon
apply(func, args)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
137, in runDaemon
purge_time, purge_sleep_ratio)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
178, in daemonLoop
last_offset = self.process_log(logfile, last_offset)
File "/usr/lib/python2.3/site-packages/DenyHosts/deny_hosts.py", line
380, in process_log
[warn_Admin(ip) for ip in new_denied_hosts]
NameError: global name 'warn_Admin' is not defined
--
If I take the two functions out of their current environment and store
them in test file and run it, it doesn't complain. I'm new to python
so I'm guessing there is some weird scope rule I am missing. I did try
'self.warn_Admin(ip)' just to be safe but then I got a 'too many
arguments' error?

I'm lost :)

the added function plus the header of the existing function(its too
large):
------------
def warn_Admin(warn_ip):
SENDMAIL = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % SENDMAIL, "w")
p.write("To: (e-mail address removed)\n")
p.write("Subject: test from denyhosts\n")
p.write("\n") # blank line separating headers from body
p.write("Some text\n")
p.write(warn_ip)
sts = p.close()
if sts != 0:
info("Sendmail exit status: %s", sts)
return sts


def process_log(self, logfile, offset):
-------------

the call to warn_Admin from process_log:
---
if new_denied_hosts:
info("new denied hosts: %s", str(new_denied_hosts))
#[info(ip) for ip in new_denied_hosts]
[warn_Admin(ip) for ip in new_denied_hosts]
else:
debug("no new denied hosts")

-kevin

Sounds like warn_Admin is defined within a class.
a. could not resolve name when call was not qualified with "self."
b. when called as "self.warn_Admin", name was resolved, but got "too many
arguments" - this is because there was no explicit self argument in the
definition of warn_Admin.

It doesn't look like warn_Admin needs to be in the class. Move warn_Admin
to module-level scope, outside of the class containing process_log, and see
if things work better.

-- Paul


-- Paul
 
N

NetKev

You are probably right and I think I will do so but just for the sake
of my understanding of python...I noticed somthing. process_log takes
two arguments when called but it's definition has 3 and one of them is
"self". So I'm thinking if I modify my warn_Admin definition to
include "self" and then call it from process_log with
self.warn_Admin... it will work. This explains why I was getting the
"too many arguments" error.
 
P

Paul McGuire

NetKev said:
You are probably right and I think I will do so but just for the sake
of my understanding of python...I noticed somthing. process_log takes
two arguments when called but it's definition has 3 and one of them is
"self". So I'm thinking if I modify my warn_Admin definition to
include "self" and then call it from process_log with
self.warn_Admin... it will work. This explains why I was getting the
"too many arguments" error.

Yes. When you invoke self.warn_Admin(x), it calls warn_Admin with 2 args,
self and x.

The reason I did not suggest this is becaus it looked like warn_Admin didn't
really use anything inside self, so why make it a method?

Looks like you are getting the method/function concepts straight.

(I'm not trying to confuse you, but you could also make warn_Admin a
staticmethod within the class, using the @staticmethod decorator. Static
methods do not pass the self argument, so making warn_Admin into a static
method would be another way to resolve this problem. But only do this if
your class, whatever it is, has something inherently about it that wants its
own warn_Admin method - otherwise, just make it a global function.)

-- Paul
 
B

bruno at modulix

NetKev wrote:
(snip)
def process_log(self, logfile, offset):
if new_denied_hosts:
info("new denied hosts: %s", str(new_denied_hosts))
[warn_Admin(ip) for ip in new_denied_hosts]

This uselessly builds a list. List comprehension is meant to create
lists, not to replace for loops.

for ip in new_denied_hosts:
warn_admin(ip)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top