Howdy.
An important use case that I feel has been very underserved by typing is handling only a subset of a classes fields.
For example, imagine you have a SQL table modeled as a class, with columns mapping to fields (a very common modeling approach). Your class has 30 fields, but you only need 3. Fetching all 30 is more work for the database, the networking stack, and your app, for no reason.
Another example is hitting a 3rd party HTTP endpoint. You’ve modeled the data coming back as a class, the class has a ton of fields but you only need a few. Even independently of whether you can get the API to only send a subset, you’ll be spending unnecessary resources constantly decoding data you don’t want.
Enter a TypeScript concept called pick types. The idea is to create a new class from an existing class by picking a subset of the existing fields.
A hypothetical example:
from dataclasses import dataclass
@dataclass
class Model:
an_int: int
a_float: float
# We only want the int though
from typing import Pick
loaded = fetch(Pick[Model, "an_int"]) # We pick only the "an_int" field
# loaded is an instance of Pick[Model, "an_int"]
reveal_type(loaded.an_int) # int
reveal_type(loaded.a_float) # Attribute error
The main benefit is that if you refactor the an_int
field to have a different type, the picks will automatically pick that up (pun intended). So it’s DRY, succinct and type-safe.
Speaking on behalf of attrs, I think this is easily doable at runtime. The main issue would be type checking.
I think we would need a degree of structural typing for this to be usable. Model
would need to be treated as a subtype of all of its Picks, and I guess a Pick[Model, "an_int"]
needs to be treated as a supertype of Pick[Model, "an_int", "a_float"]
(and any other picks where the fields are a superset of this pick’s fields.
Is this a good idea for Python?