Read-only Protocol
attributes (again)
#1123
Unanswered
bryanforbes
asked this question in
Q&A
Replies: 1 comment
-
With the release of the SQLAlchemy 2.0 betas, this starts to become a lot more relevant. Here's a similar example to the above, but with SQLAlchemy: from __future__ import annotations
from dataclasses import dataclass
from typing import Protocol
from sqlalchemy import Integer, String
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column
class Base(MappedAsDataclass, DeclarativeBase):
...
class Named(Protocol):
@property
def name(self) -> str:
...
@dataclass
class Person:
name: str
class Animal:
__name: str
def __init__(self, name: str) -> None:
self.__name = name
@property
def name(self) -> str:
return self.__name
class Record(Base):
__tablename__ = 'records'
id: Mapped[int] = mapped_column(Integer, primary_key=True, init=False)
name: Mapped[str] = mapped_column(String)
def print_name(obj: Named) -> None:
print(obj.name)
person = Person('John Doe')
animal = Animal('Dog')
record = Record('thing')
print_name(person) # OK
print_name(animal) # OK
print_name(record) # Error: Mapped[str] is incompatible with str |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
In my last question, I asked about how to mark a protocol attribute as read-only in order to accept either an object with a read-only attribute or a writable attribute. I have a similar question, but slightly different: How do I mark a
Protocol
attribute as read-only so that any object that the operationobj.prop
is valid can be passed in. Here's a code sample:In this example, all three objects can have the operation
obj.name
done on them and get a string value back, so it seems like they should match theNamed
protocol. However bothmypy
andpyright
give an error that indicatesunknown.name
is an incompatible type. I can come up with a second protocol that has a descriptor protocol forname
, but that will get incredibly complex if more attributes are needed. Should the convention of using@property
in protocols for read-only attributes apply only to actual@property
and standard attribute declarations, or should it apply to anything that can have theobj.name
operation done on it?Beta Was this translation helpful? Give feedback.
All reactions