Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/sphinx/source/whatsnew/v0.13.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Enhancements
(:pull:`2500`)
* :py:func:`pvlib.spectrum.spectral_factor_firstsolar` no longer emits warnings
when airmass and precipitable water values fall out of range. (:pull:`2512`)
* Allows reading TMY data from a Path or file-like object in :py:func:`~pvlib.iotools.read_tmy3`.
(:pull:`2544`, :ghuser:`jerluc`)

Documentation
~~~~~~~~~~~~~
Expand Down
6 changes: 4 additions & 2 deletions pvlib/iotools/tmy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import re
import pandas as pd

from pvlib.tools import _file_context_manager

# Dictionary mapping TMY3 names to pvlib names
VARIABLE_MAP = {
'GHI (W/m^2)': 'ghi',
Expand Down Expand Up @@ -35,7 +37,7 @@ def read_tmy3(filename, coerce_year=None, map_variables=True, encoding=None):

Parameters
----------
filename : str
filename : str, Path, or file-like object
A relative file path or absolute file path.
coerce_year : int, optional
If supplied, the year of the index will be set to ``coerce_year``, except
Expand Down Expand Up @@ -186,7 +188,7 @@ def read_tmy3(filename, coerce_year=None, map_variables=True, encoding=None):
""" # noqa: E501
head = ['USAF', 'Name', 'State', 'TZ', 'latitude', 'longitude', 'altitude']

with open(str(filename), 'r', encoding=encoding) as fbuf:
with _file_context_manager(filename, mode="r", encoding=encoding) as fbuf:
# header information on the 1st line (0 indexing)
firstline = fbuf.readline()
# use pandas to read the csv file buffer
Expand Down
4 changes: 2 additions & 2 deletions pvlib/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ def normalize_max2one(a):
return res


def _file_context_manager(filename_or_object, mode='r'):
def _file_context_manager(filename_or_object, mode='r', encoding=None):
"""
Open a filename/path for reading, or pass a file-like object
through unchanged.
Expand All @@ -584,5 +584,5 @@ def _file_context_manager(filename_or_object, mode='r'):
context = contextlib.nullcontext(filename_or_object)
else:
# otherwise, assume a filename or path
context = open(str(filename_or_object), mode=mode)
context = open(str(filename_or_object), mode=mode, encoding=encoding)
return context
7 changes: 7 additions & 0 deletions tests/iotools/test_tmy.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def test_read_tmy3():
tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)


def test_read_tmy3_buffer():
with open(TMY3_TESTFILE) as f:
data, _ = tmy.read_tmy3(f, map_variables=False)
assert 'GHI source' in data.columns
assert len(data) == 8760


def test_read_tmy3_norecolumn():
data, _ = tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)
assert 'GHI source' in data.columns
Expand Down