nsmirosh
nsmirosh

Reputation: 125

global name is not defined python

I get a NameError: global name 'valid_username' is not defined which confuses me. Why does that happen? I declared the valid_username function before actually calling it so what's the problem?

Here's the code full code:

import webapp2
import cgi
import re

class WelcomeHandler(webapp2.RequestHandler):
    def get(self):
        self.response.out.write("Welcome, ")


class MainPage(webapp2.RequestHandler):
    def write_form(self, username="", username_error="", password_error="", verify_password_error="", email="",
                   email_error=""):
        self.response.out.write(form % {
            "username": username, "username_error": username_error,
            "password_error": password_error,
            "verify_password_error": verify_password_error,
            "email": email, "email_error": email_error})

    def checkEscaped(text):
        return cgi.escape(text, quote="True")

    def valid_username(username):
        USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
        return USER_RE.match(checkEscaped(username))

    def valid_password(password):
        PASSWORD_RE = re.compile(r"^.{3,20}$")
        return PASSWORD_RE.match(checkEscaped(password))

    def valid_email(email):
        if len(email) > 0:
            EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
            return EMAIL_RE.match(checkEscaped(email))
        else:
            return True

    def password_match(password, confirmPassword):
        return password == confirmPassword

    def get(self):
        self.write_form()

    def post(self):
        input_username = self.request.get('username')
        input_password = self.request.get('password')
        input_verify_password = self.request.get('verify_password')
        input_email = self.request.get('email')

        username_error = ""
        is_valid_name = valid_username(input_username)
        if not is_valid_name:
            username_error = "That's not a valid username."

        password_error = ""
        is_valid_password = valid_password(input_password)
        if not is_valid_password:
            password_error = "That wasn't a valid password."

        verify_password_error = ""
        is_valid_verify_password = password_match(input_password, input_verify_password)
        if not is_valid_verify_password:
            verify_password_error = "the passwords don't match"

        email_error = ""
        is_valid_email = valid_email(input_email)
        if not is_valid_email:
            email_error = "that's not a valid email"

        if not (is_valid_name and is_valid_password and is_valid_verify_password and is_valid_email):
            self.write_form(name, username_error, password_error, verify_password_error, email, email_error)
        else:
            self.redirect("/welcome")


app = webapp2.WSGIApplication([
    ('/', MainPage), ('/welcome', WelcomeHandler)], debug=True)

Upvotes: 0

Views: 675

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124538

You need to reference methods on the instance via the self object:

is_valid_password = self.valid_password(input_password)

You have the same problem in other places too; checkEscaped() should be self.checkEscaped(), password_match() should be self.password_match(), etc.

Methods are not globals or locals.

Next, your methods should accept a self reference too; each of your own methods is missing the required parameter:

def checkEscaped(self, text):
    # ...

def valid_username(self, username):
    # ...

def valid_password(self, password):
    # ...

def valid_email(self, email):
    # ...

def password_match(self, password, confirmPassword):
    # ...

Of course, you could just move those four methods out of the class and actually make them global functions instead of methods. In that case, leave off the self arguments again.

Upvotes: 3

Related Questions