Skip to content

Commit 60f0752

Browse files
mypy
1 parent 680a569 commit 60f0752

5 files changed

Lines changed: 40 additions & 20 deletions

File tree

mp_api/client/contribs/_types.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
import gzip
6+
from abc import ABCMeta, abstractmethod
67
from base64 import b64decode, b64encode
78
from inspect import getfullargspec
89
from pathlib import Path
@@ -30,6 +31,18 @@
3031
j2h = Json2Html()
3132

3233

34+
class _Component(metaclass=ABCMeta):
35+
"""Define component which requires a from_dict method.
36+
37+
Mostly exists for mypy checking.
38+
"""
39+
40+
@classmethod
41+
@abstractmethod
42+
def from_dict(cls, dct: dict):
43+
"""Instantiate from a dict."""
44+
45+
3346
class MPCDict(dict):
3447
"""Custom dictionary to display itself as HTML table with Bulma CSS."""
3548

@@ -49,7 +62,7 @@ def display(self, attrs: str = f'class="table {MPCC_SETTINGS.BULMA}"'):
4962
return display(HTML(html)) if _in_ipython() else html
5063

5164

52-
class Table(pd.DataFrame):
65+
class Table(pd.DataFrame, _Component):
5366
"""Wrapper class around pandas.DataFrame to provide display() and info()."""
5467

5568
def display(self):
@@ -139,7 +152,7 @@ def as_dict(self):
139152
return dct
140153

141154

142-
class MPCStructure(PmgStructure):
155+
class MPCStructure(PmgStructure, _Component):
143156
"""Wrapper class around pymatgen.Structure to provide display() and info()."""
144157

