Skip to content

Commit 9640f5e

Browse files
authored
Merge pull request #109 from python-periodictable/fix-104-type-hinting
Add type hinting
2 parents 846539b + aa880dc commit 9640f5e

25 files changed

Lines changed: 1361 additions & 754 deletions

.github/workflows/test.yml

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55
branches: [ master ]
66
pull_request:
7-
branches: [ master ]
7+
# branches: [ master ]
88
release:
99
types: [published]
1010

@@ -18,11 +18,11 @@ jobs:
1818
- name: Set up Python
1919
uses: actions/setup-python@v5
2020
with:
21-
python-version: '3.11'
21+
python-version: '3.14'
2222

2323
- name: Build the wheel
2424
run: |
25-
python -m pip install build
25+
python -m pip install --group dev
2626
python -m build
2727
2828
- name: Upload wheel
@@ -33,13 +33,10 @@ jobs:
3333

3434
- name: Run the tests
3535
run: |
36-
python -m pip install numpy pyparsing pytest pytest-cov
3736
pytest -v
3837
3938
- name: Build the docs
4039
run: |
41-
python -m pip install matplotlib sphinx
42-
python -m pip install dist/periodictable*.whl
4340
make -j 4 -C doc/sphinx SPHINXOPTS="-W --keep-going" html
4441
4542
# Test the wheel on different platforms
@@ -50,12 +47,11 @@ jobs:
5047
strategy:
5148
matrix:
5249
cfg:
53-
#- { os: ubuntu-20.04, py: 2.7 }
54-
#- { os: ubuntu-20.04, py: 3.6 }
55-
- { os: ubuntu-latest, py: 3.8 }
56-
- { os: ubuntu-latest, py: 3.11, doc: 1 }
57-
- { os: windows-latest, py: 3.11 }
58-
- { os: macos-latest, py: 3.11 }
50+
#- { os: ubuntu-20.04, py: '3.6' }
51+
- { os: ubuntu-latest, py: '3.10' }
52+
- { os: ubuntu-latest, py: '3.14', doc: 1 }
53+
- { os: windows-latest, py: '3.14' }
54+
- { os: macos-latest, py: '3.14' }
5955
fail-fast: false
6056

6157
steps:
@@ -76,17 +72,22 @@ jobs:
7672
run: python -m pip install dist/periodictable*.whl
7773
shell: bash
7874

79-
- name: Install Python dependencies
75+
# uncertainties and matplotlib are optional packages, but they are needed for mypy tests
76+
- name: Install test dependencies
8077
run: |
81-
python -m pip install pytest pytest-cov
78+
python -m pip install --group test
8279
80+
# Use --pyargs --import-mode=append to target the installed package.
8381
# Change into the test directory to test the wheel so that the
84-
# source directory is not on the path. Full tests with coverage are
85-
# run before building the wheel.
82+
# source directory is not on the path. We are running coverage tests
83+
# because it shows that it is indeed the installed package that is tested.
84+
# The mypy plugin fails when testing the installed package. Since there is no
85+
# way to turn the option off, so we instead erase the addopts configuration
86+
# and put them explicitly on the pytest command line below without --mypy.
8687
- name: Test wheel with pytest
8788
run: |
8889
cd test
89-
pytest -v --pyargs --import-mode=append periodictable . ../doc/sphinx/guide
90+
pytest -v --pyargs --import-mode=append periodictable --override-ini addopts= --doctest-modules --doctest-glob=*.rst --cov=periodictable . ../doc/sphinx/guide
9091
9192
# Upload wheel to PyPI only when a tag is pushed, and its name begins with 'v'
9293
upload-to-pypi:

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include README.rst
33
graft periodictable/xsf
44
include periodictable/f0_WaasKirf.dat
55
include periodictable/activation.dat
6+
include periodictable/py.typed
67
prune doc
78
prune doc/sphinx/_build
89
prune doc/sphinx/build

