diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 955f328cd..18fdcbc20 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.5.2dev2 +current_version = 0.5.2.dev2 commit = True tag = True diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6f68dba4a..8a4a7fff9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: 3.9 diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index b3601dfb9..874a5bfb7 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/tox_checks.yml b/.github/workflows/tox_checks.yml index 8686b132f..f575ed022 100644 --- a/.github/workflows/tox_checks.yml +++ b/.github/workflows/tox_checks.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Python ${{ env.default_python || '3.9' }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: "${{ env.default_python || '3.9' }}" diff --git a/.github/workflows/tox_pytests.yml b/.github/workflows/tox_pytests.yml index dc777a7f9..7b7570226 100644 --- a/.github/workflows/tox_pytests.yml +++ b/.github/workflows/tox_pytests.yml @@ -23,7 +23,7 @@ jobs: - name: Install cbc run: sudo apt install coinor-cbc - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/MANIFEST.in b/MANIFEST.in index c80f59439..69992fa42 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,7 +5,6 @@ graft tests include .bumpversion.cfg include .coveragerc -include .cookiecutterrc include .editorconfig include AUTHORS.rst diff --git a/VERSION b/VERSION index ae000fe0a..28bcfa005 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -__version__ = "0.5.2dev2" +__version__ = "0.5.2.dev2" diff --git a/docs/conf.py b/docs/conf.py index 6a7d75dea..d1adcfd5f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,7 +36,7 @@ def setup(app): year = "2014-2023" author = "oemof-developer-group" copyright = "{0}, {1}".format(year, author) -version = release = "0.5.2dev2" +version = release = "0.5.2.dev2" pygments_style = "trac" templates_path = ["."] diff --git a/pyproject.toml b/pyproject.toml index bbde2c90f..8d7102f4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,5 +19,5 @@ exclude = ''' ''' [build-system] -requires = ["setuptools<60.0", "wheel"] +requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg index 889fafe6e..8354fec39 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,7 +33,7 @@ python_files = tests.py addopts = -ra - --strict + --strict-markers --ignore=docs/conf.py --ignore=setup.py --ignore=ci diff --git a/setup.py b/setup.py index 818f2ea0c..ac89066f9 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ def read(*names, **kwargs): setup( name="oemof.solph", - version="0.5.2dev2", + version="0.5.2.dev2", license="MIT", description=( "A model generator for energy system modelling and optimisation." diff --git a/src/oemof/solph/__init__.py b/src/oemof/solph/__init__.py index d8632f71c..c002c1b8e 100644 --- a/src/oemof/solph/__init__.py +++ b/src/oemof/solph/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.5.2dev2" +__version__ = "0.5.2.dev2" from . import buses from . import components diff --git a/src/oemof/solph/constraints/equate_variables.py b/src/oemof/solph/constraints/equate_variables.py index 5ce350da4..53d5f3e7e 100644 --- a/src/oemof/solph/constraints/equate_variables.py +++ b/src/oemof/solph/constraints/equate_variables.py @@ -62,8 +62,11 @@ def equate_variables(model, var1, var2, factor1=1, name=None): >>> import pandas as pd >>> from oemof import solph - >>> date_time_index = pd.date_range('1/1/2012', periods=5, freq='H') - >>> energysystem = solph.EnergySystem(timeindex=date_time_index) + >>> date_time_index = pd.date_range('1/1/2012', periods=6, freq='H') + >>> energysystem = solph.EnergySystem( + ... timeindex=date_time_index, + ... infer_last_interval=False, + ... ) >>> bel1 = solph.buses.Bus(label='electricity1') >>> bel2 = solph.buses.Bus(label='electricity2') >>> energysystem.add(bel1, bel2) diff --git a/src/oemof/solph/constraints/integral_limit.py b/src/oemof/solph/constraints/integral_limit.py index 28fe427b6..e5157e5b7 100644 --- a/src/oemof/solph/constraints/integral_limit.py +++ b/src/oemof/solph/constraints/integral_limit.py @@ -102,8 +102,11 @@ def generic_integral_limit(om, keyword, flows=None, limit=None): -------- >>> import pandas as pd >>> from oemof import solph - >>> date_time_index = pd.date_range('1/1/2012', periods=5, freq='H') - >>> energysystem = solph.EnergySystem(timeindex=date_time_index) + >>> date_time_index = pd.date_range('1/1/2012', periods=6, freq='H') + >>> energysystem = solph.EnergySystem( + ... timeindex=date_time_index, + ... infer_last_interval=False, + ... ) >>> bel = solph.buses.Bus(label='electricityBus') >>> flow1 = solph.flows.Flow( ... nominal_value=100, diff --git a/src/oemof/solph/constraints/investment_limit.py b/src/oemof/solph/constraints/investment_limit.py index 078b553b1..f2a44a955 100644 --- a/src/oemof/solph/constraints/investment_limit.py +++ b/src/oemof/solph/constraints/investment_limit.py @@ -171,8 +171,11 @@ def additional_investment_flow_limit(model, keyword, limit=None): -------- >>> import pandas as pd >>> from oemof import solph - >>> date_time_index = pd.date_range('1/1/2020', periods=5, freq='H') - >>> es = solph.EnergySystem(timeindex=date_time_index) + >>> date_time_index = pd.date_range('1/1/2020', periods=6, freq='H') + >>> es = solph.EnergySystem( + ... timeindex=date_time_index, + ... infer_last_interval=False, + ... ) >>> bus = solph.buses.Bus(label='bus_1') >>> sink = solph.components.Sink(label="sink", inputs={bus: ... solph.flows.Flow(nominal_value=10, fix=[10, 20, 30, 40, 50])}) diff --git a/src/oemof/solph/constraints/shared_limit.py b/src/oemof/solph/constraints/shared_limit.py index 4cf055b8b..e85a3abab 100644 --- a/src/oemof/solph/constraints/shared_limit.py +++ b/src/oemof/solph/constraints/shared_limit.py @@ -60,8 +60,11 @@ def shared_limit( >>> import pandas as pd >>> from oemof import solph - >>> date_time_index = pd.date_range('1/1/2012', periods=5, freq='H') - >>> energysystem = solph.EnergySystem(timeindex=date_time_index) + >>> date_time_index = pd.date_range('1/1/2012', periods=6, freq='H') + >>> energysystem = solph.EnergySystem( + ... timeindex=date_time_index, + ... infer_last_interval=False, + ... ) >>> b1 = solph.buses.Bus(label="Party1Bus") >>> b2 = solph.buses.Bus(label="Party2Bus") >>> storage1 = solph.components.GenericStorage( diff --git a/tests/constraint_tests.py b/tests/constraint_tests.py index 4738fe8d0..c5be91e1f 100644 --- a/tests/constraint_tests.py +++ b/tests/constraint_tests.py @@ -36,7 +36,9 @@ def setup_class(cls): def setup_method(self): self.energysystem = solph.EnergySystem( - groupings=solph.GROUPINGS, timeindex=self.date_time_index + groupings=solph.GROUPINGS, + timeindex=self.date_time_index, + infer_last_interval=True, ) def get_om(self): @@ -1862,8 +1864,8 @@ def test_integral_limit_error_no_multi_period(self): om, keyword="space" ) - def test_summed_min_max_source(self): - """Constraints test summed_min and summed_max attribute of flow""" + def test_full_load_time_min_max_source(self): + """Constraints test full_load_time_min and _max attribute of flow""" bel = solph.buses.Bus(label="electricityBus") diff --git a/tests/multi_period_constraint_tests.py b/tests/multi_period_constraint_tests.py index 6394e8a52..417fdf0dd 100644 --- a/tests/multi_period_constraint_tests.py +++ b/tests/multi_period_constraint_tests.py @@ -22,6 +22,22 @@ logging.disable(logging.INFO) +# Warnings about the fature being experimental: +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) +# Warnings about default parameters beaing used: +@pytest.mark.filterwarnings( + "ignore:You did not specify an interest rate.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:By default, a discount_rate of 0.02 is used for a multi-period" + " model.:UserWarning" +) class TestsMultiPeriodConstraint: @classmethod def setup_class(cls): @@ -160,7 +176,7 @@ def test_linear_converter_invest_remaining_value(self): outputs={ bel: solph.flows.Flow( variable_costs=50, - investment=solph.Investment( + nominal_value=solph.Investment( existing=50, maximum=1000, overall_maximum=10000, @@ -266,7 +282,8 @@ def test_nominal_value_to_zero(self): self.compare_lp_files("nominal_value_to_zero_multi_period.lp") def test_fixed_source_invest_sink(self): - """Constraints test for fixed source + invest sink w. `summed_max`""" + """Constraints test for fixed source + invest sink w. + `full_load_time_max`""" bel = solph.buses.Bus(label="electricityBus") source = solph.components.Source( @@ -282,7 +299,7 @@ def test_fixed_source_invest_sink(self): label="excess", inputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, nominal_value=solph.Investment( @@ -407,7 +424,6 @@ def test_storage_invest_1_remaining_value(self): label="storage1", inputs={bel: solph.flows.Flow(variable_costs=56)}, outputs={bel: solph.flows.Flow(variable_costs=24)}, - nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, min_storage_level=0.1, @@ -417,7 +433,7 @@ def test_storage_invest_1_remaining_value(self): lifetime_outflow=20, inflow_conversion_factor=0.97, outflow_conversion_factor=0.86, - investment=solph.Investment( + nominal_storage_capacity=solph.Investment( ep_costs=[145, 130, 115], maximum=234, lifetime=20, @@ -1930,7 +1946,6 @@ def test_nonconvex_investment_storage_without_offset_remaining_value(self): label="storage_non_convex", inputs={bel: solph.flows.Flow(variable_costs=56)}, outputs={bel: solph.flows.Flow(variable_costs=24)}, - nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, min_storage_level=0.1, @@ -1940,7 +1955,7 @@ def test_nonconvex_investment_storage_without_offset_remaining_value(self): outflow_conversion_factor=0.86, lifetime_inflow=20, lifetime_outflow=20, - investment=solph.Investment( + nominal_storage_capacity=solph.Investment( ep_costs=141, maximum=244, minimum=12, @@ -1996,7 +2011,6 @@ def test_nonconvex_investment_storage_with_offset_remaining_value(self): label="storage_non_convex", inputs={bel: solph.flows.Flow(variable_costs=56)}, outputs={bel: solph.flows.Flow(variable_costs=24)}, - nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, min_storage_level=0.1, @@ -2006,7 +2020,7 @@ def test_nonconvex_investment_storage_with_offset_remaining_value(self): outflow_conversion_factor=0.86, lifetime_inflow=20, lifetime_outflow=20, - investment=solph.Investment( + nominal_storage_capacity=solph.Investment( ep_costs=145, minimum=19, offset=5, @@ -2072,7 +2086,7 @@ def test_nonconvex_invest_sink_without_offset(self): label="sink_nonconvex_invest", inputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, nominal_value=solph.Investment( @@ -2096,10 +2110,10 @@ def test_nonconvex_invest_sink_without_offset_remaining_value(self): label="sink_nonconvex_invest", inputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, - investment=solph.Investment( + nominal_value=solph.Investment( ep_costs=500, minimum=15, nonconvex=True, @@ -2124,7 +2138,7 @@ def test_nonconvex_invest_source_with_offset(self): label="source_nonconvex_invest", outputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, nominal_value=solph.Investment( @@ -2149,10 +2163,10 @@ def test_nonconvex_invest_source_with_offset_remaining_value(self): label="source_nonconvex_invest", outputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, - investment=solph.Investment( + nominal_value=solph.Investment( ep_costs=500, minimum=15, maximum=20, @@ -2178,7 +2192,7 @@ def test_nonconvex_invest_source_with_offset_no_minimum(self): label="source_nonconvex_invest", outputs={ bel: solph.flows.Flow( - summed_max=2.3, + full_load_time_max=2.3, variable_costs=25, max=0.8, nominal_value=solph.Investment( @@ -2197,15 +2211,15 @@ def test_nonconvex_invest_source_with_offset_no_minimum(self): ) def test_summed_min_max_source(self): - """Test sink with summed_min and summed_max attribute""" + """Test sink with full_load_time_min and _max attribute""" bel = solph.buses.Bus(label="electricityBus") sink = solph.components.Sink( label="excess", inputs={ bel: solph.flows.Flow( - summed_min=3, - summed_max=100, + full_load_time_min=3, + full_load_time_max=100, variable_costs=25, max=0.8, nominal_value=10, @@ -2249,6 +2263,9 @@ def test_flow_reaching_lifetime_initial_age(self): self.energysystem.add(bel, sink) self.compare_lp_files("flow_reaching_lifetime_initial_age.lp") + @pytest.mark.filterwarnings( + "ignore:Be aware that the fixed costs attribute is only:UserWarning" + ) def test_fixed_costs(self): """Test fixed_cost attribute for different kinds of flows""" bel = solph.buses.Bus(label="electricityBus") diff --git a/tests/test_components.py b/tests/test_components.py index 9e71d4b13..f1db847b4 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -148,6 +148,17 @@ def test_generic_storage_with_convex_invest_offset(): ) +def test_generic_storage_invest_warning(): + with pytest.warns(FutureWarning): + bel = Bus() + components.GenericStorage( + label="storage7", + inputs={bel: Flow()}, + outputs={bel: Flow()}, + investment=Investment(), + ) + + def test_generic_storage_with_invest_and_fixed_losses_absolute(): """ Storage with fixed losses in the investment mode but no minimum or existing diff --git a/tests/test_energy_system.py b/tests/test_energy_system.py index 7828f31dd..d4a9b0cf4 100644 --- a/tests/test_energy_system.py +++ b/tests/test_energy_system.py @@ -8,10 +8,18 @@ """ import pandas as pd +import pytest from oemof.solph import EnergySystem +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) def test_add_periods(): """test method _add_periods of energy system""" timeindex = pd.date_range(start="2012-01-01", periods=10000, freq="H") @@ -31,6 +39,13 @@ def test_add_periods(): ) +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) def test_extract_periods_years(): """test method _extract_periods_years of energy system""" t_idx_1 = pd.date_range("1/1/2020", periods=3, freq="H").to_series() diff --git a/tests/test_models.py b/tests/test_models.py index 3ac3938eb..b7e7eda8f 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -68,9 +68,15 @@ def test_infeasible_model(): solph.processing.meta_results(m) +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) def test_multi_period_default_discount_rate(): """Test error being thrown for default multi-period discount rate""" - warnings.filterwarnings("ignore", category=FutureWarning) timeindex = pd.date_range(start="2017-01-01", periods=100, freq="D") es = solph.EnergySystem( timeindex=timeindex, diff --git a/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_dispatch_model.py b/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_dispatch_model.py index 0d2ffec5c..9b1ceef27 100644 --- a/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_dispatch_model.py +++ b/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_dispatch_model.py @@ -15,6 +15,7 @@ """ import pandas as pd +import pytest from oemof.solph import EnergySystem from oemof.solph import Model @@ -25,6 +26,13 @@ from oemof.solph import views +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) def test_multi_period_dispatch_model(solver="cbc"): """Test a simple multi_period dispatch model""" diff --git a/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_investment_model.py b/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_investment_model.py index ccf3e3b91..e8d36f7ce 100644 --- a/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_investment_model.py +++ b/tests/test_scripts/test_solph/test_multi_period_model/test_multi_period_investment_model.py @@ -15,6 +15,7 @@ """ import pandas as pd +import pytest from oemof.solph import EnergySystem from oemof.solph import Model @@ -26,6 +27,13 @@ from oemof.solph import views +@pytest.mark.filterwarnings( + "ignore:Ensure that your timeindex and timeincrement are" + " consistent.:UserWarning" +) +@pytest.mark.filterwarnings( + "ignore:CAUTION! You specified the 'periods' attribute:UserWarning" +) def test_multi_period_investment_model(solver="cbc"): """Test a simple multi_period investment model for multiple SinkDSM approaches""" diff --git a/tests/test_time_index.py b/tests/test_time_index.py index db4049a1b..f5a7aaf03 100644 --- a/tests/test_time_index.py +++ b/tests/test_time_index.py @@ -29,6 +29,12 @@ def test_energysystem_with_datetimeindex(): assert es.timeincrement.sum() == 23 +def test_energysystem_interval_inference_warning(): + datetimeindex = pd.date_range("1/1/2012", periods=24, freq="H") + with pytest.warns(FutureWarning): + _ = solph.EnergySystem(timeindex=datetimeindex) + + def test_energysystem_with_datetimeindex_non_equidistant_infer_last_interval(): """Test EnergySystem with DatetimeIndex (non-equidistant)""" dtindex1 = pd.date_range("1/1/2012", periods=24, freq="H")