Skip to content

Commit dd4da5f

Browse files
authored
Add orjson as required dependency as default JSON handler when custom encoder/decoder is not needed (#4411)
* clean up pyproject * try to remove pybtex warning * sort optional dependencies * allow pyproject change to trigger test * also include workflow and setup in test workflow trigger * add orjson as dependency * replace json.dumps * replace json.loads * fix phonondos numpy handling * remove indent and see how many test will break * replace json.load * fix JSON str whitespace sensitivity * replace json.dump * fix os.path.exists * replace str | PathLike * use pmg typealias pathlike * clean up import * minor clean up of module docstring
1 parent 57d7f57 commit dd4da5f

File tree

80 files changed

+400
-427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+400
-427
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ name: test
55
on:
66
push:
77
branches: [master]
8-
paths: ["src/**/*.*", "tests/**/*.*"]
8+
paths: ["src/**/*.*", "tests/**/*.*", ".github/workflows/*" ,"pyproject.toml", "setup.py"]
99
pull_request:
1010
branches: [master]
11-
paths: ["src/**/*.*", "tests/**/*.*"]
11+
paths: ["src/**/*.*", "tests/**/*.*", ".github/workflows/*", "pyproject.toml", "setup.py" ]
1212
workflow_dispatch:
1313
workflow_call: # make this workflow reusable by release.yml
1414

dev_scripts/chemenv/strategies/multi_weights_strategy_parameters.py

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

55
import copy
6-
import json
76
from typing import TYPE_CHECKING
87

98
import matplotlib.pyplot as plt
109
import numpy as np
10+
import orjson
1111

1212
from pymatgen.analysis.chemenv.coordination_environments.chemenv_strategies import (
1313
AngleNbSetWeight,
@@ -299,8 +299,8 @@ def get_weights(self, weights_options):
299299
"+-------------------------------------------------------------+\n"
300300
)
301301

302-
with open("ce_pairs.json", encoding="utf-8") as file:
303-
ce_pairs = json.load(file)
302+
with open("ce_pairs.json", "rb") as file:
303+
ce_pairs = orjson.loads(file.read())
304304
self_weight_max_csms: dict[str, list[float]] = {}
305305
self_weight_max_csms_per_cn: dict[str, list[float]] = {}
306306
all_self_max_csms = []

docs/usage.md

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,18 @@ classifiers = [
5555
"Topic :: Software Development :: Libraries :: Python Modules",
5656
]
5757
dependencies = [
58+
"bibtexparser>=1.4.0",
5859
"joblib>=1",
5960
"matplotlib>=3.8",
6061
"monty>=2025.1.9",
6162
"networkx>=2.7", # PR4116
63+
# NumPy documentation suggests pinning the current major version as the C API is used
64+
# https://numpy.org/devdocs/dev/depending_on_numpy.html#runtime-dependency-version-ranges
65+
"numpy>=1.25.0,<3",
66+
"orjson>=3.10,<4",
6267
"palettable>=3.3.3",
6368
"pandas>=2",
6469
"plotly>=5.0.0",
65-
"bibtexparser>=1.4.0",
6670
"requests>=2.32",
6771
"ruamel.yaml>=0.17.0",
6872
"scipy>=1.13.0",
@@ -74,9 +78,6 @@ dependencies = [
7478
"tabulate>=0.9",
7579
"tqdm>=4.60",
7680
"uncertainties>=3.1.4",
77-
# NumPy documentation suggests pinning the current major version as the C API is used
78-
# https://numpy.org/devdocs/dev/depending_on_numpy.html#runtime-dependency-version-ranges
79-
"numpy>=1.25.0,<3",
8081
]
8182
version = "2025.5.2"
8283

@@ -90,11 +91,19 @@ Pypi = "https://pypi.org/project/pymatgen"
9091
[project.optional-dependencies]
9192
abinit = ["netcdf4>=1.7.2"]
9293
ase = ["ase>=3.23.0"]
94+
ci = [
95+
"pytest>=8.3.5",
96+
"pytest-cov>=6.0.0",
97+
"pytest-split>=0.10.0",
98+
]
9399
electronic_structure = ["fdint>=2.0.2"]
100+
matcalc = [
101+
"matcalc>=0.4.0; python_version<'3.13'",
102+
"matgl>=1.2.7; python_version<'3.13'",
103+
]
94104
mlp = ["matgl>=1.2.7 ; python_version<'3.13'"]
95105
numba = ["numba>=0.55"]
96106
numpy-v1 = ["numpy>=1.25.0,<2"] # Test NP1 on Windows (quite buggy ATM)
97-
zeopp = ["pyzeo"] # Note: requires voro++ and zeo++ to be installed
98107
optional = [
99108
"pymatgen[abinit,ase,mlp,tblite,matcalc]",
100109
"beautifulsoup4",
@@ -106,7 +115,6 @@ optional = [
106115
"h5py>=3.11.0",
107116
"hiphive>=1.3.1",
108117
"jarvis-tools>=2020.7.14",
109-
"matplotlib>=3.8",
110118
"phonopy>=2.33.3",
111119
"seekpath>=2.0.1",
112120
]
@@ -117,15 +125,7 @@ symmetry = ["moyopy[interface]>=0.3", "spglib>=2.5"]
117125
# https://github.com/tblite/tblite/issues/175
118126
tblite = ["tblite[ase]>=0.3.0; platform_system=='Linux' and python_version<'3.12'"]
119127
vis = ["vtk>=6.0.0"]
120-
ci = [
121-
"pytest>=8.3.5",
122-
"pytest-cov>=6.0.0",
123-
"pytest-split>=0.10.0",
124-
]
125-
matcalc = [
126-
"matcalc>=0.4.0; python_version<'3.13'",
127-
"matgl>=1.2.7; python_version<'3.13'",
128-
]
128+
zeopp = ["pyzeo"] # Note: requires Voro++ and Zeo++ to be installed
129129

130130
[project.scripts]
131131
pmg = "pymatgen.cli.pmg:main"
@@ -264,14 +264,8 @@ addopts = "--durations=30 --quiet -r xXs --color=yes --import-mode=importlib"
264264
filterwarnings = [
265265
# NOTE: the LAST matching option would be used
266266
"ignore::UserWarning", # Ignore UserWarning
267-
"error:We strongly encourage explicit `encoding`:EncodingWarning", # Mark `zopen` EncodingWarning as error
268-
"error:We strongly discourage using implicit binary/text:FutureWarning", # Mark `zopen` FutureWarning as error
269-
# TODO: remove the following filter once `monty.io` dropped custom EncodingWarning
267+
# TODO: remove the following filter once `monty.io` dropped custom EncodingWarning (python 3.10+ only)
270268
"error:We strongly encourage explicit `encoding`:monty.io.EncodingWarning",
271-
# TODO: pybtex (perhaps some others) emits the following warnings
272-
'ignore:pkg_resources is deprecated as an API:DeprecationWarning',
273-
'ignore:distutils Version classes are deprecated:DeprecationWarning',
274-
'ignore:Deprecated call to `pkg_resources.declare_namespace:DeprecationWarning',
275269
]
276270

277271
[tool.coverage.run]

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ numpy==2.0.0
3535
# pandas
3636
# scipy
3737
# spglib
38+
orjson==3.10.18
39+
# via pymatgen (pyproject.toml)
3840
packaging==24.2
3941
# via
4042
# matplotlib

src/pymatgen/alchemy/materials.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from typing import TYPE_CHECKING
1212
from warnings import warn
1313

14+
import orjson
1415
from monty.json import MSONable, jsanitize
1516

1617
from pymatgen.core.structure import Structure
@@ -193,7 +194,7 @@ def get_vasp_input(self, vasp_input_set: type[VaspInputSet] = MPRelaxSet, **kwar
193194
**kwargs: All keyword args supported by the VASP input set.
194195
"""
195196
dct = vasp_input_set(self.final_structure, **kwargs).get_input_set()
196-
dct["transformations.json"] = json.dumps(self.as_dict())
197+
dct["transformations.json"] = orjson.dumps(self.as_dict()).decode()
197198
return dct
198199

199200
def write_vasp_input(

src/pymatgen/analysis/chemenv/coordination_environments/coordination_geometries.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
import abc
1313
import itertools
14-
import json
1514
import os
1615
from typing import TYPE_CHECKING
1716

1817
import numpy as np
18+
import orjson
1919
from monty.json import MontyDecoder, MSONable
2020
from scipy.special import factorial
2121

@@ -865,15 +865,15 @@ def __init__(self, permutations_safe_override=False, only_symbols=None):
865865
data = file.readlines()
866866
for line in data:
867867
cg_file = f"{MODULE_DIR}/{line.strip()}"
868-
with open(cg_file, encoding="utf-8") as file:
869-
dd = json.load(file)
868+
with open(cg_file, "rb") as file:
869+
dd = orjson.loads(file.read())
870870
self.cg_list.append(CoordinationGeometry.from_dict(dd))
871871
else:
872872
for symbol in only_symbols:
873873
fsymbol = symbol.replace(":", "#")
874874
cg_file = f"{MODULE_DIR}/coordination_geometries_files/{fsymbol}.json"
875-
with open(cg_file, encoding="utf-8") as file:
876-
dd = json.load(file)
875+
with open(cg_file, "rb") as file:
876+
dd = orjson.loads(file.read())
877877
self.cg_list.append(CoordinationGeometry.from_dict(dd))
878878

879879
self.cg_list.append(CoordinationGeometry(UNKNOWN_ENVIRONMENT_SYMBOL, "Unknown environment", deactivate=True))

src/pymatgen/analysis/chemenv/utils/chemenv_config.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
from __future__ import annotations
44

5-
import json
6-
from os import makedirs
7-
from os.path import exists, expanduser
5+
import os
86
from typing import TYPE_CHECKING
97

8+
import orjson
9+
1010
from pymatgen.analysis.chemenv.utils.scripts_utils import strategies_class_lookup
1111
from pymatgen.core import SETTINGS
1212

@@ -142,19 +142,19 @@ def save(self, root_dir=None):
142142
root_dir:
143143
"""
144144
if root_dir is None:
145-
home = expanduser("~")
145+
home = os.expanduser("~")
146146
root_dir = f"{home}/.chemenv"
147-
if not exists(root_dir):
148-
makedirs(root_dir)
147+
if not os.path.exists(root_dir):
148+
os.makedirs(root_dir)
149149
config_dict = {"package_options": self.package_options}
150150
config_file = f"{root_dir}/config.json"
151-
if exists(config_file):
151+
if os.path.exists(config_file):
152152
test = input("Overwrite existing configuration ? (<Y> + <ENTER> to confirm)")
153153
if test != "Y":
154154
print("Configuration not saved")
155155
return config_file
156-
with open(config_file, mode="w", encoding="utf-8") as file:
157-
json.dump(config_dict, file)
156+
with open(config_file, "wb") as file:
157+
file.write(orjson.dumps(config_dict))
158158
print("Configuration saved")
159159
return config_file
160160

@@ -167,12 +167,12 @@ def auto_load(cls, root_dir=None):
167167
root_dir:
168168
"""
169169
if root_dir is None:
170-
home = expanduser("~")
170+
home = os.expanduser("~")
171171
root_dir = f"{home}/.chemenv"
172172
config_file = f"{root_dir}/config.json"
173173
try:
174-
with open(config_file, encoding="utf-8") as file:
175-
config_dict = json.load(file)
174+
with open(config_file, "rb") as file:
175+
config_dict = orjson.loads(file.read())
176176
return ChemEnvConfig(package_options=config_dict["package_options"])
177177

178178
except OSError:

src/pymatgen/analysis/chempot_diagram.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222

2323
from __future__ import annotations
2424

25-
import json
2625
import warnings
2726
from functools import lru_cache
2827
from itertools import groupby
2928
from typing import TYPE_CHECKING
3029

3130
import numpy as np
31+
import orjson
3232
import plotly.express as px
3333
from monty.json import MSONable
3434
from plotly.graph_objects import Figure, Mesh3d, Scatter, Scatter3d
@@ -44,8 +44,8 @@
4444
if TYPE_CHECKING:
4545
from pymatgen.entries.computed_entries import ComputedEntry
4646

47-
with open(f"{PKG_DIR}/util/plotly_chempot_layouts.json", encoding="utf-8") as file:
48-
plotly_layouts = json.load(file)
47+
with open(f"{PKG_DIR}/util/plotly_chempot_layouts.json", "rb") as file:
48+
plotly_layouts = orjson.loads(file.read())
4949

5050

5151
@due.dcite(

src/pymatgen/analysis/diffraction/neutron.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
from __future__ import annotations
44

5-
import json
65
import math
76
import os
87
from typing import TYPE_CHECKING
98

109
import numpy as np
10+
import orjson
1111

1212
from pymatgen.analysis.diffraction.core import (
1313
AbstractDiffractionPatternCalculator,
@@ -29,9 +29,9 @@
2929
# This table was cited from "Neutron Data Booklet" 2nd ed (Old City 2003).
3030
with open(
3131
os.path.join(os.path.dirname(__file__), "neutron_scattering_length.json"),
32-
encoding="utf-8",
32+
"rb",
3333
) as file:
34-
ATOMIC_SCATTERING_LEN = json.load(file)
34+
ATOMIC_SCATTERING_LEN = orjson.loads(file.read())
3535

3636

3737
class NDCalculator(AbstractDiffractionPatternCalculator):

src/pymatgen/analysis/diffraction/tem.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
from __future__ import annotations
44

5-
import json
65
import os
76
from fractions import Fraction
87
from typing import TYPE_CHECKING, NamedTuple, cast
98

109
import numpy as np
10+
import orjson
1111
import pandas as pd
1212
import plotly.graph_objects as go
1313
import scipy.constants as sc
@@ -30,8 +30,8 @@
3030

3131

3232
MODULE_DIR = os.path.dirname(__file__)
33-
with open(f"{MODULE_DIR}/atomic_scattering_params.json", encoding="utf-8") as file:
34-
ATOMIC_SCATTERING_PARAMS = json.load(file)
33+
with open(f"{MODULE_DIR}/atomic_scattering_params.json", "rb") as file:
34+
ATOMIC_SCATTERING_PARAMS = orjson.loads(file.read())
3535

3636

3737
class TEMCalculator(AbstractDiffractionPatternCalculator):

src/pymatgen/analysis/diffraction/xrd.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
from __future__ import annotations
44

5-
import json
65
import math
76
import os
87
from typing import TYPE_CHECKING
98

109
import numpy as np
10+
import orjson
1111

1212
from pymatgen.analysis.diffraction.core import (
1313
AbstractDiffractionPatternCalculator,
@@ -49,9 +49,9 @@
4949

5050
with open(
5151
os.path.join(os.path.dirname(__file__), "atomic_scattering_params.json"),
52-
encoding="utf-8",
52+
"rb",
5353
) as file:
54-
ATOMIC_SCATTERING_PARAMS = json.load(file)
54+
ATOMIC_SCATTERING_PARAMS = orjson.loads(file.read())
5555

5656

5757
class XRDCalculator(AbstractDiffractionPatternCalculator):

src/pymatgen/analysis/interface_reactions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
from __future__ import annotations
77

8-
import json
98
import warnings
109
from typing import TYPE_CHECKING
1110

1211
import matplotlib.pyplot as plt
1312
import numpy as np
13+
import orjson
1414
from monty.json import MSONable
1515
from pandas import DataFrame
1616
from plotly.graph_objects import Figure, Scatter
@@ -31,8 +31,8 @@
3131
__email__ = "mcdermott@lbl.gov"
3232
__date__ = "Sep 1, 2021"
3333

34-
with open(f"{PKG_DIR}/util/plotly_interface_rxn_layouts.json", encoding="utf-8") as file:
35-
plotly_layouts = json.load(file)
34+
with open(f"{PKG_DIR}/util/plotly_interface_rxn_layouts.json", "rb") as file:
35+
plotly_layouts = orjson.loads(file.read())
3636

3737

3838
@due.dcite(

0 commit comments

Comments
 (0)