145158
def display(self):
@@ -178,7 +191,7 @@ def from_dict(
178191
return super().from_dict(dct)
179192

180193

181-
class Attachment(dict):
194+
class Attachment(dict, _Component):
182195
"""Wrapper class around dict to handle attachments."""
183196

184197
def decode(self) -> bytes:
@@ -272,9 +285,7 @@ def from_file(cls, path: str | Path) -> Self:
272285
content = path.read_bytes()
273286

274287
if not (
275-
supported := any(
276-
isinstance(kind, ftyp) for ftyp in MPCC_SETTINGS.SUPPORTED_FILETYPES
277-
)
288+
supported := kind in MPCC_SETTINGS.SUPPORTED_FILETYPES
278289
): # try to gzip text file
279290
try:
280291
content = gzip.compress(content)

mp_api/client/contribs/client.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
from bravado_core.spec import Spec, _identity, build_api_serving_url
3535
from bravado_core.validate import validate_object
3636
from bson.objectid import ObjectId
37-
from cachetools import LRUCache, cached
38-
from cachetools.keys import hashkey
37+
from cachetools import LRUCache, cached # type: ignore[import-untyped]
38+
from cachetools.keys import hashkey # type: ignore[import-untyped]
3939
from jsonschema.exceptions import ValidationError
4040
from pint.errors import DimensionalityError
4141
from pyisemail import is_email
@@ -47,7 +47,13 @@
4747
from tqdm.auto import tqdm
4848
from urllib3.util.retry import Retry
4949

50-
from mp_api.client.contribs._types import Attachment, MPCDict, MPCStructure, Table
50+
from mp_api.client.contribs._types import (
51+
Attachment,
52+
MPCDict,
53+
MPCStructure,
54+
Table,
55+
_Component,
56+
)
5157
from mp_api.client.contribs._units import ureg
5258
from mp_api.client.contribs.logger import MPCC_LOGGER, TqdmToLogger
5359
from mp_api.client.contribs.schemas import (
@@ -738,7 +744,7 @@ def query_projects(
738744
fields: list | None = None,
739745
sort: str | None = None,
740746
timeout: int = -1,
741-
) -> list[dict] | list[ContribsProject]:
747+
) -> list[MPCDict] | list[ContribsProject]:
742748
"""Query projects by query and/or term (Atlas Search).
743749
744750
See `client.available_query_params(resource="projects")` for keyword arguments used in
@@ -758,7 +764,7 @@ def query_projects(
758764
query = query or {}
759765

760766
if self.project or "name" in query:
761-
return self.get_project(name=query.get("name"), fields=fields)
767+
return [self.get_project(name=query.get("name"), fields=fields)] # type: ignore[return-value]
762768

763769
if term:
764770

@@ -1219,7 +1225,7 @@ def init_columns(
12191225
f"Can't convert {existing_unit} to {new_unit} for {path}"
12201226
)
12211227
try:
1222-
factor = ureg.convert(1, *conv_args)
1228+
factor = ureg.convert(1, *conv_args) # type: ignore[arg-type]
12231229
except DimensionalityError:
12241230
raise MPContribsClientError(
12251231
f"Can't convert {existing_unit} to {new_unit} for {path}"
@@ -1704,7 +1710,7 @@ def query_contributions(
17041710
).result()
17051711

17061712
if len(ret["data"]) > 0 and self.use_document_model: # type: ignore[arg-type]
1707-
ret["data"] = [ContribData(**doc) for doc in ret["data"]]
1713+
ret["data"] = [ContribData(**doc) for doc in ret["data"]] # type: ignore[arg-type,misc,union-attr]
17081714

17091715
return (
17101716
_convert_to_model( # type: ignore[return-value]
@@ -2327,7 +2333,7 @@ def download_contributions(
23272333

23282334
match component:
23292335
case "structures":
2330-
component_cls = MPCStructure
2336+
component_cls: type[_Component] = MPCStructure
23312337
case "tables":
23322338
component_cls = Table
23332339
case "attachments":

mp_api/client/contribs/logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,4 @@ def write(self, buf: str) -> int:
9494
return 1
9595

9696
def flush(self) -> None:
97-
self.logger.log(self.level, self.buf)
97+
self.logger.log(self.level, self.buf) # type: ignore[arg-type]

mp_api/client/contribs/schemas.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import re
55
from datetime import datetime, timezone
6-
from typing import Any, Literal, Self, get_args
6+
from typing import TYPE_CHECKING, Any, Literal, Self, get_args
77

88
import pandas as pd
99
from pydantic import BaseModel, Field, create_model, field_serializer, field_validator
@@ -12,11 +12,14 @@
1212
from mp_api.client.contribs.utils import flatten_dict, unflatten_dict
1313
from mp_api.client.core.schemas import _DictLikeAccess
1414

15+
if TYPE_CHECKING:
16+
from types import UnionType
17+
1518
CONTRIBS_DOC_NAME = "ContribsDoc"
1619
"""Parent name of the dynamically-created contribs docs, similar to `MPDataDoc`."""
1720

1821

19-
def _cast_pandas_dtype(dtype: type, assume_nullable: bool = True) -> type:
22+
def _cast_pandas_dtype(dtype: type, assume_nullable: bool = True) -> type | UnionType:
2023
"""Convert pandas dtype to built-in types.
2124
2225
Args:
@@ -116,7 +119,7 @@ def _get_pydantic_from_dataframe(
116119
if not all(pd.isna(df[col_name]))
117120
}
118121

119-
return create_model("InferredModel", **model_fields), columns_renamed
122+
return create_model("InferredModel", **model_fields), columns_renamed # type: ignore[call-overload]
120123

121124

122125
class Reference(_DictLikeAccess):
@@ -239,7 +242,7 @@ def construct_data(cls, d: dict) -> dict[str, str | Datum]:
239242
}
240243
return {
241244
k: (
242-
Datum(
245+
Datum( # type: ignore[misc]
243246
**{
244247
sub_k: flattened_data_dct.get(f"{k}.{sub_k}", field.default)
245248
for sub_k, field in Datum.model_fields.items()

mp_api/client/mprester.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ def __init__(
247247
)
248248

249249
@property
250-
def contribs(self) -> None:
250+
def contribs(self):
251251
"""Create an instance of the MP ContribsClient.
252252
253253
NB: The following args are taken from `MPRester`:

0 commit comments

Comments
 (0)