Skip to content

Commit

Permalink
Merge pull request #28 from flexiblepower/fix/support-python-3.8
Browse files Browse the repository at this point in the history
adapt code to work in Python 3.8
  • Loading branch information
lfse-slafleur authored Sep 8, 2023
2 parents bd33a58 + 37c70eb commit ca2afe1
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 37 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ jobs:
strategy:
matrix:
python:
# - "3.9"
# - "3.7" # oldest Python supported by PSF
- "3.8"
- "3.9"
- "3.10"
- "3.11" # newest Python that is stable
platform:
- ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions src/s2python/common/number_range.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any
from typing import Any, Dict

from pydantic import root_validator

Expand All @@ -11,7 +11,7 @@ class Config(GenNumberRange.Config):
validate_assignment = True

@root_validator(pre=False)
def validate_start_end_order(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_start_end_order(cls, values: Dict[str, Any]) -> Dict[str, Any]:
if values.get("start_of_range", 0.0) > values.get("end_of_range", 0.0):
raise ValueError(cls, 'start_of_range should not be higher than end_of_range')

Expand Down
4 changes: 2 additions & 2 deletions src/s2python/common/power_range.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any
from typing import Any, Dict

from pydantic import root_validator

Expand All @@ -12,7 +12,7 @@ class Config(GenPowerRange.Config):
validate_assignment = True

@root_validator(pre=False)
def validate_start_end_order(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_start_end_order(cls, values: Dict[str, Any]) -> Dict[str, Any]:
if values.get("start_of_range", 0.0) > values.get("end_of_range", 0.0):
raise ValueError(cls, 'start_of_range should not be higher than end_of_range')

Expand Down
31 changes: 15 additions & 16 deletions src/s2python/common/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@


def commodity_has_quantity(commodity: 'Commodity', quantity: CommodityQuantity) -> bool:
match commodity:
case Commodity.HEAT:
return quantity in [CommodityQuantity.HEAT_THERMAL_POWER,
CommodityQuantity.HEAT_TEMPERATURE,
CommodityQuantity.HEAT_FLOW_RATE]
case Commodity.ELECTRICITY:
return quantity in [CommodityQuantity.ELECTRIC_POWER_3_PHASE_SYMMETRIC,
CommodityQuantity.ELECTRIC_POWER_L1,
CommodityQuantity.ELECTRIC_POWER_L2,
CommodityQuantity.ELECTRIC_POWER_L3]
case Commodity.GAS:
return quantity in [CommodityQuantity.NATURAL_GAS_FLOW_RATE]
case Commodity.OIL:
return quantity in [CommodityQuantity.OIL_FLOW_RATE]
case _:
raise RuntimeError(f'Unsupported commodity {commodity}. Missing implementation.')
if commodity == Commodity.HEAT:
return quantity in [CommodityQuantity.HEAT_THERMAL_POWER,
CommodityQuantity.HEAT_TEMPERATURE,
CommodityQuantity.HEAT_FLOW_RATE]
elif commodity == Commodity.ELECTRICITY:
return quantity in [CommodityQuantity.ELECTRIC_POWER_3_PHASE_SYMMETRIC,
CommodityQuantity.ELECTRIC_POWER_L1,
CommodityQuantity.ELECTRIC_POWER_L2,
CommodityQuantity.ELECTRIC_POWER_L3]
elif commodity == Commodity.GAS:
return quantity in [CommodityQuantity.NATURAL_GAS_FLOW_RATE]
elif commodity == Commodity.OIL:
return quantity in [CommodityQuantity.OIL_FLOW_RATE]
else:
raise RuntimeError(f'Unsupported commodity {commodity}. Missing implementation.')
14 changes: 7 additions & 7 deletions src/s2python/frbc/frbc_actuator_description.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import uuid

from typing import List, Any
from typing import List, Any, Dict

from pydantic import root_validator

Expand All @@ -23,7 +23,7 @@ class Config(GenFRBCActuatorDescription.Config):
supported_commodities: List[Commodity] = GenFRBCActuatorDescription.__fields__['supported_commodities'].field_info # type: ignore[assignment]

@root_validator(pre=False)
def validate_timers_in_transitions(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_timers_in_transitions(cls, values: Dict[str, Any]) -> Dict[str, Any]:
timers_by_id = {timer.id: timer for timer in values.get("timers", {})}
transition: Transition
for transition in values.get("transitions", []):
Expand All @@ -40,7 +40,7 @@ def validate_timers_in_transitions(cls, values: dict[str, Any]) -> dict[str, Any
return values

@root_validator(pre=False)
def validate_timers_unique_ids(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_timers_unique_ids(cls, values: Dict[str, Any]) -> Dict[str, Any]:
ids = []
timer: Timer
for timer in values.get("timers", []):
Expand All @@ -51,7 +51,7 @@ def validate_timers_unique_ids(cls, values: dict[str, Any]) -> dict[str, Any]:
return values

@root_validator(pre=False)
def validate_operation_modes_in_transitions(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_operation_modes_in_transitions(cls, values: Dict[str, Any]) -> Dict[str, Any]:
operation_mode_by_id = {operation_mode.id: operation_mode
for operation_mode in values.get("operation_modes", [])}
transition: Transition
Expand All @@ -67,7 +67,7 @@ def validate_operation_modes_in_transitions(cls, values: dict[str, Any]) -> dict
return values

@root_validator(pre=False)
def validate_operation_modes_unique_ids(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_operation_modes_unique_ids(cls, values: Dict[str, Any]) -> Dict[str, Any]:
ids = []
operation_mode: FRBCOperationMode
for operation_mode in values.get("operation_modes", []):
Expand All @@ -78,7 +78,7 @@ def validate_operation_modes_unique_ids(cls, values: dict[str, Any]) -> dict[str
return values

@root_validator(pre=False)
def validate_operation_mode_elements_have_all_supported_commodities(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_operation_mode_elements_have_all_supported_commodities(cls, values: Dict[str, Any]) -> Dict[str, Any]:
supported_commodities = values.get('supported_commodities', [])
operation_mode: FRBCOperationMode
for operation_mode in values.get("operation_modes", []):
Expand All @@ -99,7 +99,7 @@ def validate_operation_mode_elements_have_all_supported_commodities(cls, values:
return values

@root_validator(pre=False)
def validate_unique_supported_commodities(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_unique_supported_commodities(cls, values: Dict[str, Any]) -> Dict[str, Any]:
supported_commodities: list[CommodityQuantity] = values.get('supported_commodities', [])

for supported_commodity in supported_commodities:
Expand Down
10 changes: 5 additions & 5 deletions src/s2python/frbc/frbc_operation_mode.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from itertools import pairwise
#from itertools import pairwise
import uuid
from typing import List, Dict, Any
from typing import List, Dict, Any, Generator, Tuple

from pydantic import root_validator

from s2python.common import NumberRange
from s2python.frbc import FRBCOperationModeElement
from s2python.generated.gen_s2 import FRBCOperationMode as GenFRBCOperationMode
from s2python.validate_values_mixin import ValidateValuesMixin, catch_and_convert_exceptions

from s2python.utils import pairwise

@catch_and_convert_exceptions
class FRBCOperationMode(GenFRBCOperationMode, ValidateValuesMixin['FRBCOperationMode']):
Expand All @@ -19,11 +19,11 @@ class Config(GenFRBCOperationMode.Config):
elements: List[FRBCOperationModeElement] = GenFRBCOperationMode.__fields__['elements'].field_info # type: ignore[assignment]

@root_validator(pre=False)
def validate_contiguous_fill_levels_operation_mode_elements(cls, values: dict[str, Any]) -> dict[str, Any]:
def validate_contiguous_fill_levels_operation_mode_elements(cls, values: Dict[str, Any]) -> Dict[str, Any]:
elements_by_fill_level_range: Dict[NumberRange, FRBCOperationModeElement]
elements_by_fill_level_range = {element.fill_level_range: element for element in values.get('elements', [])}

sorted_fill_level_ranges: list[NumberRange]
sorted_fill_level_ranges: List[NumberRange]
sorted_fill_level_ranges = list(elements_by_fill_level_range.keys())
sorted_fill_level_ranges.sort(key=lambda r: r.start_of_range)

Expand Down
3 changes: 3 additions & 0 deletions src/s2python/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def pairwise(arr : list):
for i in range(max(len(arr) - 1,0)):
yield (arr[i], arr[i+1])
6 changes: 3 additions & 3 deletions src/s2python/validate_values_mixin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TypeVar, Generic, Protocol, Type, Tuple, Optional, Callable, cast, Any, Union, AbstractSet, Mapping
from typing import TypeVar, Generic, Protocol, Type, Tuple, Optional, Callable, cast, Any, Union, AbstractSet, Mapping, List, Dict

from pydantic import BaseModel, StrBytes, Protocol as PydanticProtocol, ValidationError

Expand Down Expand Up @@ -43,7 +43,7 @@ def dict(
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
) -> dict[str, Any]: ...
) -> Dict[str, Any]: ...

@classmethod
def parse_raw(cls,
Expand Down Expand Up @@ -75,7 +75,7 @@ def from_json(cls: Type[C], json_str: str) -> C:


def convert_to_s2exception(f : Callable) -> Callable:
def inner(*args: list[Any], **kwargs: dict[str, Any]) -> Any:
def inner(*args: List[Any], **kwargs: Dict[str, Any]) -> Any:
try:
return f(*args, **kwargs)
except (ValidationError, TypeError) as e:
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from unittest import TestCase

from s2python.utils import pairwise

class PairwiseTest(TestCase):
def test_empty(self):
# Arrange
input_array = []

# Act
pairs = list(pairwise(input_array))

# Assert
self.assertEqual(len(pairs), 0)

def test_len_2(self):
# Arrange
input_array = [1,2]

# Act
pairs = list(pairwise(input_array))

# Assert
self.assertEqual(pairs, [(1,2)])

def test_odd(self):
# Arrange
input_array = [1,2,3]

# Act
pairs = list(pairwise(input_array))

# Assert
self.assertEqual(pairs, [(1,2), (2,3)])

def test_even(self):
# Arrange
input_array = [1,2,3,4]

# Act
pairs = list(pairwise(input_array))

# Assert
self.assertEqual(pairs, [(1,2), (2,3), (3,4)])
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ isolated_build = True

[testenv]
description = Invoke pytest to run automated tests

setenv =
TOXINIDIR = {toxinidir}
passenv =
Expand Down

0 comments on commit ca2afe1

Please sign in to comment.