Skip to content

Commit

Permalink
Refactor conditional imports for Pydantic versions
Browse files Browse the repository at this point in the history
- Remove asserts
  • Loading branch information
DiamondJoseph committed Jul 19, 2023
1 parent ed012a9 commit 11e42d4
Show file tree
Hide file tree
Showing 25 changed files with 90 additions and 88 deletions.
4 changes: 2 additions & 2 deletions docs/user/tutorials/create-a-device.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ if the device requires any adapters to control it externally.

.. code-block:: python
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation
@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Amplifier(ComponentConfig):
initial_amplification: float
Expand Down
2 changes: 1 addition & 1 deletion docs/user/tutorials/use-composed-adapter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ our amplifier `ComponentConfig`. To do this we simply add it to the arguments of

.. code-block:: python
@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Amplifier(ComponentConfig):
initial_amplification: int
Expand Down
2 changes: 1 addition & 1 deletion examples/configs/amplifier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
- type: tickit.devices.sink.Sink
name: sink
inputs:
input: amp:amplified_signal
input: amp:amplified_signal
2 changes: 1 addition & 1 deletion examples/configs/counter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
- type: tickit.devices.sink.Sink
name: counter_sink
inputs:
input: counter:_value
input: counter:_value
2 changes: 1 addition & 1 deletion examples/configs/shutter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
- type: tickit.devices.sink.Sink
name: sink
inputs:
flux: shutter:flux
flux: shutter:flux
4 changes: 2 additions & 2 deletions examples/devices/amplifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.byte_format import ByteFormat
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass


class AmplifierDevice(Device):
Expand Down Expand Up @@ -88,7 +88,7 @@ async def set_amplification(self, amplification: float) -> None:
self.device.amplification = amplification


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Amplifier(ComponentConfig):
"""Amplifier you can set the amplification value of over TCP."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Counter(ComponentConfig):
"""Simulation of simple counting device."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/http_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.devices.iobox import IoBoxDevice
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass


class IoBoxHttpAdapter(HttpAdapter):
Expand Down Expand Up @@ -43,7 +43,7 @@ async def read_from_address(self, request: web.Request) -> web.Response:
return web.json_response({address: value})


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class ExampleHTTP(ComponentConfig):
"""Example HTTP device."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/isolated_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.byte_format import ByteFormat
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass


class IsolatedBoxDevice(Device):
Expand Down Expand Up @@ -116,7 +116,7 @@ def on_db_load(self) -> None:
self.link_input_on_interrupt(builder.aIn("VALUE_RBV"), self.device.get_value)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class IsolatedBox(ComponentConfig):
"""Isolated box device you can change the value of either over TCP or via EPICS."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/remote_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.byte_format import ByteFormat
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -222,7 +222,7 @@ async def yield_observed(self, n: int = 10) -> AsyncIterable[bytes]:
yield f"Observed is {self.device.observed}".encode("utf-8")


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class RemoteControlled(ComponentConfig):
"""Thing you can poke over TCP."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/shutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.byte_format import ByteFormat
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass


class ShutterDevice(Device):
Expand Down Expand Up @@ -153,7 +153,7 @@ async def set_target(self, target: str) -> None:
self.device.last_time = None


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Shutter(ComponentConfig):
"""Shutter you can open or close over TCP."""

Expand Down
4 changes: 2 additions & 2 deletions examples/devices/trampoline.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -90,7 +90,7 @@ def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class RandomTrampoline(ComponentConfig):
"""Random thing that goes boing."""

Expand Down
5 changes: 3 additions & 2 deletions examples/devices/zeromq_push_device.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass, field
from dataclasses import field
from typing import Optional, Set

from tickit.adapters.zeromq.push_adapter import (
Expand All @@ -9,6 +9,7 @@
from tickit.core.components.component import Component, ComponentConfig
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.devices.iobox import IoBoxDevice
from tickit.utils.compat.typing_compat import pydantic_dataclass


class IoBoxZeroMqAdapter(ZeroMqPushAdapter):
Expand All @@ -33,7 +34,7 @@ def after_update(self):
self.send_message([{address: value}])


@dataclass
@pydantic_dataclass
class ExampleZeroMqPusher(ComponentConfig):
"""Device that can publish writes to its memory over a zeromq socket."""

Expand Down
6 changes: 1 addition & 5 deletions src/tickit/adapters/zeromq/push_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@

from tickit.core.adapter import Adapter, RaiseInterrupt
from tickit.core.device import Device

try:
from pydantic.v1 import BaseModel
except ImportError:
from pydantic import BaseModel # type: ignore
from tickit.utils.compat.typing_compat import BaseModel

LOGGER = logging.getLogger(__name__)

Expand Down
4 changes: 2 additions & 2 deletions src/tickit/core/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
SimTime,
StopComponent,
)
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass
from tickit.utils.configuration.configurable import as_tagged_union
from tickit.utils.topic_naming import input_topic, output_topic

Expand Down Expand Up @@ -55,7 +55,7 @@ async def on_tick(self, time: SimTime, changes: Changes):


@as_tagged_union
@pydantic.dataclasses.dataclass
@pydantic_dataclass
class ComponentConfig:
"""A data container for component configuration.
Expand Down
4 changes: 2 additions & 2 deletions src/tickit/core/components/system_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from tickit.core.runner import run_all
from tickit.core.state_interfaces.state_interface import StateConsumer, StateProducer
from tickit.core.typedefs import Changes, ComponentID, ComponentPort, PortID, SimTime
from tickit.utils.compat.typing_compat import pydantic
from tickit.utils.compat.typing_compat import pydantic_dataclass
from tickit.utils.topic_naming import output_topic

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -99,7 +99,7 @@ async def stop_component(self) -> None:
task.cancel()


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class SystemSimulation(ComponentConfig):
"""Simulation of a nested set of components."""