doc/sphinx/conf.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@
4949
nitpick_ignore = [
5050
('py:class', 'type'),
5151
('py:class', 'object'),
52+
53+
('py:class', 'collections.abc.Callable'),
54+
('py:class', 'collections.abc.Iterator'),
55+
('py:class', 'collections.abc.Sequence'),
56+
('py:class', 'pathlib.Path'),
57+
58+
('py:class', 'numpy.dtype'),
59+
('py:class', 'numpy.ndarray'),
60+
('py:class', 'numpy.float64'),
61+
('py:class', 'numpy._typing._array_like._Buffer'),
62+
('py:class', 'numpy._typing._array_like._SupportsArray'),
63+
('py:class', 'numpy._typing._array_like._ScalarT'),
64+
('py:class', 'numpy._typing._nested_sequence._NestedSequence'),
65+
('py:class', 'pyparsing.core.ParserElement'),
66+
67+
('py:class', 'periodictable.core._AtomBase'),
68+
('py:class', 'periodictable.core.IonSet'),
69+
('py:class', 'periodictable.core.AtomVar'),
70+
('py:class', 'Fragment'),
71+
('py:class', 'FormulaInput'),
5272
]
5373

5474
# Add any paths that contain templates here, relative to this directory.

doc/sphinx/discoverer/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import periodictable.core
1+
from periodictable.core import default_table, delayed_load
22

33
# Delayed loading of the element discoverer information
44
def _load_discoverer():
55
"""
66
The name of the person or group who discovered the element.
77
"""
88
from . import discoverer
9-
discoverer.init(periodictable.core.default_table())
10-
periodictable.core.delayed_load(['discoverer'], _load_discoverer)
9+
discoverer.init(default_table())
10+
delayed_load(['discoverer'], _load_discoverer)

