docs: def password(
              self,
              length=10,
              special_chars=True,
              digits=True,
              upper_case=True,
              lower_case=True):
          """
          Generates a random password.
          @param length: Integer. Length of a password
          @param special_chars: Boolean. Whether to use special characters !@#$%^&*()_+
          @param digits: Boolean. Whether to use digits
          @param upper_case: Boolean. Whether to use upper letters
          @param lower_case: Boolean. Whether to use lower letters
          @return: String. Random password
          """
          choices = ""
          required_tokens = []
          if special_chars:
              required_tokens.append(
                  self.generator.random.choice("!@#$%^&*()_+"))
              choices += "!@#$%^&*()_+"
          if digits:
              required_tokens.append(self.generator.random.choice(string.digits))
              choices += string.digits
          if upper_case:
              required_tokens.append(
                  self.generator.random.choice(string.ascii_uppercase))
              choices += string.ascii_uppercase
          if lower_case:
              required_tokens.append(
                  self.generator.random.choice(string.ascii_lowercase))
              choices += string.ascii_lowercase
  
          assert len(
              required_tokens) <= length, "Required length is shorter than required characters"
  
          # Generate a first version of the password
          chars = self.random_choices(choices, length=length)
  
          # Pick some unique locations
          random_indexes = set()
          while len(random_indexes) < len(required_tokens):
              random_indexes.add(
                  self.generator.random.randint(0, len(chars) - 1))
  
          # Replace them with the required characters
          for i, index in enumerate(random_indexes):
              chars[index] = required_tokens[i]
  
          return ''.join(chars)