code: def login(self, user=None, password=None, restrict_login=None):
          
          if self.api_key:
              raise ValueError("cannot login when using an API key")
  
          if user:
              self.user = user
          if password:
              self.password = password
  
          if not self.user:
              raise ValueError("missing username")
          if not self.password:
              raise ValueError("missing password")
  
          if restrict_login:
              log.info("logging in with restrict_login=True")
  
          try:
              ret = self._login(self.user, self.password, restrict_login)
              self.password = ''
              log.info("login successful for user=%s", self.user)
              return ret
          except Fault as e:
              raise BugzillaError("Login failed: %s" % str(e.faultString))
docs: Attempt to log in using the given username and password. Subsequent
          method calls will use this username and password. Returns False if
          login fails, otherwise returns some kind of login info - typically
          either a numeric userid, or a dict of user info.
  
          If user is not set, the value of Bugzilla.user will be used. If *that*
          is not set, ValueError will be raised. If login fails, BugzillaError
          will be raised.
  
          The login session can be restricted to current user IP address
          with restrict_login argument. (Bugzilla 4.4+)
  
          This method will be called implicitly at the end of connect() if user
          and password are both set. So under most circumstances you won't need
          to call this yourself.