doc/sphinx/discoverer/discoverer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
From http://en.wikipedia.org/wiki/Discoveries_of_the_chemical_elements.
55
"""
66

7-
import periodictable.core
7+
from periodictable.core import Element
88

99
def init(table, reload=False):
1010
if 'discoverer' in table.properties and not reload: return
1111
table.properties.append('discoverer')
1212

1313
# Set the default, if any
14-
periodictable.core.Element.discoverer = "Unknown"
14+
Element.discoverer = "Unknown"
1515

1616
# Not numeric, so no discoverer_units
1717

doc/sphinx/shelltable/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import periodictable.core
1+
from periodictable.core import default_table, delayed_load
22

33
# Delayed loading of the element discoverer information
44
def _load():
55
"""
66
The name of the person or group who discovered the element.
77
"""
88
from . import shelltable
9-
shelltable.init(periodictable.core.default_table())
10-
periodictable.core.delayed_load(
9+
shelltable.init(default_table())
10+
delayed_load(
1111
['shells'], _load, isotope=True, element=False)

periodictable/__init__.py

Lines changed: 134 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from . import mass
3737
from . import density
3838

39-
_LAZY_MODULES = []
39+
_LAZY_MODULES: list[str] = []
4040
_LAZY_LOAD = {
4141
'formula': 'formulas',
4242
'mix_by_weight': 'formulas',
@@ -77,6 +77,129 @@ def __dir__():
7777
density.init(elements)
7878
del mass, density
7979

80+
# For type hinting with vscode we need an explicit list of elements.
81+
hydrogen = H = elements.symbol("H")
82+
helium = He = elements.symbol("He")
83+
lithium = Li = elements.symbol("Li")
84+
beryllium = Be = elements.symbol("Be")
85+
boron = B = elements.symbol("B")
86+
carbon = C = elements.symbol("C")
87+
nitrogen = N = elements.symbol("N")
88+
oxygen = O = elements.symbol("O")
89+
fluorine = F = elements.symbol("F")
90+
neon = Ne = elements.symbol("Ne")
91+
sodium = Na = elements.symbol("Na")
92+
magnesium = Mg = elements.symbol("Mg")
93+
aluminum = Al = elements.symbol("Al")
94+
silicon = Si = elements.symbol("Si")
95+
phosphorus = P = elements.symbol("P")
96+
sulfur = S = elements.symbol("S")
97+
chlorine = Cl = elements.symbol("Cl")
98+
argon = Ar = elements.symbol("Ar")
99+
potassium = K = elements.symbol("K")
100+
calcium = Ca = elements.symbol("Ca")
101+
scandium = Sc = elements.symbol("Sc")
102+
titanium = Ti = elements.symbol("Ti")
103+
vanadium = V = elements.symbol("V")
104+
chromium = Cr = elements.symbol("Cr")
105+
manganese = Mn = elements.symbol("Mn")
106+
iron = Fe = elements.symbol("Fe")
107+
cobalt = Co = elements.symbol("Co")
108+
nickel = Ni = elements.symbol("Ni")
109+
copper = Cu = elements.symbol("Cu")
110+
zinc = Zn = elements.symbol("Zn")
111+
gallium = Ga = elements.symbol("Ga")
112+
germanium = Ge = elements.symbol("Ge")
113+
arsenic = As = elements.symbol("As")
114+
selenium = Se = elements.symbol("Se")
115+
bromine = Br = elements.symbol("Br")
116+
krypton = Kr = elements.symbol("Kr")
117+
rubidium = Rb = elements.symbol("Rb")
118+
strontium = Sr = elements.symbol("Sr")
119+
yttrium = Y = elements.symbol("Y")
120+
zirconium = Zr = elements.symbol("Zr")
121+
niobium = Nb = elements.symbol("Nb")
122+
molybdenum = Mo = elements.symbol("Mo")
123+
technetium = Tc = elements.symbol("Tc")
124+
ruthenium = Ru = elements.symbol("Ru")
125+
rhodium = Rh = elements.symbol("Rh")
126+
palladium = Pd = elements.symbol("Pd")
127+
silver = Ag = elements.symbol("Ag")
128+
cadmium = Cd = elements.symbol("Cd")
129+
indium = In = elements.symbol("In")
130+
tin = Sn = elements.symbol("Sn")
131+
antimony = Sb = elements.symbol("Sb")
132+
tellurium = Te = elements.symbol("Te")
133+
iodine = I = elements.symbol("I")
134+
xenon = Xe = elements.symbol("Xe")
135+
cesium = Cs = elements.symbol("Cs")
136+
barium = Ba = elements.symbol("Ba")
137+
lanthanum = La = elements.symbol("La")
138+
cerium = Ce = elements.symbol("Ce")
139+
praseodymium = Pr = elements.symbol("Pr")
140+
neodymium = Nd = elements.symbol("Nd")
141+
promethium = Pm = elements.symbol("Pm")
142+
samarium = Sm = elements.symbol("Sm")
143+
europium = Eu = elements.symbol("Eu")
144+
gadolinium = Gd = elements.symbol("Gd")
145+
terbium = Tb = elements.symbol("Tb")
146+
dysprosium = Dy = elements.symbol("Dy")
147+
holmium = Ho = elements.symbol("Ho")
148+
erbium = Er = elements.symbol("Er")
149+
thulium = Tm = elements.symbol("Tm")
150+
ytterbium = Yb = elements.symbol("Yb")
151+
lutetium = Lu = elements.symbol("Lu")
152+
hafnium = Hf = elements.symbol("Hf")
153+
tantalum = Ta = elements.symbol("Ta")
154+
tungsten = W = elements.symbol("W")
155+
rhenium = Re = elements.symbol("Re")
156+
osmium = Os = elements.symbol("Os")
157+
iridium = Ir = elements.symbol("Ir")
158+
platinum = Pt = elements.symbol("Pt")
159+
gold = Au = elements.symbol("Au")
160+
mercury = Hg = elements.symbol("Hg")
161+
thallium = Tl = elements.symbol("Tl")
162+
lead = Pb = elements.symbol("Pb")
163+
bismuth = Bi = elements.symbol("Bi")
164+
polonium = Po = elements.symbol("Po")
165+
astatine = At = elements.symbol("At")
166+
radon = Rn = elements.symbol("Rn")
167+
francium = Fr = elements.symbol("Fr")
168+
radium = Ra = elements.symbol("Ra")
169+
actinium = Ac = elements.symbol("Ac")
170+
thorium = Th = elements.symbol("Th")
171+
protactinium = Pa = elements.symbol("Pa")
172+
uranium = U = elements.symbol("U")
173+
neptunium = Np = elements.symbol("Np")
174+
plutonium = Pu = elements.symbol("Pu")
175+
americium = Am = elements.symbol("Am")
176+
curium = Cm = elements.symbol("Cm")
177+
berkelium = Bk = elements.symbol("Bk")
178+
californium = Cf = elements.symbol("Cf")
179+
einsteinium = Es = elements.symbol("Es")
180+
fermium = Fm = elements.symbol("Fm")
181+
mendelevium = Md = elements.symbol("Md")
182+
nobelium = No = elements.symbol("No")
183+
lawrencium = Lr = elements.symbol("Lr")
184+
rutherfordium = Rf = elements.symbol("Rf")
185+
dubnium = Db = elements.symbol("Db")
186+
seaborgium = Sg = elements.symbol("Sg")
187+
bohrium = Bh = elements.symbol("Bh")
188+
hassium = Hs = elements.symbol("Hs")
189+
meitnerium = Mt = elements.symbol("Mt")
190+
darmstadtium = Ds = elements.symbol("Ds")
191+
roentgenium = Rg = elements.symbol("Rg")
192+
copernicium = Cn = elements.symbol("Cn")
193+
nihonium = Nh = elements.symbol("Nh")
194+
flerovium = Fl = elements.symbol("Fl")
195+
moscovium = Mc = elements.symbol("Mc")
196+
livermorium = Lv = elements.symbol("Lv")
197+
tennessine = Ts = elements.symbol("Ts")
198+
oganesson = Og = elements.symbol("Og")
199+
deuterium = D = elements.symbol("D")
200+
tritium = T = elements.symbol("T")
201+
neutron = n = elements.symbol("n")
202+
80203
# Add element name and symbol (e.g. nickel and Ni) to the public attributes.
81204
__all__ += core.define_elements(elements, globals())
82205

@@ -91,6 +214,7 @@ def _load_covalent_radius():
91214
'covalent_radius_units',
92215
'covalent_radius_uncertainty'],
93216
_load_covalent_radius)
217+
del _load_covalent_radius
94218

95219
def _load_crystal_structure():
96220
"""
@@ -102,6 +226,7 @@ def _load_crystal_structure():
102226
from . import crystal_structure
103227
crystal_structure.init(elements)
104228
core.delayed_load(['crystal_structure'], _load_crystal_structure)
229+
del _load_crystal_structure
105230

