Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type annotations for io.vasp.outputs #3776

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

DanielYang59
Copy link
Contributor

@DanielYang59 DanielYang59 commented Apr 21, 2024

Summary

  • Add type annotations for io.vasp.outputs, a follow-up PR of Add type annotations for io.vasp.inputs/optics #3740.
  • Use PathLike as type over str for all paths.
  • Add missing docstrings and clean up docstrings.
  • Lazily import Vasprun/Xdatcar in Trajectory to be consistent with other part of the class.

@janosh janosh added io Input/output functionality vasp Vienna Ab initio Simulation Package types Type all the things labels Apr 21, 2024
@DanielYang59
Copy link
Contributor Author

@janosh While you are working on improving dcostrings, can you please skip this io.vasp.outputs part to avoid overlapping? I would help fixing some docstring issues while adding types. Thanks!

@DanielYang59
Copy link
Contributor Author

DanielYang59 commented May 6, 2024

I'm now facing significant resistance from the "default value as None behavior" (most mypy errors are more or less related to possible default None values), similar to #3724.

Default values for get or similar methods

For the following example:

poscar_dict = {"lattice": Lattice, "pos": Position}  # a terrible example dict

- comment: str | None = poscar_dict.get("comment", None)
+ comment: str = poscar_dict.get("comment", "")

# More downstream operations that only works for `str`
clean_comment = comment.strip()

Using empty str "" could avoid the type being expanded to str | None.

Or perhaps:

@property
def net_magnetization(self):
"""Net magnetization from Chgcar"""
return np.sum(self.data["diff"]) if self.is_spin_polarized else None

Such default values as None would expand the type from float to float | None, meaning all downstream operations (or child objects) need to explicitly check for None.

Default values for functions/methods

For example

def __init__(
self,
filename: str | Path,
ionic_step_skip: int | None = None,
ionic_step_offset: int = 0,
parse_dos: bool = True,
parse_eigen: bool = True,
parse_projected_eigen: bool = False,
parse_potcar_file: bool = True,
occu_tol: float = 1e-8,
separate_spins: bool = False,
exception_on_bad_xml: bool = True,
) -> None:

The default ionic_step_skip is None, which would require all downstream methods to handle this case. Using a default int which will NOT normally happen during runtime could bypass this issue (for number of steps, -1 might be a good choice).

Some preliminary thoughts

  • For sequence types, use an empty sequence might be quite straightforward ("" for str, []/()/{} for list/tuple/dict).
  • For numbers, maybe use a number that would NOT happen during runtime (for example, -1 for number of CPU cores).

Summary

Such cases are happening everywhere across the code base (for all kinds of types) and need to insert huge amount of checks if var is None. I'm not sure how to resolve this gracefully (I cannot even describe this issue properly because it's happening everywhere and in various forms). Any suggestion would be appreciated @janosh.

@janosh
Copy link
Member

janosh commented May 6, 2024

Any suggestion would be appreciated @janosh.

definitely feel free to homogenize types where it make sense and simplifies the code. there are cases where it's important to be explicit about accepting None and handling that case separately. but if an empty string/tuple/... works for the default case, by all means use that over None

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
io Input/output functionality types Type all the things vasp Vienna Ab initio Simulation Package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants