0

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)

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

6 Comments

And most of the OP code's method definitions are missing self args, too.
@PM2Ring yep, you're right. Coming from java - these function calls are implicit there
@nsmirosh: Fair enough. We do OOP a little differently in Python. But I'm sure you'll soon get the hang of it. :)
@PM2Ring Why do you need to pass 'self' everywhere in functions?
@nsmirosh: you only need those in methods, because that's how Python gives you access to the current instance.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.