diff --git a/.github/workflows/pushtests.yml b/.github/workflows/pushtests.yml index ef462825..a347d0ff 100644 --- a/.github/workflows/pushtests.yml +++ b/.github/workflows/pushtests.yml @@ -29,9 +29,7 @@ jobs: pycodestyle sportsreference/ tests/integration/ tests/unit/ - name: Upload coverage to Codecov if: matrix.operating-system == 'ubuntu-latest' && matrix.python-version == '3.7' - uses: codecov/codecov-action@v1.0.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} + uses: codecov/codecov-action@v1.0.6 publish: name: Publish package to PyPI diff --git a/sportsreference/mlb/roster.py b/sportsreference/mlb/roster.py index a130fad4..6421f422 100644 --- a/sportsreference/mlb/roster.py +++ b/sportsreference/mlb/roster.py @@ -746,6 +746,8 @@ def weight(self): """ Returns an ``int`` of the player's weight in pounds. """ + if not self._weight: + return None return int(self._weight.replace('lb', '')) @property diff --git a/sportsreference/nba/roster.py b/sportsreference/nba/roster.py index c983a69b..5ebdcba0 100644 --- a/sportsreference/nba/roster.py +++ b/sportsreference/nba/roster.py @@ -104,6 +104,7 @@ class Player(AbstractPlayer): 'NN' is a number starting at '01' for the first time that player ID has been used and increments by 1 for every successive player. """ + def __init__(self, player_id): self._most_recent_season = '' self._index = None @@ -1196,6 +1197,7 @@ class Roster: respective stats which greatly reduces the time to return a response if just the names and IDs are desired. Defaults to False. """ + def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim diff --git a/sportsreference/ncaaf/player.py b/sportsreference/ncaaf/player.py index 21d5c6d0..a3f356e2 100644 --- a/sportsreference/ncaaf/player.py +++ b/sportsreference/ncaaf/player.py @@ -1,6 +1,5 @@ import pandas as pd import re -import warnings from functools import wraps from lxml.etree import ParserError, XMLSyntaxError from pyquery import PyQuery as pq @@ -212,17 +211,6 @@ def completed_passes(self): """ return self._completed_passes - @_int_property_decorator - def attempted_passes(self): - """ - Returns an ``int`` of the number of passes the player attempted. - """ - warnings.warn('Warning: "attempted_passes" is deprecated and will ' - 'be removed in a future release. Please use ' - '"pass_attempts" instead for identical functionality.', - DeprecationWarning) - return self._pass_attempts - @_int_property_decorator def pass_attempts(self): """ diff --git a/sportsreference/ncaaf/roster.py b/sportsreference/ncaaf/roster.py index dee1d9d4..546339c7 100644 --- a/sportsreference/ncaaf/roster.py +++ b/sportsreference/ncaaf/roster.py @@ -1,6 +1,5 @@ import pandas as pd import re -import warnings from functools import wraps from lxml.etree import ParserError, XMLSyntaxError from pyquery import PyQuery as pq @@ -524,17 +523,6 @@ def completed_passes(self): """ return self._completed_passes - @_int_property_decorator - def attempted_passes(self): - """ - Returns an ``int`` of the number of passes the player attempted. - """ - warnings.warn('Warning: "attempted_passes" is deprecated and will ' - 'be removed in a future release. Please use ' - '"pass_attempts" instead for identical functionality.', - DeprecationWarning) - return self._pass_attempts - @_int_property_decorator def pass_attempts(self): """ diff --git a/sportsreference/nfl/boxscore.py b/sportsreference/nfl/boxscore.py index 2650e853..81e8ea24 100644 --- a/sportsreference/nfl/boxscore.py +++ b/sportsreference/nfl/boxscore.py @@ -1,6 +1,6 @@ import pandas as pd import re -from datetime import timedelta +from datetime import datetime from pyquery import PyQuery as pq from urllib.error import HTTPError from .. import utils @@ -732,6 +732,7 @@ def dataframe(self): 'away_yards_from_penalties': self.away_yards_from_penalties, 'away_yards_lost_from_sacks': self.away_yards_lost_from_sacks, 'date': self.date, + 'datetime': self.datetime, 'duration': self.duration, 'home_first_downs': self.home_first_downs, 'home_fourth_down_attempts': self.home_fourth_down_attempts, @@ -815,6 +816,19 @@ def time(self): """ return self._time + @property + def datetime(self): + """ + Returns a ``datetime`` object of the date and time the game took place. + """ + dt = None + if self._date and self._time: + date = '%s %s' % (self._date, self._time) + dt = datetime.strptime(date, '%A %b %d, %Y %I:%M%p') + elif self._date: + dt = datetime.strptime(self._date, '%A %b %d, %Y') + return dt + @property def stadium(self): """ diff --git a/sportsreference/nfl/roster.py b/sportsreference/nfl/roster.py index d29f5eea..90e3b0cf 100644 --- a/sportsreference/nfl/roster.py +++ b/sportsreference/nfl/roster.py @@ -663,6 +663,8 @@ def weight(self): """ Returns an ``int`` of the player's weight in pounds. """ + if not self._weight: + return None return int(self._weight.replace('lb', '')) @property diff --git a/sportsreference/nhl/roster.py b/sportsreference/nhl/roster.py index ce23d9ca..9c7a4986 100644 --- a/sportsreference/nhl/roster.py +++ b/sportsreference/nhl/roster.py @@ -568,6 +568,8 @@ def weight(self): """ Returns an ``int`` of the player's weight in pounds. """ + if not self._weight: + return None return int(self._weight.replace('lb', '')) @_int_property_decorator diff --git a/tests/integration/boxscore/test_nfl_boxscore.py b/tests/integration/boxscore/test_nfl_boxscore.py index 8c753ff3..d804d018 100644 --- a/tests/integration/boxscore/test_nfl_boxscore.py +++ b/tests/integration/boxscore/test_nfl_boxscore.py @@ -47,6 +47,7 @@ def setup_method(self, *args, **kwargs): self.results = { 'date': 'Sunday Feb 4, 2018', 'time': '6:30pm', + 'datetime': datetime(2018, 2, 4, 18, 30), 'stadium': 'U.S. Bank Stadium', 'attendance': 67612, 'duration': '3:46', diff --git a/tests/unit/test_mlb_roster.py b/tests/unit/test_mlb_roster.py index 0138220d..e2ed5dee 100644 --- a/tests/unit/test_mlb_roster.py +++ b/tests/unit/test_mlb_roster.py @@ -84,3 +84,11 @@ def test_cleanup_of_none_returns_default_for_player(self): result = _cleanup_player(None) assert result == '' + + @patch('requests.get', side_effect=mock_pyquery) + def test_missing_weight_returns_none(self, *args, **kwargs): + mock_weight = PropertyMock(return_value=None) + player = Player(None) + type(player)._weight = mock_weight + + assert not player.weight diff --git a/tests/unit/test_nba_roster.py b/tests/unit/test_nba_roster.py index 97326c04..40dd763e 100644 --- a/tests/unit/test_nba_roster.py +++ b/tests/unit/test_nba_roster.py @@ -103,6 +103,14 @@ def test_empty_contract_is_none(self): assert player._contract is None + @patch('requests.get', side_effect=mock_pyquery) + def test_missing_weight_returns_none(self, *args, **kwargs): + mock_weight = PropertyMock(return_value=None) + player = Player(None) + type(player)._weight = mock_weight + + assert not player.weight + class TestInvalidNBAPlayer: def test_no_player_data_returns_no_stats(self): diff --git a/tests/unit/test_ncaaf_boxscore.py b/tests/unit/test_ncaaf_boxscore.py index d8f73c7e..442fb114 100644 --- a/tests/unit/test_ncaaf_boxscore.py +++ b/tests/unit/test_ncaaf_boxscore.py @@ -435,22 +435,6 @@ def test_non_int_value_returns_none(self): assert self.boxscore.away_rush_attempts is None - @patch('requests.get', side_effect=mock_pyquery) - def test_attempted_passes_has_deprecation_warning(self, *args, **kwargs): - flexmock(AbstractPlayer) \ - .should_receive('__init__') \ - .and_return(None) - mock_passes = PropertyMock(return_value=[32]) - mock_index = PropertyMock(return_value=0) - player = AbstractPlayer(None, None, None) - type(player)._pass_attempts = mock_passes - type(player)._index = mock_index - - with pytest.deprecated_call(): - result = player.attempted_passes - - assert result == 32 - class TestNCAABBoxscores: @patch('requests.get', side_effect=mock_pyquery) diff --git a/tests/unit/test_ncaaf_roster.py b/tests/unit/test_ncaaf_roster.py index ffc1d518..6f4a62bf 100644 --- a/tests/unit/test_ncaaf_roster.py +++ b/tests/unit/test_ncaaf_roster.py @@ -49,16 +49,3 @@ def test_missing_weight_returns_none(self, *args, **kwargs): result = player.weight assert result is None - - @patch('requests.get', side_effect=mock_pyquery) - def test_attempted_passes_has_deprecation_warning(self, *args, **kwargs): - mock_passes = PropertyMock(return_value=[32]) - mock_index = PropertyMock(return_value=0) - player = Player(None) - type(player)._pass_attempts = mock_passes - type(player)._index = mock_index - - with pytest.deprecated_call(): - result = player.attempted_passes - - assert result == 32 diff --git a/tests/unit/test_nfl_boxscore.py b/tests/unit/test_nfl_boxscore.py index 70281879..00b40448 100644 --- a/tests/unit/test_nfl_boxscore.py +++ b/tests/unit/test_nfl_boxscore.py @@ -1,3 +1,4 @@ +from datetime import datetime from flexmock import flexmock from mock import patch, PropertyMock from pyquery import PyQuery as pq @@ -285,6 +286,14 @@ def test_nfl_home_abbreviation(self): assert self.boxscore.home_abbreviation == 'nwe' + def test_nfl_datetime_missing_time(self): + date = PropertyMock(return_value='Sunday Oct 7, 2018') + time = PropertyMock(return_value=None) + type(self.boxscore)._date = date + type(self.boxscore)._time = time + + assert self.boxscore.datetime == datetime(2018, 10, 7) + class TestNFLBoxscores: @patch('requests.get', side_effect=mock_pyquery) diff --git a/tests/unit/test_nfl_roster.py b/tests/unit/test_nfl_roster.py index 36dff3b3..89ce2dd7 100644 --- a/tests/unit/test_nfl_roster.py +++ b/tests/unit/test_nfl_roster.py @@ -38,3 +38,11 @@ def test_invalid_url_returns_none(self, *args, **kwargs): result = player._retrieve_html_page() assert result is None + + @patch('requests.get', side_effect=mock_pyquery) + def test_missing_weight_returns_none(self, *args, **kwargs): + mock_weight = PropertyMock(return_value=None) + player = Player(None) + type(player)._weight = mock_weight + + assert not player.weight diff --git a/tests/unit/test_nhl_roster.py b/tests/unit/test_nhl_roster.py index d1e5602b..8969e8f7 100644 --- a/tests/unit/test_nhl_roster.py +++ b/tests/unit/test_nhl_roster.py @@ -38,3 +38,11 @@ def test_invalid_url_returns_none(self, *args, **kwargs): result = player._retrieve_html_page() assert result is None + + @patch('requests.get', side_effect=mock_pyquery) + def test_missing_weight_returns_none(self, *args, **kwargs): + mock_weight = PropertyMock(return_value=None) + player = Player(None) + type(player)._weight = mock_weight + + assert not player.weight