106231
def _load_neutron():
107232
"""
@@ -114,6 +239,7 @@ def _load_neutron():
114239
from . import nsf
115240
nsf.init(elements)
116241
core.delayed_load(['neutron'], _load_neutron, isotope=True)
242+
del _load_neutron
117243

118244
def _load_neutron_activation():
119245
"""
@@ -127,6 +253,7 @@ def _load_neutron_activation():
127253
activation.init(elements)
128254
core.delayed_load(['neutron_activation'], _load_neutron_activation,
129255
element=False, isotope=True)
256+
del _load_neutron_activation
130257

131258
def _load_xray():
132259
"""
@@ -138,6 +265,7 @@ def _load_xray():
138265
from . import xsf
139266
xsf.init(elements)
140267
core.delayed_load(['xray'], _load_xray, ion=True)
268+
del _load_xray
141269

142270
def _load_emission_lines():
143271
"""
@@ -149,6 +277,7 @@ def _load_emission_lines():
149277
xsf.init_spectral_lines(elements)
150278
core.delayed_load(['K_alpha', 'K_beta1', 'K_alpha_units', 'K_beta1_units'],
151279
_load_emission_lines)
280+
del _load_emission_lines
152281

153282
def _load_magnetic_ff():
154283
"""
@@ -161,6 +290,7 @@ def _load_magnetic_ff():
161290
from . import magnetic_ff
162291
magnetic_ff.init(elements)
163292
core.delayed_load(['magnetic_ff'], _load_magnetic_ff)
293+
del _load_magnetic_ff
164294

165295

166296
# Data needed for setup.py when bundling the package into an exe
@@ -173,9 +303,11 @@ def data_files():
173303
"""
174304
import os
175305
import glob
306+
from .core import get_data_path
307+
176308
def _finddata(ext, patterns):
177309
files = []
178-
path = core.get_data_path(ext)
310+
path = get_data_path(ext)
179311
for p in patterns:
180312
files += glob.glob(os.path.join(path, p))
181313
return files

0 commit comments

Comments
 (0)