Skip to content

Commit e4a0c10

Browse files
authored
set __annotations__, describe intellisense limitations (#29)
1 parent 7a01a10 commit e4a0c10

File tree

6 files changed

+23
-40
lines changed

6 files changed

+23
-40
lines changed

attrs_mypy.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ An `xarray <https://docs.xarray.dev/en/stable/index.html>`_ integration for `att
1717
md/what
1818
md/how
1919
md/rules
20+
md/gotchas
2021
examples/basics
2122
examples/indexes
2223

docs/md/gotchas.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Gotchas
2+
3+
## Intellisense
4+
5+
Your average felid is aloof by constitution &mdash; similarly, this library keeps to itself, though it will not prevent you from exposing *your* (classes') guts in public if you so choose.
6+
7+
Since `xattree`-managed fields are attached via [`field_transformer`](https://www.attrs.org/en/stable/extending.html#automatic-field-transformation-and-modification), *they are not visible to static type checkers*. Static checkers don't run your code, they just look at it. This means you will not see fields like `data` (or whatever else you called your `DataTree` field), `parent`, etc in the initializer signature on hovering over your class, nor will you see an informative type hint on hovering over `xattree`-managed attributes. Intellisense *will* work properly on your own fields.
8+
9+
## `__annotations__`
10+
11+
Despite the above, `xattree` updates your class' `__anotations__` with the `xattree`-managed field information, in case you need it at runtime.

docs/md/rules.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,3 @@ By default, `xattree` names the datatree attribute `data`. To name it something
7979
Unlike typical appointments of wood and fabric, wherever you put the tree, that's where it stays. If you try to move it (at runtime), things will break. If you regret your choice, tough luck &mdash; find a new apartment (i.e. kill the program and set `where` to something else).
8080

8181
**Note**: some names are reserved, namely the core `xattree`-managed fields (`name`, `parent`, `children`, `dims`, and `strict`).
82-

pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,6 @@ ignore = [
9797

9898
[tool.mypy]
9999
mypy_path = "xattree"
100-
plugins = [
101-
"attrs_mypy.py",
102-
]
103100
ignore_missing_imports = true
104101
warn_unreachable = true
105102

xattree/__init__.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,12 @@ def post_init(self):
15711571
converters = {}
15721572
validators = {}
15731573

1574+
# rename the datatree field to `where`
1575+
xtra_attrs = _XTRA_ATTRS.copy()
1576+
datatree = xtra_attrs.pop(_DATA)
1577+
xtra_attrs[where] = datatree
1578+
xtra_attrs = {n: f(cls) if callable(f) else f for n, f in xtra_attrs.items()}
1579+
15741580
def transformer(cls: type, fields: list[Attribute]) -> Iterator[Attribute]:
15751581
def _transform_field(field: Attribute) -> Attribute:
15761582
if field.name in _XTRA_ATTRS.keys():
@@ -1671,17 +1677,11 @@ def _transform_field(field: Attribute) -> Attribute:
16711677
alias=field.alias,
16721678
)
16731679

1674-
# rename the datatree field
1675-
xtra_attrs = _XTRA_ATTRS.copy()
1676-
datatree = xtra_attrs.pop(_DATA)
1677-
xtra_attrs[where] = datatree
1678-
16791680
if is_xattree:
16801681
fields = [f for f in fields if f.name not in xtra_attrs.keys()]
16811682

16821683
attrs_ = [_transform_field(f) for f in fields]
1683-
extra = [f(cls) if callable(f) else f for f in xtra_attrs.values()]
1684-
return attrs_ + extra # type: ignore
1684+
return attrs_ + list(xtra_attrs.values()) # type: ignore
16851685

16861686
old_setattr = cls.__setattr__
16871687

@@ -1747,10 +1747,11 @@ def drop_matching_children(node: xr.DataTree) -> xr.DataTree:
17471747
_CONVERTERS: converters,
17481748
_VALIDATORS: validators,
17491749
}
1750-
# Register this class for parent lookup
1750+
cls.__annotations__ = {
1751+
**getattr(cls, "__annotations__", {}),
1752+
**{n: field.type for n, field in xtra_attrs.items()},
1753+
}
17511754
_XATTREE_CLASSES.add(cls)
1752-
1753-
# Update dimension groups for all classes now that we have a new class
17541755
_update_dim_groups()
17551756

17561757
return cls

0 commit comments

Comments
 (0)