Skip to content

Commit

Permalink
replace custom @require_keywords decorator with modern syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
a-detiste committed Nov 27, 2024
1 parent 91af03a commit a7e11f8
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 94 deletions.
8 changes: 3 additions & 5 deletions periodictable/formulas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .core import default_table, isatom, isisotope, ision, change_table
from .constants import avogadro_number
from .util import require_keywords, cell_volume
from .util import cell_volume

PACKING_FACTORS = dict(cubic=pi/6, bcc=pi*sqrt(3)/8, hcp=pi/sqrt(18),
fcc=pi/sqrt(18), diamond=pi*sqrt(3)/16)
Expand Down Expand Up @@ -518,8 +518,7 @@ def volume(self, *args, **kw):
packing_factor = PACKING_FACTORS[packing_factor.lower()]
return V/packing_factor*1e-24

@require_keywords
def neutron_sld(self, wavelength=None, energy=None):
def neutron_sld(self, *, wavelength=None, energy=None):
"""
Neutron scattering information for the molecule.
Expand All @@ -543,8 +542,7 @@ def neutron_sld(self, wavelength=None, energy=None):
return neutron_sld(self.atoms, density=self.density,
wavelength=wavelength, energy=energy)

@require_keywords
def xray_sld(self, energy=None, wavelength=None):
def xray_sld(self, *, energy=None, wavelength=None):
"""
X-ray scattering length density for the molecule.
Expand Down
11 changes: 4 additions & 7 deletions periodictable/nsf.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
from .core import Element, Isotope, default_table
from .constants import (avogadro_number, planck_constant, electron_volt,
neutron_mass, atomic_mass_constant)
from .util import require_keywords, parse_uncertainty
from .util import parse_uncertainty

