From 535764e505c49c696fc591bb6a09e9ac99996440 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Mon, 3 Feb 2020 17:03:30 -0700 Subject: [PATCH 1/5] the worst --- pvlib/forecast.py | 51 ++++++++++++++++++++++++------------ pvlib/tests/test_forecast.py | 15 ++++++----- pvlib/tests/test_location.py | 1 + 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/pvlib/forecast.py b/pvlib/forecast.py index cbea9bb8c8..9533b9535b 100644 --- a/pvlib/forecast.py +++ b/pvlib/forecast.py @@ -165,6 +165,25 @@ def set_dataset(self): self.ncss = NCSS(self.access_url) self.query = self.ncss.query() + def set_query_time_range(self, start, end): + """ + Parameters + ---------- + start : datetime.datetime, pandas.Timestamp + Must be tz-localized. + end : datetime.datetime, pandas.Timestamp + Must be tz-localized. + + Notes + ----- + Assigns ``self.start``, ``self.end``. Modifies ``self.query`` + """ + self.start = pd.Timestamp(start) + self.end = pd.Timestamp(end) + if self.start.tz is None or self.end.tz is None: + raise TypeError('start and end must be tz-localized') + self.query.time_range(self.start, self.end) + def set_query_latlon(self): ''' Sets the NCSS query location latitude and longitude. @@ -180,24 +199,24 @@ def set_query_latlon(self): self.lbox = False self.query.lonlat_point(self.longitude, self.latitude) - def set_location(self, time, latitude, longitude): + def set_location(self, tz, latitude, longitude): ''' Sets the location for the query. Parameters ---------- - time: datetime or DatetimeIndex - Time range of the query. - ''' - if isinstance(time, datetime.datetime): - tzinfo = time.tzinfo - else: - tzinfo = time.tz + tz: tzinfo + Timezone of the query + latitude: float + Latitude of the query + longitude: float + Longitude of the query - if tzinfo is None: - self.location = Location(latitude, longitude) - else: - self.location = Location(latitude, longitude, tz=tzinfo) + Notes + ----- + Assigns ``self.location``. + ''' + self.location = Location(latitude, longitude, tz=tz) def get_data(self, latitude, longitude, start, end, vert_level=None, query_variables=None, @@ -243,14 +262,12 @@ def get_data(self, latitude, longitude, start, end, else: self.query_variables = query_variables + self.set_query_time_range(start, end) + self.latitude = latitude self.longitude = longitude self.set_query_latlon() # modifies self.query - self.set_location(start, latitude, longitude) - - self.start = start - self.end = end - self.query.time_range(self.start, self.end) + self.set_location(self.start.tz, latitude, longitude) if self.vert_level is not None: self.query.vertical_level(self.vert_level) diff --git a/pvlib/tests/test_forecast.py b/pvlib/tests/test_forecast.py index d98deb357c..43b8bd6308 100644 --- a/pvlib/tests/test_forecast.py +++ b/pvlib/tests/test_forecast.py @@ -1,5 +1,4 @@ -from datetime import datetime, timedelta -from pytz import timezone +from datetime import datetime, timedelta, timezone import warnings import pandas as pd @@ -114,7 +113,7 @@ def test_vert_level(): @requires_siphon def test_datetime(): amodel = NAM() - start = datetime.now() + start = datetime.now(tz=timezone.utc) end = start + timedelta(days=1) amodel.get_processed_data(_latitude, _longitude, start, end) @@ -138,7 +137,6 @@ def test_full(): GFS(set_type='full') -@requires_siphon def test_temp_convert(): amodel = GFS() data = pd.DataFrame({'temp_air': [273.15]}) @@ -157,14 +155,19 @@ def test_temp_convert(): # variables=new_variables) -@requires_siphon def test_set_location(): amodel = GFS() latitude, longitude = 32.2, -110.9 - time = datetime.now(timezone('UTC')) + time = 'UTC' amodel.set_location(time, latitude, longitude) +def test_set_query_time_range_tzfail(): + amodel = GFS() + with pytest.raises(TypeError): + amodel.set_query_time_range(datetime.now(), datetime.now()) + + def test_cloud_cover_to_transmittance_linear(): amodel = GFS() assert_allclose(amodel.cloud_cover_to_transmittance_linear(0), 0.75) diff --git a/pvlib/tests/test_location.py b/pvlib/tests/test_location.py index 2deec4c8da..c3c3959985 100644 --- a/pvlib/tests/test_location.py +++ b/pvlib/tests/test_location.py @@ -29,6 +29,7 @@ def test_location_all(): @pytest.mark.parametrize('tz', [ pytz.timezone('US/Arizona'), 'America/Phoenix', -7, -7.0, + datetime.timezone.utc ]) def test_location_tz(tz): Location(32.2, -111, tz) From 20ed85d135770bb515d32e8a072ed3cca879b4eb Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Mon, 10 Feb 2020 20:08:42 -0700 Subject: [PATCH 2/5] fix location tz bug with datetime.timezone.utc --- pvlib/location.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pvlib/location.py b/pvlib/location.py index cb865bd046..afca46ece0 100644 --- a/pvlib/location.py +++ b/pvlib/location.py @@ -66,6 +66,9 @@ def __init__(self, latitude, longitude, tz='UTC', altitude=0, if isinstance(tz, str): self.tz = tz self.pytz = pytz.timezone(tz) + elif isinstance(tz, datetime.timezone): + self.tz = 'UTC' + self.pytz = pytz.UTC elif isinstance(tz, datetime.tzinfo): self.tz = tz.zone self.pytz = tz From d8a06e1b5ecbd20daccb580d51f605bf6842d5d3 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Mon, 10 Feb 2020 20:21:29 -0700 Subject: [PATCH 3/5] update whatsnew --- docs/sphinx/source/whatsnew/v0.7.2.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/sphinx/source/whatsnew/v0.7.2.rst b/docs/sphinx/source/whatsnew/v0.7.2.rst index 35511e6202..87d269f915 100644 --- a/docs/sphinx/source/whatsnew/v0.7.2.rst +++ b/docs/sphinx/source/whatsnew/v0.7.2.rst @@ -3,6 +3,11 @@ v0.7.2 (Month day, year) ------------------------- +API Changes +~~~~~~~~~~~ +* :py:class:`pvlib.forecast.Forecast` now requires ``start`` and ``end`` + arguments to be tz-localized. (:pull:`879`) + Enhancements ~~~~~~~~~~~~ * TMY3 dataframe returned by :py:func:`~pvlib.iotools.read_tmy3` now contains @@ -15,6 +20,8 @@ Bug fixes a leap year (:pull:`866`) * Implement NREL Developer Network API key for consistent success with API calls in :py:mod:`pvlib.tests.iotools.test_psm3` (:pull:`873`) +* Fix issue with :py:class:`pvlib.location.Location` creation when + passing ``tz=datetime.timezone.utc`` (:pull:`879`) Documentation ~~~~~~~~~~~~~ @@ -29,3 +36,6 @@ Contributors * Mark Mikofski (:ghuser:`mikofski`) * Cliff Hansen (:ghuser:`cwhanse`) * Cameron T. Stark (:ghuser:`camerontstark`) +* Will Holmgren (:ghuser:`wholmgren`) +* Kevin Anderson (:ghuser:`kanderso-nrel`) +* Karthikeyan Singaravelan (:ghuser:`tirkarthi`) From fec21b526d1e2813160e225e7bcb71b817379e8c Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Mon, 10 Feb 2020 20:21:58 -0700 Subject: [PATCH 4/5] issue in whatsnew --- docs/sphinx/source/whatsnew/v0.7.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.7.2.rst b/docs/sphinx/source/whatsnew/v0.7.2.rst index 87d269f915..e74fff7e3c 100644 --- a/docs/sphinx/source/whatsnew/v0.7.2.rst +++ b/docs/sphinx/source/whatsnew/v0.7.2.rst @@ -6,7 +6,7 @@ v0.7.2 (Month day, year) API Changes ~~~~~~~~~~~ * :py:class:`pvlib.forecast.Forecast` now requires ``start`` and ``end`` - arguments to be tz-localized. (:pull:`879`) + arguments to be tz-localized. (:issue:`877`, :pull:`879`) Enhancements ~~~~~~~~~~~~ From 1579fbd04635adea4218bc7c7af55d532fc8f34d Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Mon, 10 Feb 2020 20:40:32 -0700 Subject: [PATCH 5/5] fix whatsnew class typo --- docs/sphinx/source/whatsnew/v0.7.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.7.2.rst b/docs/sphinx/source/whatsnew/v0.7.2.rst index e74fff7e3c..367a8ab1c6 100644 --- a/docs/sphinx/source/whatsnew/v0.7.2.rst +++ b/docs/sphinx/source/whatsnew/v0.7.2.rst @@ -5,7 +5,7 @@ v0.7.2 (Month day, year) API Changes ~~~~~~~~~~~ -* :py:class:`pvlib.forecast.Forecast` now requires ``start`` and ``end`` +* :py:class:`pvlib.forecast.ForecastModel` now requires ``start`` and ``end`` arguments to be tz-localized. (:issue:`877`, :pull:`879`) Enhancements