Skip to content

Commit

Permalink
Changes to public API (#10)
Browse files Browse the repository at this point in the history
* Add argument safety to several public methods

* Implement test for non existing tag in PGN file tags

* Remove redundant test and add safety to http conns

* Rename public methods to be shorter

* Bump version to minor and update README

* Add event getter, improve missing tag exception test

* Remove duplicate dependency pytest
  • Loading branch information
DaniruKun committed Nov 30, 2019
1 parent 0311a11 commit 161d8be
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 52 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ python setup.py install

```python
from pypgn.game import Game

# Importing game from file on disk
chess_game = Game('test.pgn')

print(chess_game.get_tag('Event'))
print(chess_game.get_result())
# Import game from Lichess
chess_game.pgn('dGm3ND39')

print(chess_game.tag('Event'))
print(chess_game.result())
# Print opening ply for white
print(chess_game.get_ply(1, 'w'))
print(chess_game.ply(1, 'w'))
```

Output:
Expand Down
39 changes: 19 additions & 20 deletions pypgn/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ def __init__(self, path: str = None):
self.tags: dict = _get_tags(self.pgn)
self.moves: List[Move] = _get_moves(self.pgn)

def open_pgn(self, path: str) -> None:
def pgn(self, path: str) -> None:
"""Sets the pgn attribute
:param path: path to pgn file or Lichess game ID
"""
self.pgn = _get_pgn_list(path)

def get_pgn_list(self) -> list:
def pgn_list(self) -> list:
"""Gets and returns a list of lines of the PGN
:return: a list of lines of the parsed PGN
:rtype: list
"""
return self.pgn

def get_tag(self, name: str) -> str:
def tag(self, name: str) -> str:
"""Gets and returns a tag for a given key name
:param name: Key name
Expand All @@ -62,15 +62,15 @@ def get_tag(self, name: str) -> str:
else:
raise KeyError(f"This tag does not exist: {name}")

def get_tags(self) -> dict:
def tags(self) -> dict:
"""Gets and returns a map of metadata tags of the PGN
:return: Map of PGN tags
:rtype: dict
"""
return self.tags

def get_move(self, index: int) -> Move:
def move(self, index: int) -> Move:
"""Gets and returns a move of a certain number
:param index: Move number
Expand All @@ -80,15 +80,7 @@ def get_move(self, index: int) -> Move:
"""
return self.moves[index - 1]

def get_moves(self) -> List[Move]:
"""Gets and returns a list of moves
:return: A list of Moves
:rtype: List[Move]
"""
return self.moves

def get_ply(self, index: int, player: str) -> str:
def ply(self, index: int, player: str) -> str:
"""Gets and returns a ply for a given move
:param index: Move number
Expand All @@ -100,30 +92,37 @@ def get_ply(self, index: int, player: str) -> str:
"""
return self.moves[index - 1][1 if 'w' in player.lower() else 2]

def get_move_count(self) -> int:
def move_count(self) -> int:
"""Gets and returns the total number of moves in the game
:return: Total number of moves
:rtype: int
"""
return len(self.moves)

def get_result(self) -> str:
def event(self) -> str:
"""Returns the name of the event if such exists
:return: Event name
"""
return self.tag('Event' if 'Event' in self.tags else '')

def result(self) -> str:
"""Gets and returns the game result
:return: Result of the game
:rtype: str
"""
return self.get_tag('Result')
return self.tag('Result')

def get_date(self) -> str:
def date(self) -> str:
"""Gets and returns the date of the game
:return: Date of the game in format YYYY.MM.DD
"""
return self.get_tag('Date' if 'Date' in self.tags else 'UTCDate')
return self.tag('Date' if 'Date' in self.tags else 'UTCDate')

def get_move_range(self, start: int = 1, end: int = None) -> List[Move]:
def move_range(self, start: int = 1, end: int = None) -> List[Move]:
"""Gets and returns a range of moves
:param start: Start index of moves to get
Expand Down
11 changes: 8 additions & 3 deletions pypgn/game_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
import http.client
from typing import List, NewType, Union
from http.client import HTTPException

Move = NewType('Move', Union[str, List])

Expand Down Expand Up @@ -59,8 +60,12 @@ def _get_lichess_pgn_lines(src: str) -> list:
game_id = src

conn.request("GET", endpoint + game_id + "?evals=0&clocks=0", payload)

res = conn.getresponse()
data = res.read()

return data.decode("utf-8").splitlines()
if res.status == 200:
data = res.read()
conn.close()
return data.decode("utf-8").splitlines()
else:
conn.close()
raise HTTPException(f'Unexpected status code! Expected: 200 Actual: {res.status}')
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ importlib-metadata==0.23
mccabe==0.6.1
more-itertools==7.2.0
packaging==19.2
pluggy==0.13.1
py==1.8.0
pycodestyle==2.5.0
pyflakes==2.1.1
pyparsing==2.4.5
pytest==5.3.0
six==1.13.0
wcwidth==0.1.7
zipp==0.6.0
pytest==5.2.4
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
name='pypgn',
long_description=long_description,
long_description_content_type='text/markdown',
version='0.4.2',
version='0.5.0',
packages=['pypgn'],
url='https://github.com/DaniruKun/pypgn',
license='MPL-2.0',
Expand Down
39 changes: 17 additions & 22 deletions test/test_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,47 @@ def game_pgn():

class TestGame:
def test_get_pgn_list(self, game_pgn):
assert len(game_pgn.get_pgn_list()) == 20

def test_get_tags(self, game_pgn):
assert type(game_pgn.get_tags()) == dict
assert len(game_pgn.pgn_list()) == 20

def test_get_tag(self, game_pgn):
assert game_pgn.get_tag('Event') == "Rated Blitz game"
assert game_pgn.get_tag('Site') == "https://lichess.org/#"
assert game_pgn.get_tag('UTCDate') == "2019.11.06"
assert game_pgn.tag('Event') == "Rated Blitz game"
assert game_pgn.tag('Site') == "https://lichess.org/#"
assert game_pgn.tag('UTCDate') == "2019.11.06"

def test_get_non_existing_tag(self, game_pgn):
with pytest.raises(KeyError):
game_pgn.get_tag('SomeTag')
tag = 'SomeTag'
with pytest.raises(KeyError, match=fr'{tag}'):
game_pgn.tag(tag)

def test_get_move(self, game_pgn):
assert game_pgn.get_move(4) == ["4.", "d4", "Nc6"]
assert game_pgn.move(4) == ["4.", "d4", "Nc6"]

def test_get_moves(self, game_pgn):
moves = game_pgn.get_moves()
moves = game_pgn.moves
assert type(moves) == list
assert moves[0] == ["1.", "e4", "c6"]

def test_get_ply(self, game_pgn):
for i in range(1, game_pgn.get_move_count()):
move = game_pgn.get_move(i)
assert move[1] == game_pgn.get_ply(i, 'w') and move[2] == game_pgn.get_ply(i, 'b'), \
for i in range(1, game_pgn.move_count()):
move = game_pgn.move(i)
assert move[1] == game_pgn.ply(i, 'w') and move[2] == game_pgn.ply(i, 'b'), \
"Non-matching ply pair at move %s !" % str(i)

def test_get_move_count(self, game_pgn):
assert game_pgn.get_move_count() == len(game_pgn.get_moves())

def test_get_result(self, game_pgn):
assert game_pgn.get_result() == game_pgn.get_tag('Result')
assert game_pgn.result() == game_pgn.tag('Result')

def test_get_date(self, game_pgn):
assert game_pgn.get_date() == game_pgn.get_tag('UTCDate')
assert game_pgn.date() == game_pgn.tag('UTCDate')

def test_get_move_range(self, game_pgn):
assert game_pgn.get_move_range(1, 28) == game_pgn.get_moves()
assert game_pgn.move_range(1, 28) == game_pgn.moves

def test_init_from_lichess_id(self):
game_lichess = Game('dGm3ND39')
time.sleep(1)
assert game_lichess.get_move_count() == 18
assert game_lichess.move_count() == 18

def test_init_from_lichess_url(self):
game_lichess = Game('https://lichess.org/dGm3ND39')
time.sleep(1)
assert game_lichess.get_move_count() == 18
assert game_lichess.move_count() == 18

0 comments on commit 161d8be

Please sign in to comment.