From 94834a0e6359fca992afcb345acabc1cdc49aac2 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Tue, 3 Jun 2025 12:03:59 -0400 Subject: [PATCH 1/5] deprecate parse_bsrn --- pvlib/iotools/bsrn.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/pvlib/iotools/bsrn.py b/pvlib/iotools/bsrn.py index 777eab9614..f934cabd08 100644 --- a/pvlib/iotools/bsrn.py +++ b/pvlib/iotools/bsrn.py @@ -8,6 +8,10 @@ import warnings import io import os +from functools import partial + +from pvlib.tools import _file_context_manager +from pvlib._deprecation import deprecated BSRN_FTP_URL = "ftp.bsrn.awi.de" @@ -136,7 +140,7 @@ def get_bsrn(station, start, end, username, password, See Also -------- - pvlib.iotools.read_bsrn, pvlib.iotools.parse_bsrn + pvlib.iotools.read_bsrn References ---------- @@ -191,7 +195,7 @@ def get_bsrn(station, start, end, username, password, bio.seek(0) # reset buffer to start of file gzip_file = io.TextIOWrapper(gzip.GzipFile(fileobj=bio), encoding='latin1') - dfi, metadata = parse_bsrn(gzip_file, logical_records) + dfi, metadata = _parse_bsrn(gzip_file, logical_records) dfs.append(dfi) # FTP client raises an error if the file does not exist on server except ftplib.error_perm as e: @@ -217,7 +221,7 @@ def get_bsrn(station, start, end, username, password, return data, metadata -def parse_bsrn(fbuf, logical_records=('0100',)): +def _parse_bsrn(fbuf, logical_records=('0100',)): """ Parse a file-like buffer of a BSRN station-to-archive file. @@ -382,7 +386,7 @@ def read_bsrn(filename, logical_records=('0100',)): Parameters ---------- filename: str or path-like - Name or path of a BSRN station-to-archive data file + Name, path, or in-memory buffer of a BSRN station-to-archive data file logical_records: list or tuple, default: ('0100',) List of the logical records (LR) to parse. Options include: '0100', '0300', and '0500'. @@ -439,7 +443,7 @@ def read_bsrn(filename, logical_records=('0100',)): See Also -------- - pvlib.iotools.parse_bsrn, pvlib.iotools.get_bsrn + pvlib.iotools.get_bsrn References ---------- @@ -455,9 +459,13 @@ def read_bsrn(filename, logical_records=('0100',)): `_ """ # noqa: E501 if str(filename).endswith('.gz'): # check if file is a gzipped (.gz) file - open_func, mode = gzip.open, 'rt' + open_func = partial(gzip.open, mode='rt') else: - open_func, mode = open, 'r' - with open_func(filename, mode) as f: - content = parse_bsrn(f, logical_records) + open_func = _file_context_manager(filename, mode='r') + with open_func(filename) as f: + content = _parse_bsrn(f, logical_records) return content + + +parse_bsrn = deprecated(since="0.13.0", name="parse_bsrn", + alternative="read_bsrn")(read_bsrn) From dc478ce5a9942e6c73d8e2636c3e155887d40b5c Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Tue, 3 Jun 2025 12:05:33 -0400 Subject: [PATCH 2/5] tests --- tests/iotools/test_bsrn.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/iotools/test_bsrn.py b/tests/iotools/test_bsrn.py index 6a01511e93..61ba6af580 100644 --- a/tests/iotools/test_bsrn.py +++ b/tests/iotools/test_bsrn.py @@ -6,7 +6,7 @@ import pytest import os import tempfile -from pvlib.iotools import read_bsrn, get_bsrn +from pvlib.iotools import read_bsrn, get_bsrn, parse_bsrn from tests.conftest import ( TESTS_DATA_DIR, RERUNS, @@ -15,6 +15,7 @@ requires_bsrn_credentials, ) +from pvlib._deprecation import pvlibDeprecationWarning @pytest.fixture(scope="module") def bsrn_credentials(): @@ -33,6 +34,12 @@ def expected_index(): tz='UTC') +def test_parse_bsrn_deprecated(): + with pytest.warns(pvlibDeprecationWarning, match='Use read_bsrn instead'): + with open(TESTS_DATA_DIR / 'bsrn-lr0100-pay0616.dat') as fbuf: + data, metadata = parse_bsrn(fbuf) + + @pytest.mark.parametrize('testfile', [ ('bsrn-pay0616.dat.gz'), ('bsrn-lr0100-pay0616.dat'), @@ -47,6 +54,17 @@ def test_read_bsrn(testfile, expected_index): assert 'relative_humidity' in data.columns +def test_read_bsrn_buffer(expected_index): + with open(TESTS_DATA_DIR / 'bsrn-lr0100-pay0616.dat') as fbuf: + data, metadata = read_bsrn(fbuf) + assert_index_equal(expected_index, data.index) + assert 'ghi' in data.columns + assert 'dni_std' in data.columns + assert 'dhi_min' in data.columns + assert 'lwd_max' in data.columns + assert 'relative_humidity' in data.columns + + def test_read_bsrn_logical_records(expected_index): # Test if logical records 0300 and 0500 are correct parsed # and that 0100 is not passed when not specified From 22d2f405ab7bebf8360d3c57bfd4e15a49fde421 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Tue, 3 Jun 2025 12:05:41 -0400 Subject: [PATCH 3/5] whatsnew --- docs/sphinx/source/whatsnew/v0.12.1.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.12.1.rst b/docs/sphinx/source/whatsnew/v0.12.1.rst index 06907e76fc..883aa1bdb3 100644 --- a/docs/sphinx/source/whatsnew/v0.12.1.rst +++ b/docs/sphinx/source/whatsnew/v0.12.1.rst @@ -17,10 +17,11 @@ Breaking Changes Deprecations ~~~~~~~~~~~~ * The following ``parse_`` functions in :py:mod:`pvlib.iotools` are deprecated, - with the corresponding ``read_`` functions taking their place: (:issue:`2444`, :pull:`2458`) + with the corresponding ``read_`` functions taking their place: (:issue:`2444`, :pull:`2458`, :pull:`2466`) - :py:func:`~pvlib.iotools.parse_psm3` - :py:func:`~pvlib.iotools.parse_cams` + - :py:func:`~pvlib.iotools.parse_bsrn` * The ``server`` parameter in :py:func:`~pvlib.iotools.get_cams` has been renamed to ``url`` to be consistent with the other iotools. From 7b50c107d4d0e935df44bf60fa1230958722bc4c Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Tue, 3 Jun 2025 12:14:56 -0400 Subject: [PATCH 4/5] fixes --- pvlib/iotools/bsrn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pvlib/iotools/bsrn.py b/pvlib/iotools/bsrn.py index f934cabd08..f236df0a51 100644 --- a/pvlib/iotools/bsrn.py +++ b/pvlib/iotools/bsrn.py @@ -459,10 +459,10 @@ def read_bsrn(filename, logical_records=('0100',)): `_ """ # noqa: E501 if str(filename).endswith('.gz'): # check if file is a gzipped (.gz) file - open_func = partial(gzip.open, mode='rt') + open_func, mode = gzip.open, 'rt' else: - open_func = _file_context_manager(filename, mode='r') - with open_func(filename) as f: + open_func, mode = _file_context_manager, 'r' + with open_func(filename, mode) as f: content = _parse_bsrn(f, logical_records) return content From 52599412a4d6b45404f26e5aa3446424a65a9348 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Tue, 3 Jun 2025 12:23:58 -0400 Subject: [PATCH 5/5] lint --- pvlib/iotools/bsrn.py | 1 - tests/iotools/test_bsrn.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/iotools/bsrn.py b/pvlib/iotools/bsrn.py index f236df0a51..3cca48c959 100644 --- a/pvlib/iotools/bsrn.py +++ b/pvlib/iotools/bsrn.py @@ -8,7 +8,6 @@ import warnings import io import os -from functools import partial from pvlib.tools import _file_context_manager from pvlib._deprecation import deprecated diff --git a/tests/iotools/test_bsrn.py b/tests/iotools/test_bsrn.py index 61ba6af580..8d8f905635 100644 --- a/tests/iotools/test_bsrn.py +++ b/tests/iotools/test_bsrn.py @@ -17,6 +17,7 @@ from pvlib._deprecation import pvlibDeprecationWarning + @pytest.fixture(scope="module") def bsrn_credentials(): """Supplies the BSRN FTP credentials for testing purposes.