Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_empty_entity_in_options():
parser = LogParser()
parser.read(StringIO(INITIAL_GAME))
parser.flush()
data = "target 0 entity="
with pytest.raises(ParsingError):
# This can happen, but the game is corrupt
parser.handle_options(None, data)
self._chosen_packet = packets.ChosenEntities(ts, player, id)
self.current_block.packets.append(self._chosen_packet)
return self._chosen_packet
elif data.startswith("Entities["):
sre = tokens.ENTITIES_CHOSEN_ENTITIES_RE.match(data)
if not sre:
raise RegexParsingError(data)
idx, entity = sre.groups()
id = self.parse_entity_or_player(entity)
if not id:
raise ParsingError("Missing entity chosen %r (%r)" % (id, entity))
if not self._chosen_packet:
raise ParsingError("Entity Chosen outside of choice packet: %r" % (data))
self._chosen_packet.choices.append(id)
if len(self._chosen_packet.choices) > self._chosen_packet_count:
raise ParsingError("Too many choices (expected %r)" % (self._chosen_packet_count))
return id
raise NotImplementedError("Unhandled entities chosen: %r" % (data))
if not sre:
raise RegexParsingError(data)
entity, = sre.groups()
id = self.parse_entity_or_player(entity)
if not self._choice_packet:
raise ParsingError("Source Choice Entity outside of choie packet: %r" % (data))
self._choice_packet.source = id
return id
elif data.startswith("Entities["):
sre = tokens.CHOICES_ENTITIES_RE.match(data)
if not sre:
raise RegexParsingError(data)
idx, entity = sre.groups()
id = self.parse_entity_or_player(entity)
if not id:
raise ParsingError("Missing choice entity %r (%r)" % (id, entity))
if not self._choice_packet:
raise ParsingError("Choice Entity outside of choice packet: %r" % (data))
self._choice_packet.choices.append(id)
return id
raise NotImplementedError("Unhandled entity choice: %r" % (data))
raise RegexParsingError(data)
error, error_param = clean_option_errors(error, error_param)
else:
sre = tokens.OPTIONS_OPTION_RE.match(data)
if not sre:
raise RegexParsingError(data)
optype, id, type, entity = sre.groups()
error, error_param = None, None
id = int(id)
type = parse_enum(enums.OptionType, type)
if entity:
entity = self.parse_entity_or_player(entity)
self._option_packet = packets.Option(ts, entity, id, type, optype, error, error_param)
if not self._options_packet:
raise ParsingError("Option without a parent option group: %r" % (data))
self._options_packet.options.append(self._option_packet)
self._suboption_packet = None
return self._option_packet
"""
Log parsing exceptions
"""
class ParsingError(Exception):
pass
class RegexParsingError(ParsingError):
pass
def hide_entity(self, ts, entity, tag, value):
id = parse_entity_id(entity)
tag, value = parse_tag(tag, value)
if tag != GameTag.ZONE:
raise ParsingError("HIDE_ENTITY got non-zone tag (%r)" % (tag))
packet = packets.HideEntity(ts, id, value)
self.current_block.packets.append(packet)
return packet
def full_entity(self, ts, id, card_id):
id = int(id)
self._entity_packet = packets.FullEntity(ts, id, card_id)
self.current_block.packets.append(self._entity_packet)
if self._creating_game:
# First packet after create game should always be a FULL_ENTITY
self._creating_game = False
# It should always have ID 4
if id != 4:
raise ParsingError("Expected entity 4 after creating game, got %r" % (id))
# While we're at it, we check if we got an abnormal amount of players
player_count = len(self._game_packet.players)
if player_count != 2:
raise ParsingError("Expected exactly 2 players, got %r" % (player_count))
return self._entity_packet
available as early as before. That means games conceded at Mulligan no
longer have player names.
This technique uses the cards offered in Mulligan instead, registering
the name of the packet's entity with the card's controller as PlayerID.
"""
lazy_player = packet.entity
if isinstance(lazy_player, int) or lazy_player.id:
# The player is already registered, ignore.
return
if not lazy_player.name:
# If we don't have the player name, we can't use this at all
return
for choice in packet.choices:
if choice not in self._entity_controller_map:
raise ParsingError("Unknown entity ID in choice: %r" % (choice))
player_id = self._entity_controller_map[choice]
# We need ENTITY_ID for register_player_name()
entity_id = int(self._players_by_player_id[player_id])
packet.entity = entity_id
return self.register_player_name(lazy_player.name, entity_id)
if " errorParam=" in data:
sre = tokens.OPTIONS_SUBOPTION_ERROR_RE.match(data)
if not sre:
raise RegexParsingError(data)
optype, id, entity, error, error_param = sre.groups()
error, error_param = clean_option_errors(error, error_param)
else:
sre = tokens.OPTIONS_SUBOPTION_RE.match(data)
if not sre:
raise RegexParsingError(data)
optype, id, entity = sre.groups()
error, error_param = None, None
id = int(id)
if not entity:
raise ParsingError("SubOption / target got an empty entity: %r" % (data))
entity = self.parse_entity_or_player(entity)
packet = packets.Option(ts, entity, id, None, optype, error, error_param)
if optype == "subOption":
self._suboption_packet = packet
node = self._option_packet
elif optype == "target":
node = self._suboption_packet or self._option_packet
node.options.append(packet)
return packet