Skip to content

Commit

Permalink
Shout out @uriyyo fix for Scalar. Next we gotta fix Prefixed.
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-fritchman committed Mar 26, 2024
1 parent d97d925 commit a141cac
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 53 deletions.
8 changes: 5 additions & 3 deletions hdl21/datatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ def _update_forward_refs():
tp.__pydantic_model__.update_forward_refs()

else: # _pydantic_major_version==2
from pydantic import Extra, BaseModel, RootModel
from pydantic import Extra, BaseModel, RootModel, BeforeValidator

PYDANTIC_V2 = True
OurBaseConfig = dict(allow_extra="forbid")
AllowArbConfig = dict(allow_extra="forbid", arbitrary_types_allowed=True)
OurBaseConfig = dict(allow_extra="forbid", validate_default=True)
AllowArbConfig = dict(
allow_extra="forbid", validate_default=True, arbitrary_types_allowed=True
)

def _update_forward_refs():
"""Update all the forward type-references"""
Expand Down
2 changes: 1 addition & 1 deletion hdl21/prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def __ge__(self, other) -> bool:
ToPrefixed = Union[int, float, str, Decimal]


def to_prefixed(v: Union[Prefixed, "ToPrefixed"]) -> Prefixed:
def to_prefixed(v: Union[Prefixed, ToPrefixed]) -> Prefixed:
"""Convert any convertible type to a `Prefixed` number."""

if isinstance(v, Prefixed):
Expand Down
3 changes: 0 additions & 3 deletions hdl21/proto/exporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,6 @@ def export_param_value(val: ToVlsirParam) -> Optional[vlsir.ParamValue]:
return vlsir.ParamValue(literal=val.value)

# Internal numeric (and number-like) types
if isinstance(val, Scalar):
# `Scalar` will either have an internal `Literal` or `Prefixed` value.
val = val.inner
if isinstance(val, Literal): # String/ expression literals
return vlsir.ParamValue(literal=val.text)
if isinstance(val, Prefixed):
Expand Down
43 changes: 9 additions & 34 deletions hdl21/scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ class MyMosParams:
MyMosParams(w="11*l", l=11)
```
"""
from typing import Union
from decimal import Decimal

# Std-Lib Imports
from typing import Union, Annotated
from decimal import Decimal

# Local Imports
from .datatype import _pydantic_major_version
Expand Down Expand Up @@ -106,39 +107,13 @@ def __get_validators__(cls):
yield to_scalar

else:
from .datatype import RootModel
from pydantic_core import core_schema
from pydantic import BaseModel, GetCoreSchemaHandler
from typing import Any, Type

class Scalar(RootModel):
root: Union[Prefixed, Literal]
__doc__ = _doc

def __init__(self, *_, **__):
# Brick any attempts to create instances
msg = f"Invalid attempt to instantiate a `Scalar` directly. "
msg += f"Create either of its variants `Prefixed` or `Literal` instead, "
msg += f"or use their built-in conversions from strings, ints, floats, and Decimals."
raise RuntimeError(msg)

@classmethod
def __get_pydantic_core_schema__(
cls, source: Type[Any], _handler: GetCoreSchemaHandler
) -> core_schema.CoreSchema:
# if source is not Scalar:
# raise TabError("HUH Invalid source")
return core_schema.no_info_after_validator_function(
to_scalar,
core_schema.union_schema([core_schema.model_schema(), Literal]),
serialization=None,
# core_schema.plain_serializer_function_ser_schema(
# cls._serialize,
# info_arg=False,
# return_schema=core_schema.str_schema(),
# ),
)
from pydantic import BeforeValidator

# Union of types convertible into `Scalar`
Scalar = Annotated[
Union[Prefixed, Literal],
BeforeValidator(to_scalar),
]

__all__ = ["Scalar", "ToScalar", "to_scalar"]
__doc__ = _doc
2 changes: 0 additions & 2 deletions hdl21/sim/proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,6 @@ def export_float(num: Union[float, int, Decimal, Prefixed, Scalar]) -> float:
return 0.0
if isinstance(num, float):
return num
if isinstance(num, Scalar):
return float(num.inner)
if isinstance(num, (int, str, Decimal, Prefixed)):
return float(num)
raise TypeError(f"Invalid value for proto float: {num}")
4 changes: 2 additions & 2 deletions hdl21/tests/test_prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ def test_prefixed_mul():


def test_prefixed_div():

"""Test `Prefixed` True Division"""
from hdl21.prefix import e

Expand Down Expand Up @@ -481,7 +480,8 @@ def test_not_implemented_exponent():
def test_prefixed_and_scalar_conversions():
"""Test inline conversions of built-in numeric types to `Prefixed` and `Scalar`."""

@dataclass
# FIXME: we may wanna export this config, or it applied to `dataclass` by default
@dataclass(config=dict(allow_extra="forbid", validate_default=True))
class P:
x: h.Prefixed
y: h.Scalar
Expand Down
5 changes: 1 addition & 4 deletions pdks/Gf180/gf180_hdl21/pdk_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,8 @@ def scale_param(self, orig: Optional[h.Scalar], default: h.Prefixed) -> h.Scalar
Primarily type-dispatches across the need to scale to microns for this PDK."""
if orig is None:
return default
if not isinstance(orig, h.Scalar):
orig = h.scalar.to_scalar(orig)

if isinstance(orig, h.Prefixed):
return orig
return orig # FIXME: where's the scaling?
if isinstance(orig, h.Literal):
return h.Literal(f"({orig} * 1e6)")
raise TypeError(f"Param Value {orig}")
Expand Down
5 changes: 1 addition & 4 deletions pdks/Sky130/sky130_hdl21/pdk_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,8 @@ def scale_param(self, orig: Optional[h.Scalar], default: h.Prefixed) -> h.Scalar
Primarily type-dispatches across the need to scale to microns for this PDK."""
if orig is None:
return default
if not isinstance(orig, h.Scalar):
orig = h.scalar.to_scalar(orig)

if isinstance(orig, h.Prefixed):
return orig
return orig # FIXME: where's the scaling?
if isinstance(orig, h.Literal):
return h.Literal(f"({orig} * 1e6)")
raise TypeError(f"Param Value {orig}")
Expand Down

1 comment on commit a141cac

@uriyyo
Copy link

@uriyyo uriyyo commented on a141cac Mar 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always happy to help you!

Please sign in to comment.