TheAlgorithms/Python · error · TypeError

Hand should be of type 'str': {hand!r}

Error message

Hand should be of type 'str': {hand!r}

What it means

Raised by the PokerHand constructor in project_euler/problem_054/sol1.py when the hand argument is not a str. Hands are expected as a single string of five space-separated cards such as '6S 4C KC AS TH'; passing a list of cards, a tuple, or None triggers this TypeError before any parsing happens.

Source

Thrown at project_euler/problem_054/sol1.py:124

        """
        Initialize hand.
        Hand should of type str and should contain only five cards each
        separated by a space.

        The cards should be of the following format:
        [card value][card suit]

        The first character is the value of the card:
        2, 3, 4, 5, 6, 7, 8, 9, T(en), J(ack), Q(ueen), K(ing), A(ce)

        The second character represents the suit:
        S(pades), H(earts), D(iamonds), C(lubs)

        For example: "6S 4C KC AS TH"
        """
        if not isinstance(hand, str):
            msg = f"Hand should be of type 'str': {hand!r}"
            raise TypeError(msg)
        # split removes duplicate whitespaces so no need of strip
        if len(hand.split(" ")) != 5:
            msg = f"Hand should contain only 5 cards: {hand!r}"
            raise ValueError(msg)
        self._hand = hand
        self._first_pair = 0
        self._second_pair = 0
        self._card_values, self._card_suit = self._internal_state()
        self._hand_type = self._get_hand_type()
        self._high_card = self._card_values[0]

    @property
    def hand(self):
        """Returns the self hand"""
        return self._hand

    def compare_with(self, other: PokerHand) -> str:
        """

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass one space-separated string: PokerHand('6S 4C KC AS TH').
  2. Join list/tuple inputs: PokerHand(' '.join(cards)).
  3. Decode bytes before constructing: PokerHand(raw.decode()).
  4. Add a type guard or assert at the boundary where hands enter your pipeline.

Example fix

# before
hand = ['6S', '4C', 'KC', 'AS', 'TH']
p = PokerHand(hand)  # TypeError

# after
p = PokerHand(' '.join(hand))
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(cards, (list, tuple)):
    hand = ' '.join(cards)
elif isinstance(hand_input, bytes):
    hand = hand_input.decode()
else:
    hand = hand_input
assert isinstance(hand, str)
PokerHand(hand)

Type guard

def is_hand_string(value) -> bool:
    return isinstance(value, str)

Try / catch

try:
    poker_hand = PokerHand(raw)
except TypeError:
    poker_hand = PokerHand(' '.join(raw))  # retry with normalized input
except ValueError:
    logger.error("malformed hand: %r", raw)
    raise

Prevention

When it happens

Trigger: PokerHand(['6S','4C','KC','AS','TH']) (list instead of string), PokerHand(None), PokerHand(b'6S 4C') (bytes), or PokerHand(123). Any non-str type, even if it contains valid card text.

Common situations: Reading hands from CSV/pandas where a row splits into a list of fields; passing bytes from file reads without decode; refactoring from list-based to string-based API and missing a call site.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/30004b8bae5f2681. Report an issue: GitHub.