Decorator¶
Polyforce is quite versatile and for different tastes. You can use the PolyModel
for you own objects or you can simply use the polycheck
decorator for everything else.
polycheck¶
This is the decorator that helps you with everything you need without the need of using an inherited object.
The same parameters of the PolyModel
are also allowed within the polycheck
.
How to use it¶
When using the polycheck
you must import it first.
from polyforce import polycheck
Once it is imported you can simply subclass it in your objects. Something like this:
from typing import List, Union
from typing_extensions import Self
from polyforce import polycheck
class Movie:
def __init__(
self,
name: str,
year: int,
tags: Union[List[str], None] = None,
) -> None:
self.name = name
self.year = year
self.tags = tags
@polycheck()
def get_movie(self, name: str) -> Self:
"""
Returns a movie
"""
...
@polycheck()
def _set_name(self, name: str) -> None:
"""
Sets the name of the movie.
"""
@polycheck()
@classmethod
def create_movie(cls, name: str, year: int) -> Self:
"""
Creates a movie object
"""
return cls(name=name, year=year)
@polycheck()
@staticmethod
def evaluate_movie(name: str, tags: List[str]) -> bool:
"""
Evaluates a movie in good (true) or bad (false)
"""
...
When adding the polycheck
object, will enable the static type checking to happen all over the
functions declared.
Ignore the checks¶
Well, there is not too much benefit of using polycheck
if you want to ignore the checks, correct?
Well, yes but you still can do it if you want.
There might be some scenarios where you want to override some checks and ignore the checks.
For this, Polyforce uses the Config dictionary.
You simply need to pass ignore=True
and the static type checking will be disabled for the class.
It will look like this:
from typing import List, Union
from typing_extensions import Self
from polyforce import polycheck
class Movie:
def __init__(
self,
name: str,
year: int,
tags: Union[List[str], None] = None,
) -> None:
self.name = name
self.year = year
self.tags = tags
@polycheck(ignore=True)
def get_movie(self, name: str) -> Self:
"""
Returns a movie
"""
...
@polycheck(ignore=True)
def _set_name(self, name: str) -> None:
"""
Sets the name of the movie.
"""
@classmethod
def create_movie(cls, name: str, year: int) -> Self:
"""
Creates a movie object
"""
return cls(name=name, year=year)
@staticmethod
def evaluate_movie(name: str, tags: List[str]) -> bool:
"""
Evaluates a movie in good (true) or bad (false)
"""
...
Tip
The decorator has the same fields as the PolyModel
but since polycheck
is done
on a function basis, applying ignore+True
is the same as not adding the decorator at all.
This serves as example for documentation purposes only.
Ignore specific types¶
What if you want to simply ignore some types? Meaning, you might want to pass arbitrary values that you don't want them to be static checked.
from typing import List, Union
from polyforce import polycheck
class Actor:
...
class Movie:
def __init__(
self,
name: str,
year: int,
tags: Union[List[str], None] = None,
) -> None:
self.name = name
self.year = year
self.tags = tags
self.actors: List[Actor] = []
@polycheck(ignored_types=(Actor,))
def add_actor(self, actor: Actor) -> None:
"""
Returns a movie
"""
self.actors.append(actor)
This will make sure that the type Actor
is actually ignore and assumed as type Any
which also means
you can pass whatever value you desire since the type Actor
is no longer checked.
Integrations¶
Polyforce works also really well with integrations, for instance with Pydantic.
The only thing you need to do is to import the decorator and use it inside the functions you want to enforce.
This example is exactly the same as the one for PolyModel.
from typing import List, Union
from pydantic import BaseModel, ConfigDict
from polyforce import polycheck
class Actor:
...
class Movie(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
name: str
year: int
actors: Union[List[Actor], None] = None
@polycheck()
def add_actor(self, actor: Actor) -> None:
self.actors.append(actor)
@polycheck()
def set_actor(self, actor: Actor) -> None:
...
This way you can use your favourite libraries with Polyforce.