Expand Down
4 changes: 2 additions & 2 deletions src/tickit/devices/iobox.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -120,7 +120,7 @@ def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
return DeviceUpdate(IoBoxDevice.Outputs(updates=updates), None)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class IoBox(ComponentConfig):
"""Arbitrary box of key-value pairs."""

Expand Down
4 changes: 2 additions & 2 deletions src/tickit/devices/sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -34,7 +34,7 @@ def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
return DeviceUpdate(SinkDevice.Outputs(), None)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Sink(ComponentConfig):
"""Arbitrary value sink that logs the value."""

Expand Down
4 changes: 2 additions & 2 deletions src/tickit/devices/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tickit.core.components.device_simulation import DeviceSimulation
from tickit.core.device import Device, DeviceUpdate
from tickit.core.typedefs import SimTime
from tickit.utils.compat.typing_compat import TypedDict, pydantic
from tickit.utils.compat.typing_compat import TypedDict, pydantic_dataclass

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -42,7 +42,7 @@ def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
return DeviceUpdate(SourceDevice.Outputs(value=self.value), None)


@pydantic.dataclasses.dataclass
@pydantic_dataclass
class Source(ComponentConfig):
"""Source of a fixed value."""

Expand Down
36 changes: 33 additions & 3 deletions src/tickit/utils/compat/typing_compat.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
import sys

try:
import pydantic.v1 as pydantic
from pydantic.v1 import (
BaseConfig,
BaseModel,
Field,
ValidationError,
create_model,
parse_obj_as,
)
from pydantic.v1.dataclasses import dataclass as pydantic_dataclass
from pydantic.v1.error_wrappers import ErrorWrapper
except ImportError:
import pydantic # type: ignore[no-redef]
from pydantic import ( # type: ignore
BaseConfig,
BaseModel,
Field,
ValidationError,
create_model,
parse_obj_as,
)
from pydantic.dataclasses import dataclass as pydantic_dataclass # type: ignore
from pydantic.error_wrappers import ErrorWrapper # type: ignore


if sys.version_info >= (3, 8):
from typing import Protocol, TypedDict, runtime_checkable
elif sys.version_info >= (3, 5):
from typing_extensions import Protocol, TypedDict, runtime_checkable

__all__ = ["Protocol", "TypedDict", "runtime_checkable", "pydantic"]
__all__ = [
"Protocol",
"TypedDict",
"runtime_checkable",
"pydantic_dataclass",
"ErrorWrapper",
"BaseConfig",
"BaseModel",
"create_model",
"Field",
"parse_obj_as",
"ValidationError",
]
36 changes: 13 additions & 23 deletions src/tickit/utils/configuration/configurable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,14 @@
from importlib import import_module
from typing import Any, Callable, Literal, Optional, Type, Union

try:
from pydantic.v1 import (
BaseConfig,
Field,
ValidationError,
create_model,
parse_obj_as,
)
from pydantic.v1.error_wrappers import ErrorWrapper
except ImportError:
from pydantic import ( # type: ignore
BaseConfig,
Field,
ValidationError,
create_model,
parse_obj_as,
)
from pydantic.error_wrappers import ErrorWrapper # type: ignore
from tickit.utils.compat.typing_compat import (
BaseConfig,
ErrorWrapper,
Field,
ValidationError,
create_model,
parse_obj_as,
)


def as_tagged_union(
Expand Down Expand Up @@ -50,9 +40,9 @@ def _as_tagged_union(

def _load_module_with_type(values: dict[str, str]) -> None:
fullname = values.get(discriminator)
assert fullname
pkg, clsname = fullname.rsplit(".", maxsplit=1)
getattr(import_module(pkg), clsname)
if fullname:
pkg, clsname = fullname.rsplit(".", maxsplit=1)
getattr(import_module(pkg), clsname)

def __init_subclass__(cls) -> None:
super_cls._model = None
Expand Down Expand Up @@ -85,8 +75,8 @@ def __validate__(cls, v: Any) -> Any:
__config__=config,
)
try:
assert cls._model
return cls._model(__root__=v).__root__
if cls._model:
return cls._model(__root__=v).__root__
except ValidationError as e:
for (
error
Expand Down
Loading

0 comments on commit 11e42d4

Please sign in to comment.