Repository: PlasmaPy/PlasmaPy
Pull request #1064 (2021-03-12 00:50:22)

Minor docstring fixes in particles
Here are a bunch of more docstring fixes using my new favorite programming paradigm of PDD.¹  This time these are for `plasmapy.particles`, and were primarily inspired by running `pydocstyle`.  If this looks good, I'm okay with it being merged.

I also renamed two private dictionaries to be more PEP8ish: `_Elements` to `_elements` and `_Isotopes` to `_isotopes` (since these aren't classes).  

¹Procrastination-driven development.

codecov[bot]: # [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=h1) Report
> Merging [#1064](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=desc) (9699b31) into [master](https://codecov.io/gh/PlasmaPy/PlasmaPy/commit/7fe327064b755fbcb3e8b2665c9d3ae54c3075e4?el=desc) (7fe3270) will **decrease** coverage by `0.59%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/graphs/tree.svg?width=650&height=150&src=pr&token=LzZ5mnXVad)](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1064      +/-   ##
==========================================
- Coverage   96.89%   96.30%   -0.60%     
==========================================
  Files          70       70              
  Lines        6921     6921              
==========================================
- Hits         6706     6665      -41     
- Misses        215      256      +41     
```


| [Impacted Files](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [plasmapy/particles/exceptions.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2V4Y2VwdGlvbnMucHk=) | `100.00% <ø> (ø)` | |
| [plasmapy/particles/ionization\_state.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2lvbml6YXRpb25fc3RhdGUucHk=) | `93.52% <ø> (ø)` | |
| [plasmapy/particles/ionization\_state\_collection.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2lvbml6YXRpb25fc3RhdGVfY29sbGVjdGlvbi5weQ==) | `91.10% <ø> (ø)` | |
| [plasmapy/particles/nuclear.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL251Y2xlYXIucHk=) | `100.00% <ø> (ø)` | |
| [plasmapy/particles/particle\_collections.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL3BhcnRpY2xlX2NvbGxlY3Rpb25zLnB5) | `99.02% <ø> (ø)` | |
| [plasmapy/particles/serialization.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL3NlcmlhbGl6YXRpb24ucHk=) | `100.00% <ø> (ø)` | |
| [plasmapy/particles/atomic.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2F0b21pYy5weQ==) | `100.00% <100.00%> (ø)` | |
| [plasmapy/particles/elements.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2VsZW1lbnRzLnB5) | `100.00% <100.00%> (ø)` | |
| [plasmapy/particles/isotopes.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL2lzb3RvcGVzLnB5) | `100.00% <100.00%> (ø)` | |
| [plasmapy/particles/parsing.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree#diff-cGxhc21hcHkvcGFydGljbGVzL3BhcnNpbmcucHk=) | `100.00% <100.00%> (ø)` | |
| ... and [3 more](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=footer). Last update [7fe3270...9699b31](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1064?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

namurphy: > I have mixed feelings about whatever docstyle directive adds "returns..." to properties.

Yeah...I had mixed thoughts about that too.  It's a good practice for functions and methods, I think, but not as well suited to properties.  I'll undo those particular changes, and then we could merge this.

Patch:
diff --git a/changelog/1064.doc.rst b/changelog/1064.doc.rst
new file mode 100644
index 00000000..d5c3a83e
--- /dev/null
+++ b/changelog/1064.doc.rst
@@ -0,0 +1,1 @@
+Make minor fixes in `plasmapy.particles` docstrings.
diff --git a/plasmapy/particles/atomic.py b/plasmapy/particles/atomic.py
index d9932de4..b6ac3355 100644
--- a/plasmapy/particles/atomic.py
+++ b/plasmapy/particles/atomic.py
@@ -27,14 +27,14 @@
 from typing import Any, List, Optional, Union
 
 from plasmapy.particles.decorators import particle_input
-from plasmapy.particles.elements import _Elements
+from plasmapy.particles.elements import _elements
 from plasmapy.particles.exceptions import (
     InvalidElementError,
     InvalidIsotopeError,
     InvalidParticleError,
     MissingParticleDataError,
 )
-from plasmapy.particles.isotopes import _Isotopes
+from plasmapy.particles.isotopes import _isotopes
 from plasmapy.particles.particle_class import Particle
 from plasmapy.particles.symbols import atomic_symbol
 
@@ -573,7 +573,7 @@ def known_isotopes(argument: Union[str, Integral] = None) -> List[str]:
     def known_isotopes_for_element(argument):
         element = atomic_symbol(argument)
         isotopes = []
-        for isotope in _Isotopes.keys():
+        for isotope in _isotopes.keys():
             if element + "-" in isotope and isotope[0 : len(element)] == element:
                 isotopes.append(isotope)
         if element == "H":
@@ -599,7 +599,7 @@ def known_isotopes_for_element(argument):
             raise InvalidParticleError("Invalid particle in known_isotopes.")
     elif argument is None:
         isotopes_list = []
-        for atomic_numb in range(1, len(_Elements.keys()) + 1):
+        for atomic_numb in range(1, len(_elements.keys()) + 1):
             isotopes_list += known_isotopes_for_element(atomic_numb)
 
     return isotopes_list
@@ -683,11 +683,11 @@ def common_isotopes_for_element(
         isotopes = known_isotopes(argument)
 
         CommonIsotopes = [
-            isotope for isotope in isotopes if "abundance" in _Isotopes[isotope].keys()
+            isotope for isotope in isotopes if "abundance" in _isotopes[isotope].keys()
         ]
 
         isotopic_abundances = [
-            _Isotopes[isotope]["abundance"] for isotope in CommonIsotopes
+            _isotopes[isotope]["abundance"] for isotope in CommonIsotopes
         ]
 
         sorted_isotopes = [
@@ -801,7 +801,7 @@ def stable_isotopes_for_element(
         StableIsotopes = [
             isotope
             for isotope in KnownIsotopes
-            if _Isotopes[isotope]["stable"] == stable_only
+            if _isotopes[isotope]["stable"] == stable_only
         ]
         return StableIsotopes
 
@@ -945,7 +945,7 @@ def periodic_table_period(argument: Union[str, Integral]) -> Integral:
             "integer representing its atomic number."
         )
     symbol = atomic_symbol(argument)
-    period = _Elements[symbol]["period"]
+    period = _elements[symbol]["period"]
     return period
 
 
@@ -999,7 +999,7 @@ def periodic_table_group(argument: Union[str, Integral]) -> Integral:
             "symbol, or an integer representing its atomic number."
         )
     symbol = atomic_symbol(argument)
-    group = _Elements[symbol]["group"]
+    group = _elements[symbol]["group"]
     return group
 
 
@@ -1053,7 +1053,7 @@ def periodic_table_block(argument: Union[str, Integral]) -> str:
             "symbol, or an integer representing its atomic number."
         )
     symbol = atomic_symbol(argument)
-    block = _Elements[symbol]["block"]
+    block = _elements[symbol]["block"]
     return block
 
 
@@ -1105,7 +1105,7 @@ def periodic_table_category(argument: Union[str, Integral]) -> str:
             "symbol, or an integer representing its atomic number."
         )
     symbol = atomic_symbol(argument)
-    category = _Elements[symbol]["category"]
+    category = _elements[symbol]["category"]
     return category
 
 
diff --git a/plasmapy/particles/elements.py b/plasmapy/particles/elements.py
index b4f7d6d2..de9ca473 100644
--- a/plasmapy/particles/elements.py
+++ b/plasmapy/particles/elements.py
@@ -5,8 +5,7 @@
 The periodic tabla data is from: http://periodic.lanl.gov/index.shtml
 
 .. attention::
-    This module only contains non-public functionality.  To learn more about the
-    package functionality, examine the code itself.
+    This module is not part of PlasmaPy's public API.
 """
 __all__ = []
 
@@ -41,16 +40,16 @@ def _element_obj_hook(obj):
 #    json.dump(_Elements, f, default=plasma_default, indent=2)
 
 
-_Elements = json.loads(
+_elements = json.loads(
     pkgutil.get_data("plasmapy", "particles/data/elements.json"),
     object_hook=_element_obj_hook,
 )
 
 
 _atomic_numbers_to_symbols = {
-    elemdict["atomic number"]: symb for (symb, elemdict) in _Elements.items()
+    elemdict["atomic number"]: symb for (symb, elemdict) in _elements.items()
 }
 
 _element_names_to_symbols = {
-    elemdict["element name"]: symb for (symb, elemdict) in _Elements.items()
+    elemdict["element name"]: symb for (symb, elemdict) in _elements.items()
 }
diff --git a/plasmapy/particles/exceptions.py b/plasmapy/particles/exceptions.py
index 2ec7528f..56acbe4a 100644
--- a/plasmapy/particles/exceptions.py
+++ b/plasmapy/particles/exceptions.py
@@ -1,6 +1,5 @@
-"""
-Collection of exceptions and warnings for `plasmapy.particles`.
-"""
+"""Collection of exceptions and warnings for `plasmapy.particles`."""
+
 __all__ = [
     "ParticleError",
     "ParticleWarning",
diff --git a/plasmapy/particles/ionization_state_collection.py b/plasmapy/particles/ionization_state_collection.py
index c374d423..cbcb634a 100644
--- a/plasmapy/particles/ionization_state_collection.py
+++ b/plasmapy/particles/ionization_state_collection.py
@@ -410,7 +410,6 @@ def ionic_fractions(self) -> Dict[str, np.array]:
         isotope.  The values will be `~numpy.ndarray` objects containing
         the ionic fractions for each ionization level corresponding to
         each element or isotope.
-
         """
         return self._ionic_fractions
 
@@ -773,9 +772,7 @@ def log_abundances(self) -> Dict[str, Real]:
 
     @log_abundances.setter
     def log_abundances(self, value: Optional[Dict[str, Real]]):
-        """
-        Set the base 10 logarithm of the relative abundances.
-        """
+        """Set the base 10 logarithm of the relative abundances."""
         if value is not None:
             try:
                 new_abundances_input = {}
@@ -849,9 +846,7 @@ def tol(self) -> np.real:
 
     @tol.setter
     def tol(self, atol: Real):
-        """
-        Set the absolute tolerance for comparisons.
-        """
+        """Set the absolute tolerance for comparisons."""
         if not isinstance(atol, Real):
             raise TypeError("The attribute tol must be a real number.")
         if 0 <= atol <= 1.0:
diff --git a/plasmapy/particles/isotopes.py b/plasmapy/particles/isotopes.py
index 681620d5..39aa8dc8 100644
--- a/plasmapy/particles/isotopes.py
+++ b/plasmapy/particles/isotopes.py
@@ -2,8 +2,7 @@
 Module for loading isotope data from :file:`plasmapy/particles/data/isotopes.json`.
 
 .. attention::
-    This module only contains non-public functionality.  To learn more about the
-    package functionality, then examine the code itself.
+    This module is not part of PlasmaPy's public API.
 """
 __all__ = []
 
@@ -26,14 +25,14 @@
 
 
 def _isotope_obj_hook(obj):
-    """An `object_hook` designed for `json.load` and `json.loads`."""
+    """Provide an `object_hook` designed for `json.load` and `json.loads`."""
     if "unit" in obj:
         return obj["value"] * u.Unit(obj["unit"])
     return obj
 
 
 #: Dictionary of isotope data.
-_Isotopes = json.loads(
+_isotopes = json.loads(
     pkgutil.get_data("plasmapy", "particles/data/isotopes.json"),
     object_hook=_isotope_obj_hook,
 )
diff --git a/plasmapy/particles/nuclear.py b/plasmapy/particles/nuclear.py
index d98bfac4..013bd79b 100644
--- a/plasmapy/particles/nuclear.py
+++ b/plasmapy/particles/nuclear.py
@@ -91,7 +91,8 @@ def mass_energy(particle: Particle, mass_numb: Optional[int] = None) -> u.Quanti
     Returns
     -------
     mass_energy: `~astropy.units.Quantity`
-        The mass energy of the particle (or in the case of ) in units of joules.
+        The mass energy of the particle (or, in the case of an isotope,
+        its nuclide) in units of joules.
 
     Raises
     ------
@@ -106,7 +107,6 @@ def mass_energy(particle: Particle, mass_numb: Optional[int] = None) -> u.Quanti
 
     Examples
     --------
-
     >>> mass_energy('He-4')
     <Quantity 5.9719e-10 J>
     """
diff --git a/plasmapy/particles/parsing.py b/plasmapy/particles/parsing.py
index 46de6f5f..7128f717 100644
--- a/plasmapy/particles/parsing.py
+++ b/plasmapy/particles/parsing.py
@@ -2,8 +2,8 @@
 Functionality to parse representations of particles into standard form.
 
 .. attention::
-    This module only contains non-public functionality.  To learn more about the
-    package functionality, examine the code itself.
+    This module is not part of PlasmaPy's public API.
+
 """
 __all__ = []
 
@@ -17,14 +17,14 @@
 from plasmapy.particles.elements import (
     _atomic_numbers_to_symbols,
     _element_names_to_symbols,
-    _Elements,
+    _elements,
 )
 from plasmapy.particles.exceptions import (
     InvalidElementError,
     InvalidParticleError,
     ParticleWarning,
 )
-from plasmapy.particles.isotopes import _Isotopes
+from plasmapy.particles.isotopes import _isotopes
 from plasmapy.particles.special_particles import _Particles, ParticleZoo
 from plasmapy.utils import roman
 
@@ -338,7 +338,7 @@ def _reconstruct_isotope_symbol(element: str, mass_numb: Integral) -> str:
             elif isotope == "H-3":
                 isotope = "T"
 
-            if isotope not in _Isotopes.keys():
+            if isotope not in _isotopes.keys():
                 raise InvalidParticleError(
                     f"The string '{isotope}' does not correspond to "
                     f"a valid isotope."
@@ -439,10 +439,10 @@ def _reconstruct_ion_symbol(
         Z = Z_from_arg
 
     if isinstance(Z, Integral):
-        if Z > _Elements[element]["atomic number"]:
+        if Z > _elements[element]["atomic number"]:
             raise InvalidParticleError(
                 f"The integer charge Z = {Z} cannot exceed the atomic number "
-                f"of {element}, which is {_Elements[element]['atomic number']}."
+                f"of {element}, which is {_elements[element]['atomic number']}."
             )
         elif Z <= -3:
             warnings.warn(
diff --git a/plasmapy/particles/particle_class.py b/plasmapy/particles/particle_class.py
index 9c37f05f..df75913e 100644
--- a/plasmapy/particles/particle_class.py
+++ b/plasmapy/particles/particle_class.py
@@ -23,7 +23,7 @@
 from numbers import Integral, Real
 from typing import Iterable, List, Optional, Set, Tuple, Union
 
-from plasmapy.particles.elements import _Elements, _PeriodicTable
+from plasmapy.particles.elements import _elements, _PeriodicTable
 from plasmapy.particles.exceptions import (
     ChargeError,
     InvalidElementError,
@@ -35,7 +35,7 @@
     ParticleError,
     ParticleWarning,
 )
-from plasmapy.particles.isotopes import _Isotopes
+from plasmapy.particles.isotopes import _isotopes
 from plasmapy.particles.parsing import (
     _dealias_particle_aliases,
     _invalid_particle_errmsg,
@@ -108,29 +108,29 @@ def _category_errmsg(particle, category: str) -> str:
 
 
 class AbstractParticle(ABC):
-    """
-    An abstract base class that defines the interface for particles.
-    """
+    """An abstract base class that defines the interface for particles."""
 
     @property
     @abstractmethod
     def mass(self) -> Union[u.Quantity, Real]:
+        """Provide the particle's mass."""
         raise NotImplementedError
 
     @property
     @abstractmethod
     def charge(self) -> Union[u.Quantity, Real]:
+        """Provide the particle's electric charge."""
         raise NotImplementedError
 
     @property
     def json_dict(self) -> dict:
         """
-        A dictionary representation of the particle object that is JSON friendly
-        (i.e. convertible to a JSON object).
+        A dictionary representation of the particle object that is JSON
+        friendly (i.e. convertible to a JSON object).
 
         The dictionary should maintain the following format so
-        `~plasmapy.particles.ParticleJSONDecoder` knows how to decoded the resulting
-        JSON object.
+        `~plasmapy.particles.ParticleJSONDecoder` knows how to decoded
+        the resulting JSON object.
 
         .. code-block:: python
 
@@ -154,7 +154,7 @@ def json_dict(self) -> dict:
                 },
             }}
 
-        Only the `"__init__"` entry should be modified by the subclass.
+        Only the ``"__init__"`` entry should be modified by the subclass.
         """
         json_dictionary = {
             "plasmapy_particle": {
@@ -168,14 +168,15 @@ def json_dict(self) -> dict:
 
     def __bool__(self):
         """
-        Raise an `~plasmapy.particles.exceptions.ParticleError` because particles
-        do not have a truth value.
+        Raise an `~plasmapy.particles.exceptions.ParticleError` because
+        particles do not have a truth value.
         """
         raise ParticleError("The truth value of a particle is not defined.")
 
     def json_dump(self, fp, **kwargs):
         """
-        Writes the particle's `json_dict` to the `fp` file object using `json.dump`.
+        Write the particle's `json_dict` to the ``fp`` file object using
+        `json.dump`.
 
         Parameters
         ----------
@@ -189,8 +190,8 @@ def json_dump(self, fp, **kwargs):
 
     def json_dumps(self, **kwargs) -> str:
         """
-        Serialize the particle's `json_dict` into a JSON formatted `str` using
-        `json.dumps`.
+        Serialize the particle's `json_dict` into a JSON formatted `str`
+        using `json.dumps`.
 
         Parameters
         ----------
@@ -517,7 +518,7 @@ def __init__(
 
             # Element properties
 
-            Element = _Elements[element]
+            Element = _elements[element]
 
             attributes["atomic number"] = Element["atomic number"]
             attributes["element name"] = Element["element name"]
@@ -530,7 +531,7 @@ def __init__(
 
             if isotope:
 
-                Isotope = _Isotopes[isotope]
+                Isotope = _isotopes[isotope]
 
                 attributes["baryon number"] = Isotope["mass number"]
                 attributes["isotope mass"] = Isotope.get("mass", None)
@@ -692,7 +693,7 @@ def __hash__(self) -> int:
         """
         return hash(self.__repr__())
 
-    def __invert__(self):
+    def __invert__(self) -> Particle:
         """
         Return the corresponding antiparticle, or raise an
         `~plasmapy.particles.exceptions.ParticleError` if the particle is not an
@@ -703,8 +704,9 @@ def __invert__(self):
     @property
     def json_dict(self) -> dict:
         """
-        A `json` friendly dictionary representation of the particle. (see
-        `AbstractParticle.json_dict` for more details)
+        A JSON friendly dictionary representation of the particle.
+
+        See `AbstractParticle.json_dict` for more details.
 
         Examples
         --------
@@ -728,7 +730,7 @@ def json_dict(self) -> dict:
     @property
     def particle(self) -> str:
         """
-        Return the symbol of the particle, atom, isotope, or ion.
+        The symbol of the particle, atom, isotope, or ion.
 
         .. deprecated:: 0.6.0
             `Particle.particle` has been deprecated and will be removed in
@@ -745,7 +747,7 @@ def particle(self) -> str:
     @property
     def symbol(self) -> str:
         """
-        Return the symbol of the particle, atom, isotope, or ion.
+        The symbol of the particle, atom, isotope, or ion.
 
         This attribute will return the canonical symbol for special
         particles (e.g., ``"p+"``, ``"e-"``, or ``"n"``), the atomic
@@ -765,14 +767,18 @@ def symbol(self) -> str:
         return self._attributes["symbol"]
 
     @property
-    def antiparticle(self):
+    def antiparticle(self) -> Particle:
         """
-        Return the corresponding antiparticle, or raise an
-        `~plasmapy.particles.exceptions.ParticleError` if the particle is not an
-        elementary particle.
+        The antiparticle corresponding to the particle.
 
         This attribute may be accessed by using the unary operator ``~``
-        acting on a `~plasmapy.particles.Particle` instance.
+        on a `~plasmapy.particles.Particle` instance.
+
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.ParticleError`
+            If the particle is not an elementary particle and does not
+            have a defined antiparticle.
 
         Examples
         --------
@@ -795,8 +801,8 @@ def antiparticle(self):
     @property
     def element(self) -> Optional[str]:
         """
-        Return the atomic symbol if the particle corresponds to an
-        element, and `None` otherwise.
+        The atomic symbol if the particle corresponds to an element, and
+        `None` otherwise.
 
         Examples
         --------
@@ -809,8 +815,8 @@ def element(self) -> Optional[str]:
     @property
     def isotope(self) -> Optional[str]:
         """
-        Return the isotope symbol if the particle corresponds to an
-        isotope, and `None` otherwise.
+        The isotope symbol if the particle corresponds to an isotope,
+        and `None` otherwise.
 
         Examples
         --------
@@ -823,7 +829,7 @@ def isotope(self) -> Optional[str]:
     @property
     def ionic_symbol(self) -> Optional[str]:
         """
-        Return the ionic symbol if the particle corresponds to an ion or
+        The ionic symbol if the particle corresponds to an ion or
         neutral atom, and `None` otherwise.
 
         Examples
@@ -840,12 +846,14 @@ def ionic_symbol(self) -> Optional[str]:
     @property
     def roman_symbol(self) -> Optional[str]:
         """
-        Return the spectral name of the particle (i.e. the ionic symbol
-        in Roman numeral notation).  If the particle is not an ion or
-        neutral atom, return `None`. The roman numeral represents one
-        plus the integer charge. Raise `ChargeError` if no charge has
-        been specified and `~plasmapy.utils.roman.roman.OutOfRangeError`
-        if the charge is negative.
+        The spectral name of the particle (i.e. the ionic symbol in
+        Roman numeral notation).
+
+        If the particle is not an ion or neutral atom, return `None`.
+        The roman numeral represents one plus the integer charge. Raise
+        `ChargeError` if no charge has been specified and
+        `~plasmapy.utils.roman.roman.OutOfRangeError` if the charge is
+        negative.
 
         Examples
         --------
@@ -871,9 +879,12 @@ def roman_symbol(self) -> Optional[str]:
     @property
     def element_name(self) -> str:
         """
-        Return the name of the element corresponding to this
-        particle, or raise an `~plasmapy.particles.exceptions.InvalidElementError` if
-        the particle does not correspond to an element.
+        The name of the element corresponding to this particle.
+
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidElementError`
+            If the particle does not correspond to an element.
 
         Examples
         --------
@@ -886,16 +897,18 @@ def element_name(self) -> str:
         return self._attributes["element name"]
 
     @property
-    def isotope_name(self) -> str:
+    def isotope_name(self) -> Optional[str]:
         """
-        Return the name of the element along with the isotope
-        symbol if the particle corresponds to an isotope, and
-        `None` otherwise.
+        The name of the element along with the isotope symbol if the
+        particle corresponds to an isotope, or `None` if it does not.
 
-        If the particle is not a valid element, then this
-        attribute will raise an `~plasmapy.particles.exceptions.InvalidElementError`.
-        If it is not an isotope, then this attribute will raise an
-        `~plasmapy.particles.exceptions.InvalidIsotopeError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidElementError`
+            If the particle is not a valid element.
+
+        `~plasmapy.particles.exceptions.InvalidIsotopeError`
+            If the particle is not a valid isotope.
 
         Examples
         --------
@@ -923,10 +936,12 @@ def isotope_name(self) -> str:
     @property
     def integer_charge(self) -> Integral:
         """
-        Return the particle's integer charge.
+        The particle's electrical charge in units of the elementary charge.
 
-        This attribute will raise a `~plasmapy.particles.exceptions.ChargeError` if the
-        charge has not been specified.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.ChargeError`
+            If the charge has not been specified.
 
         Examples
         --------
@@ -939,12 +954,14 @@ def integer_charge(self) -> Integral:
         return self._attributes["integer charge"]
 
     @property
-    def charge(self) -> u.Quantity:
+    def charge(self) -> u.C:
         """
-        Return the particle's electron charge in coulombs.
+        The particle's electrical charge in coulombs.
 
-        This attribute will raise a `~plasmapy.particles.exceptions.ChargeError` if the
-        charge has not been specified.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.ChargeError`
+            If the charge has not been specified.
 
         Examples
         --------
@@ -960,16 +977,19 @@ def charge(self) -> u.Quantity:
         return self._attributes["charge"]
 
     @property
-    def standard_atomic_weight(self) -> u.Quantity:
+    def standard_atomic_weight(self) -> u.kg:
         """
-        Return an element's standard atomic weight in kg.
+        The element's standard atomic weight in kg.
 
-        If the particle is isotope or ion or not an element, this
-        attribute will raise an `~plasmapy.particles.exceptions.InvalidElementError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidElementError`
+            If the particle is not an element or corresponds to an
+            isotope or ion.
 
-        If the element does not have a defined standard atomic weight,
-        this attribute will raise a
-        `~plasmapy.particles.exceptions.MissingParticleDataError`.
+        `~plasmapy.particles.exceptions.MissingParticleDataError`
+            If the element does not have a defined standard atomic
+            weight.
 
         Examples
         --------
@@ -986,9 +1006,9 @@ def standard_atomic_weight(self) -> u.Quantity:
         return self._attributes["standard atomic weight"].to(u.kg)
 
     @property
-    def mass(self) -> u.Quantity:
+    def mass(self) -> u.kg:
         """
-        Return the mass of the particle in kilograms.
+        The mass of the particle in kilograms.
 
         If the particle is an element and not an isotope or ion, then
         this attribute will return the standard atomic weight, if
@@ -1005,9 +1025,11 @@ def mass(self) -> u.Quantity:
         For special particles, this attribute will return the standard
         value for the particle's mass.
 
-        If the mass is unavailable (e.g., for neutrinos or elements with
-        no standard atomic weight), then this attribute will raise a
+        Raises
+        ------
         `~plasmapy.particles.exceptions.MissingParticleDataError`.
+            If the mass is unavailable (e.g., for neutrinos or elements
+            with no standard atomic weight.
 
         Examples
         --------
@@ -1053,15 +1075,17 @@ def mass(self) -> u.Quantity:
         raise MissingParticleDataError(f"The mass of {self} is not available.")
 
     @property
-    def nuclide_mass(self) -> u.Quantity:
+    def nuclide_mass(self) -> u.kg:
         """
-        Return the mass of the bare nucleus of an isotope or a neutron.
+        The mass of the bare nucleus of an isotope or a neutron.
 
-        This attribute will raise a
-        `~plasmapy.particles.exceptions.InvalidIsotopeError` if the particle is not an
-        isotope or neutron, or a
-        `~plasmapy.particles.exceptions.MissingParticleDataError` if the isotope mass is
-        not available.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidIsotopeError`
+            If the particle is not an isotope or neutron.
+
+        `~plasmapy.particles.exceptions.MissingParticleDataError`
+            If the isotope mass is not available.
 
         Examples
         --------
@@ -1096,9 +1120,9 @@ def nuclide_mass(self) -> u.Quantity:
         return _nuclide_mass.to(u.kg)
 
     @property
-    def mass_energy(self) -> u.Quantity:
+    def mass_energy(self) -> u.J:
         """
-        Return the mass energy of the particle in joules.
+        The mass energy of the particle in joules.
 
         If the particle is an isotope or nuclide, return the mass energy
         of the nucleus only.
@@ -1131,13 +1155,14 @@ def mass_energy(self) -> u.Quantity:
             ) from None
 
     @property
-    def binding_energy(self) -> u.Quantity:
+    def binding_energy(self) -> u.J:
         """
-        Return the nuclear binding energy in joules.
+        The particle's nuclear binding energy.
 
-        This attribute will raise an
-        `~plasmapy.particles.exceptions.InvalidIsotopeError` if the particle is not a
-        nucleon or isotope.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidIsotopeError`
+            If the particle is not a nucleon or isotope.
 
         Examples
         --------
@@ -1183,8 +1208,10 @@ def atomic_number(self) -> Integral:
         """
         Return the number of protons in an element, isotope, or ion.
 
-        If the particle is not an element, then this attribute will
-        raise an `~plasmapy.particles.exceptions.InvalidElementError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidElementError`.
+            If the particle does not correspond to an element.
 
         Examples
         --------
@@ -1202,13 +1229,12 @@ def atomic_number(self) -> Integral:
     @property
     def mass_number(self) -> Integral:
         """
-        Return the number of nucleons in an isotope.
-
-        This attribute will return the number of protons plus the number
-        of neutrons in an isotope or nuclide.
+        The total number of protons and neutrons in an isotope or nuclide.
 
-        If the particle is not an isotope, then this attribute will
-        raise an `~plasmapy.particles.exceptions.InvalidIsotopeError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidIsotopeError`.
+            If the particle does not correspond to an isotope.
 
         Examples
         --------
@@ -1249,13 +1275,15 @@ def neutron_number(self) -> Integral:
     @property
     def electron_number(self) -> Integral:
         """
-        Return the number of electrons in an ion.
+        The number of electrons in an ion.
 
         This attribute will return the number of bound electrons in an
         ion, or ``1`` for an electron.
 
-        If this particle is not an ion or electron, then this attribute
-        will raise an `~plasmapy.particles.exceptions.InvalidIonError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidIonError`
+            If this particle is not an ion or electron.
 
         Examples
         --------
@@ -1274,12 +1302,15 @@ def electron_number(self) -> Integral:
     @property
     def isotopic_abundance(self) -> u.Quantity:
         """
-        Return the isotopic abundance of an isotope.
+        The isotopic abundance of an isotope.
 
-        If the isotopic abundance is not available, this attribute will
-        raise a `~plasmapy.particles.exceptions.MissingParticleDataError`.  If the
-        particle is not an isotope or is an ion of an isotope, then this
-        attribute will raise an `~plasmapy.particles.exceptions.InvalidIsotopeError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidIsotopeError`
+            If the particle does not correspond to an isotope.
+
+        `~plasmapy.particles.exceptions.MissingParticleDataError`
+            If the isotopic abundance is not available.
 
         Examples
         --------
@@ -1306,14 +1337,16 @@ def isotopic_abundance(self) -> u.Quantity:
     @property
     def baryon_number(self) -> Integral:
         """
-        Return the number of baryons in a particle.
+        The number of baryons in a particle.
 
         This attribute will return the number of protons and neutrons
         minus the number of antiprotons and antineutrons. The baryon
         number is equivalent to the mass number for isotopes.
 
-        If the baryon number is unavailable, then this attribute will
-        raise a `~plasmapy.particles.exceptions.MissingParticleDataError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.MissingParticleDataError`
+            If the baryon number is unavailable.
 
         Examples
         --------
@@ -1336,8 +1369,10 @@ def lepton_number(self) -> Integral:
         This attribute returns the number of leptons minus the number of
         antileptons, excluding bound electrons in an atom or ion.
 
-        If the lepton number is unavailable, then this attribute will
-        raise a `~plasmapy.particles.exceptions.MissingParticleDataError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.MissingParticleDataError`
+            If the lepton number is unavailable.
 
         Examples
         --------
@@ -1357,8 +1392,8 @@ def lepton_number(self) -> Integral:
     @property
     def half_life(self) -> Union[u.Quantity, str]:
         """
-        Return the particle's half-life in seconds, or a `str`
-        with half-life information.
+        The particle's half-life in seconds, or a `str` with half-life
+        information.
 
         Particles that do not have sufficiently well-constrained
         half-lives will return a `str` containing the information
@@ -1411,11 +1446,13 @@ def spin(self) -> Real:
     @property
     def periodic_table(self) -> namedtuple:
         """
-        Return a `~collections.namedtuple` to access category, period,
-        group, and block information about an element.
+        A `~collections.namedtuple` that provides access to category,
+        period, group, and block information about an element.
 
-        If the particle is not an element, isotope, or ion, then this
-        attribute will raise an `~plasmapy.particles.exceptions.InvalidElementError`.
+        Raises
+        ------
+        `~plasmapy.particles.exceptions.InvalidElementError`
+            If the particle is not an element, isotope, or ion.
 
         Examples
         --------
@@ -1488,7 +1525,7 @@ def is_category(
         ``valid_categories`` attribute of `~Particle.is_category`.
 
         Examples
-        -----
+        --------
         Required categories may be entered as positional arguments,
         including as a `list`, `set`, or `tuple` of required categories.
 
@@ -1879,8 +1916,9 @@ def _validate_parameter(obj, can_be_negative=True) -> np.float64:
     @property
     def json_dict(self) -> dict:
         """
-        A `json` friendly dictionary representation of the particle. (see
-        `AbstractParticle.json_dict` for more details)
+        A `json` friendly dictionary representation of the particle.
+
+        See `AbstractParticle.json_dict` for more details.
 
         Examples
         --------
@@ -1910,12 +1948,12 @@ def json_dict(self) -> dict:
 
     @property
     def mass(self) -> np.float64:
-        """Return the dimensionless mass of the particle."""
+        """The dimensionless mass of the particle."""
         return self._mass
 
     @property
     def charge(self) -> np.float64:
-        """Return the dimensionless charge of the particle."""
+        """The dimensionless charge of the particle."""
         return self._charge
 
     @mass.setter
@@ -1949,8 +1987,9 @@ def charge(self, q: Optional[Union[Real, u.Quantity]]):
     @property
     def symbol(self) -> str:
         """
-        Return the symbol assigned to the dimensionless particle.  If no
-        symbol was defined, then return the value given by `repr`.
+        The symbol assigned to the dimensionless particle.
+
+        If no symbol was defined, then return the value given by `repr`.
         """
         return self._symbol
 
@@ -2040,8 +2079,9 @@ def __repr__(self):
     @property
     def json_dict(self) -> dict:
         """
-        A `json` friendly dictionary representation of the particle. (see
-        `AbstractParticle.json_dict` for more details)
+        A `json` friendly dictionary representation of the particle.
+
+        See `AbstractParticle.json_dict` for more details.
 
         Examples
         --------
@@ -2151,7 +2191,7 @@ def mass(self, m: u.kg):
     @property
     def mass_energy(self) -> u.J:
         """
-        Return the mass energy of the custom particle.
+        The mass energy of the custom particle.
 
         Examples
         --------
@@ -2165,8 +2205,9 @@ def mass_energy(self) -> u.J:
     @property
     def symbol(self) -> str:
         """
-        Return the symbol assigned to the custom particle.  If no symbol
-        was defined, then return the value given by `repr`.
+        The symbol assigned to the custom particle.
+
+        If no symbol was defined, then return the value given by `repr`.
         """
         return self._symbol
 
diff --git a/plasmapy/particles/particle_collections.py b/plasmapy/particles/particle_collections.py
index 40bd3b31..da868f1e 100644
--- a/plasmapy/particles/particle_collections.py
+++ b/plasmapy/particles/particle_collections.py
@@ -188,16 +188,16 @@ def append(self, particle: ParticleLike):
     @property
     def charge(self) -> u.C:
         """
-        A `~astropy.units.Quantity` array of the electric charges of the
-        particles.
+        A `~astropy.units.Quantity` array of the electric charges
+        of the particles.
         """
         return self._get_particle_attribute("charge", unit=u.C, default=np.nan * u.C)
 
     @property
     def data(self) -> List[Union[Particle, CustomParticle]]:
         """
-        A `list` containing the particles contained in the `ParticleList`
-        instance.
+        A `list` containing the particles contained in the
+        `ParticleList` instance.
 
         The `~plasmapy.particles.ParticleList.data` attribute should not
         be modified directly.
@@ -217,7 +217,10 @@ def extend(self, iterable: Iterable[ParticleLike]):
 
     @property
     def half_life(self) -> u.s:
-        """A `~astropy.units.Quantity` array of the half-lives of the particles."""
+        """
+        A `~astropy.units.Quantity` array of the half-lives of the
+        particles.
+        """
         return self._get_particle_attribute("half_life", unit=u.s, default=np.nan * u.s)
 
     def insert(self, index, particle: ParticleLike):
@@ -230,8 +233,8 @@ def insert(self, index, particle: ParticleLike):
     @property
     def integer_charge(self) -> np.array:
         """
-        An array of the quantized charges of the particles, as multiples
-        of the elementary charge.
+        An array of the quantized charges of the particles, as
+        multiples of the elementary charge.
         """
         return np.array(self._get_particle_attribute("integer_charge", default=np.nan))
 
@@ -255,8 +258,9 @@ def mass_energy(self) -> u.J:
 
     def sort(self, key: Callable = None, reverse: bool = False):
         """
-        Sort the `ParticleList` in-place.  For more information, refer
-        to the documentation for `list.sort`.
+        Sort the `ParticleList` in-place.
+
+        For more information, refer to the documentation for `list.sort`.
         """
         if key is None:
             raise TypeError("Unable to sort a ParticleList without a key.")
@@ -265,7 +269,7 @@ def sort(self, key: Callable = None, reverse: bool = False):
 
     @property
     def symbols(self) -> List[str]:
-        """A list of the symbols of the particles."""
+        """A `list` of the symbols of the particles."""
         return self._get_particle_attribute("symbol")
 
 
diff --git a/plasmapy/particles/serialization.py b/plasmapy/particles/serialization.py
index 43c8e9ef..5d9ad702 100644
--- a/plasmapy/particles/serialization.py
+++ b/plasmapy/particles/serialization.py
@@ -1,6 +1,4 @@
-"""
-Functionality for JSON deserialization of PlasmaPy particles.
-"""
+"""Functionality for JSON deserialization of particle objects."""
 __all__ = [
     "json_load_particle",
     "json_loads_particle",
@@ -21,7 +19,7 @@
 class ParticleJSONDecoder(json.JSONDecoder):
     """
     A custom `~json.JSONDecoder` class to deserialize JSON objects into
-    PlasmaPy particle objects.
+    the appropriate particle objects.
 
     Parameters
     ----------
@@ -29,8 +27,9 @@ class ParticleJSONDecoder(json.JSONDecoder):
         If specified, will be called with the result of every JSON object
         decoded and its return value will be used in place of the given `dict`.
         This can be used to provide custom deserializations (e.g. to support
-        JSON-RPC class hinting)
-        (If not specified, then defaults to `particle_hook`.).
+        JSON-RPC class hinting).  If not specified, then defaults to
+        `particle_hook`.).
+
     **kwargs :
         Any keyword accepted by `~json.JSONDecoder`.
     """
@@ -43,9 +42,12 @@ def __init__(self, *, object_hook=None, **kwargs):
     @staticmethod
     def particle_hook(json_dict):
         """
-        An `object_hook` utilized by the `json` deserialization processes to decode
-        json strings into a `plasmapy` particle class (`AbstractParticle`,
-        `CustomParticle`, `DimensionlessParticle`, `Particle`).
+        Decode JSON strings into the appropriate particle class.
+
+        This method is an `object_hook` utilized by the `json`
+        deserialization processes to decode json strings into a particle
+        class (`AbstractParticle`, `CustomParticle`,
+        `DimensionlessParticle`, `Particle`).
         """
         particle_types = {
             "AbstractParticle": AbstractParticle,
@@ -71,16 +73,20 @@ def particle_hook(json_dict):
 
 def json_load_particle(fp, *, cls=ParticleJSONDecoder, **kwargs):
     """
-    A convenient form of `json.load` to deserialize a JSON document into a
-    PlasmaPy particle object. (Mirrors `json.load` with `cls` defaulting to
-    `ParticleJSONDecoder`.).
+    Deserialize a JSON document into the appropriate particle object.
+
+    This function is a convenient form of `json.load` to deserialize a
+    JSON document into a particle object. (Mirrors `json.load` with
+    `cls` defaulting to `ParticleJSONDecoder`.).
 
     Parameters
     ----------
     fp : `file object <https://docs.python.org/3/glossary.html#term-file-object>`_
         A file object containing a JSON document.
+
     cls : `json.JSONDecoder` class
         A `~json.JSONDecoder` class. (Default `ParticleJSONDecoder`).
+
     **kwargs :
         Any keyword accepted by `json.load`.
     """
@@ -89,16 +95,20 @@ def json_load_particle(fp, *, cls=ParticleJSONDecoder, **kwargs):
 
 def json_loads_particle(s, *, cls=ParticleJSONDecoder, **kwargs):
     """
-    A convenient form of `json.loads` to deserialize a JSON string into a
-    PlasmaPy particle object. (Mirrors `json.loads` with `cls` defaulting to
-    `ParticleJSONDecoder`.).
+    Deserialize a JSON string into the appropriate particle object.
+
+    This function is convenient form of `json.loads` to deserialize a
+    JSON string into a particle object. (Mirrors `json.loads` with `cls`
+    defaulting to `ParticleJSONDecoder`.).
 
     Parameters
     ----------
     s : str
         A JSON string.
+
     cls : `json.JSONDecoder` class
         A `~json.JSONDecoder` class. (Default `ParticleJSONDecoder`).
+
     **kwargs :
         Any keyword accepted by `json.loads`.
     """
diff --git a/setup.cfg b/setup.cfg
index fa5e2576..2551acca 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -112,7 +112,7 @@ max-line-length = 88
 # line, which is sometimes necessary for even concise descriptions of plasma
 # physics functions and classes.
 convention = numpy
-add-select = D402,D413
+add-select = D402
 add-ignore = D202,D205,D302,D400,D105
 
 [flake8]


Test patch:
diff --git a/plasmapy/particles/tests/test_atomic.py b/plasmapy/particles/tests/test_atomic.py
index 635279d7..b0e40b22 100644
--- a/plasmapy/particles/tests/test_atomic.py
+++ b/plasmapy/particles/tests/test_atomic.py
@@ -35,7 +35,7 @@
     stable_isotopes,
     standard_atomic_weight,
 )
-from ..isotopes import _Isotopes
+from ..isotopes import _isotopes
 from ..nuclear import nuclear_binding_energy, nuclear_reaction_energy
 from ..symbols import atomic_symbol, element_name, isotope_symbol
 
@@ -623,10 +623,10 @@ def test_half_life():
 def test_half_life_unstable_isotopes():
     """Test that `half_life` returns `None` and raises an exception for
     all isotopes that do not yet have half-life data."""
-    for isotope in _Isotopes.keys():
+    for isotope in _isotopes.keys():
         if (
-            "half_life" not in _Isotopes[isotope].keys()
-            and not _Isotopes[isotope].keys()
+            "half_life" not in _isotopes[isotope].keys()
+            and not _isotopes[isotope].keys()
         ):
             with pytest.raises(MissingParticleDataError):
 
diff --git a/plasmapy/particles/tests/test_particle_class.py b/plasmapy/particles/tests/test_particle_class.py
index 1301cecd..b4e36d3a 100644
--- a/plasmapy/particles/tests/test_particle_class.py
+++ b/plasmapy/particles/tests/test_particle_class.py
@@ -24,7 +24,7 @@
     ParticleError,
     ParticleWarning,
 )
-from plasmapy.particles.isotopes import _Isotopes
+from plasmapy.particles.isotopes import _isotopes
 from plasmapy.particles.particle_class import (
     CustomParticle,
     DimensionlessParticle,
@@ -712,7 +712,7 @@ def test_particle_half_life_string():
     """
 
     for isotope in known_isotopes():
-        half_life = _Isotopes[isotope].get("half-life", None)
+        half_life = _isotopes[isotope].get("half-life", None)
         if isinstance(half_life, str):
             break