__all__ = ['init', 'Neutron',
'neutron_energy', 'neutron_wavelength',
Expand Down Expand Up @@ -483,8 +483,7 @@ def scattering_by_wavelength(self, wavelength):
sigma_s = _4PI_100*abs(b_c)**2 # 1 barn = 1 fm^2 1e-2 barn/fm^2
return b_c, sigma_s

@require_keywords
def sld(self, wavelength=ABSORPTION_WAVELENGTH):
def sld(self, *, wavelength=ABSORPTION_WAVELENGTH):
r"""
Returns scattering length density for the element at natural
abundance and density.
Expand All @@ -505,8 +504,7 @@ def sld(self, wavelength=ABSORPTION_WAVELENGTH):
return None, None, None
return self.scattering(wavelength=wavelength)[0]

@require_keywords
def scattering(self, wavelength=ABSORPTION_WAVELENGTH):
def scattering(self, *, wavelength=ABSORPTION_WAVELENGTH):
r"""
Returns neutron scattering information for the element at natural
abundance and density.
Expand Down Expand Up @@ -650,8 +648,7 @@ def init(table, reload=False):
# TODO: split incoherent into spin and isotope incoherence (eq 17-19 of Sears)
# TODO: require parsed compound rather than including formula() keywords in api
# Note: docs and function prototype are reproduced in __init__
@require_keywords
def neutron_scattering(compound, density=None,
def neutron_scattering(compound, *, density=None,
wavelength=None, energy=None,
natural_density=None, table=None):
r"""
Expand Down
71 changes: 0 additions & 71 deletions periodictable/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,74 +91,3 @@ def cell_volume(a=None, b=None, c=None, alpha=None, beta=None, gamma=None):
cgamma = cos(radians(gamma)) if gamma is not None else calpha
V = a*b*c*sqrt(1 - calpha**2 - cbeta**2 - cgamma**2 + 2*calpha*cbeta*cgamma)
return V

def require_keywords(function):
r"""
Decorator which forces all keyword arguments to the function to be
explicitly named.
For example:
>>> @require_keywords
... def fn(a, b, c=3): pass
>>> fn(1, 2, 3)
Traceback (most recent call last):
...
TypeError: name=value required for c
>>> fn(1, 2, c=6)
>>> fn(b=1, a=2, c=6)
Variable arguments are not currently supported:
>>> @require_keywords
... def fn(a, b, c=6, *args, **kw): pass
Traceback (most recent call last):
...
NotImplementedError: only named arguments for now
.. Note:: The call signature is not preserved.
We can't preserve the function signature for the call since the only
way we can count the number of non-keyword arguments is to
use the \*args, \*\*kw call style. Python 3+ provides the '\*' call
signature element which will force all keywords after '\*' to be named.
"""
import functools
try:
from inspect import signature
getargspec = _getargspec_from_signature
except ImportError: # CRUFT: py 2.7 support
from inspect import getargspec

args, vararg, varkwd, defaults = getargspec(function)
if defaults is None:
defaults = []
named_args = args[:-len(defaults)]
named_kwds = args[-len(defaults):]
# Keep it simple for now
if vararg or varkwd:
raise NotImplementedError("only named arguments for now")
@functools.wraps(function)
def _require_kwds(*args, **kw):
if len(args) > len(named_args):
raise TypeError("name=value required for "+", ".join(named_kwds))
return function(*args, **kw)
return _require_kwds

def _getargspec_from_signature(function):
"""
Reproduce getargspec() interface using newer signature protocol
"""
from inspect import signature

args, vararg, varkwd, defaults = [], None, None, []
sig = signature(function)
for p in sig.parameters.values():
args.append(p.name)
if p.default is not p.empty:
defaults.append(p.default)
if p.kind is p.VAR_POSITIONAL:
vararg = p.name
elif p.kind is p.VAR_KEYWORD:
varkwd = p.name
return args, vararg, varkwd, defaults
16 changes: 5 additions & 11 deletions periodictable/xsf.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@
from .constants import (
avogadro_number, planck_constant, speed_of_light, electron_volt,
electron_radius)
from .util import require_keywords

def xray_wavelength(energy):
r"""
Expand Down Expand Up @@ -271,8 +270,7 @@ def _gettable(self):
return self._table
sftable = property(_gettable, doc="X-ray scattering factor table (E,f1,f2)")

@require_keywords
def scattering_factors(self, energy=None, wavelength=None):
def scattering_factors(self, *, energy=None, wavelength=None):
"""
X-ray scattering factors f', f''.
Expand Down Expand Up @@ -337,8 +335,7 @@ def f0(self, Q):
charge=self.element.charge)
return f

@require_keywords
def sld(self, wavelength=None, energy=None):
def sld(self, *, wavelength=None, energy=None):
r"""
X ray scattering length density.
Expand Down Expand Up @@ -382,8 +379,7 @@ def sld(self, wavelength=None, energy=None):
return rho, irho

# Note: docs and function prototype are reproduced in __init__
@require_keywords
def xray_sld(compound, density=None, natural_density=None,
def xray_sld(compound, *, density=None, natural_density=None,
wavelength=None, energy=None):
"""
Compute xray scattering length densities for molecules.
Expand Down Expand Up @@ -435,8 +431,7 @@ def xray_sld(compound, density=None, natural_density=None,
return rho, irho


@require_keywords
def index_of_refraction(compound, density=None, natural_density=None,
def index_of_refraction(compound, *, density=None, natural_density=None,
energy=None, wavelength=None):
"""
Calculates the index of refraction for a given compound
Expand Down Expand Up @@ -470,8 +465,7 @@ def index_of_refraction(compound, density=None, natural_density=None,
wavelength=wavelength)
return 1 - wavelength**2/(2*pi)*(f1 + f2*1j)*1e-6

@require_keywords
def mirror_reflectivity(compound, density=None, natural_density=None,
def mirror_reflectivity(compound, *, density=None, natural_density=None,
energy=None, wavelength=None,
angle=None, roughness=0):
"""
Expand Down

0 comments on commit a7e11f8

Please sign in to comment.