python-chess
python-chess copied to clipboard
PGN parser fails to parse PGN which starts from space
PGN standard suggests that PGN should be whitespace agnostic.
Example reproducer (note the space before the "[Event") fails with:
illegal san: 'ca7' in rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 while parsing <Game at 0x758ae0b35b20 ('?' vs. '?', '????.??.??' at '?')>
[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "?"]
[Black "?"]
[Result "*"]
*
#!/bin/env python3
import chess.pgn
from io import StringIO
PGN=""" [Event "TCEC Season 27 - Entrance League"]
[Site "https://tcec-chess.com"]
[Date "2024.10.25"]
[Round "13.6"]
[White "Patricia 3.1_dev_ca7ef0a3"]
[Black "Weiss 2.1-dev11"]
[Result "*"]
[WhiteElo "3317"]
[WhiteTitle "BOT"]
[BlackElo "3367"]
[BlackTitle "BOT"]
[TimeControl "1800+3"]
[Termination "unterminated"]
[Variant "Standard"]
[ECO "A55"]
[Opening "Old Indian Defense: Normal Variation"]
[Annotator "https://lichess.org/broadcast/-/-/0tQJxXbA"]
1. d4 { [%clk 0:30:00] } 1... Nf6 { [%clk 0:30:00] } 2. c4 { [%clk 0:30:00] } 2... d6 { [%clk 0:30:00] } 3. Nc3 { [%clk 0:30:00] } 3... e5 { [%clk 0:30:00] } 4. Nf3 { [%clk 0:30:00] } 4... Nbd7 { [%clk 0:30:00] } 5. e4 { [%clk 0:30:00] } 5... Be7 { [%clk 0:30:00] } 6. Be2 { [%clk 0:30:00] } 6... O-O { [%clk 0:30:00] } 7. O-O { [%clk 0:30:00] } 7... c6 { [%clk 0:30:00] } 8. Qc2 { [%clk 0:30:00] } 8... a6 { [%clk 0:30:00] } 9. h3 { [%clk 0:28:06] } 9... Re8 { [%clk 0:29:15] } 10. Be3 { [%clk 0:26:40] } 10... exd4 { [%clk 0:28:23] } 11. Nxd4 { [%clk 0:25:45] } 11... Bf8 { [%clk 0:27:37] } 12. Rad1 { [%clk 0:24:46] } 12... g6 { [%clk 0:24:56] } 13. Rfe1 { [%clk 0:22:15] } 13... Qc7 { [%clk 0:24:15] } 14. a3 { [%clk 0:20:51] } 14... b5 { [%clk 0:23:21] } 15. Nf3 { [%clk 0:20:08] } 15... Bb7 { [%clk 0:22:46] } 16. Bd3 { [%clk 0:18:28] } 16... Rad8 { [%clk 0:22:09] } 17. Bf1 { [%clk 0:17:26] } 17... Nc5 { [%clk 0:21:21] } 18. Bxc5 { [%clk 0:16:26] } 18... dxc5 { [%clk 0:20:50] } 19. e5 { [%clk 0:15:28] } 19... Rxd1 { [%clk 0:20:19] } 20. Qxd1 { [%clk 0:14:34] } 20... Nd7 { [%clk 0:19:45] } 21. e6 { [%clk 0:13:40] } 21... Rxe6 { [%clk 0:19:06] } 22. Rxe6 { [%clk 0:13:18] } 22... fxe6 { [%clk 0:18:36] } 23. Ne4 { [%clk 0:12:32] } 23... Be7 { [%clk 0:18:08] } 24. Qe1 { [%clk 0:11:24] } 24... Ne5 { [%clk 0:17:42] } 25. Nfd2 { [%clk 0:09:50] } 25... Qd8 { [%clk 0:17:11] } 26. Qc1 { [%clk 0:08:33] } *"""
game = chess.pgn.read_game(StringIO(PGN))
print(game)
Hi, I can confirm this problem.
I have fixed it (locally) by adding to png.py the line line = line.strip(" ") at lines 1571-1572, like:
while line:
line = line.strip(" ")
# Ignore comments.
if line.startswith("%") or line.startswith(";"):
line = handle.readline()
continue
What do you think? Would it be OK?