From 50187ac538fbaae82578f86324c3fb946dd988dc Mon Sep 17 00:00:00 2001
From: Michael Murdock <mm13000@byu.edu>
Date: Mon, 30 Sep 2024 15:51:10 -0600
Subject: [PATCH] Keyword only arguments. Update simphony/libraries/sipann.py.
 Clarify description in docs/tutorials/intro.ipynb and add link to PEP 3102.

---
 docs/tutorials/intro.ipynb   |  5 +++--
 simphony/libraries/sipann.py | 10 ++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/docs/tutorials/intro.ipynb b/docs/tutorials/intro.ipynb
index 54f29703..f1b87422 100644
--- a/docs/tutorials/intro.ipynb
+++ b/docs/tutorials/intro.ipynb
@@ -135,7 +135,7 @@
     "import sax\n",
     "from jax.typing import ArrayLike\n",
     "\n",
-    "def custom_model(param: float = 0.5) -> sax.SDict:\n",
+    "def custom_model(*, param: float = 0.5) -> sax.SDict:\n",
     "    \"\"\"This model will have one parameter, param, which defaults to 0.5.\n",
     "    \n",
     "    Args:\n",
@@ -164,10 +164,11 @@
     "\n",
     "* [Python 3 guide for scientists](https://python-3-for-scientists.readthedocs.io/en/latest/python3_advanced.html)\n",
     "* [Luke Plant's Blog](https://lukeplant.me.uk/blog/posts/keyword-only-arguments-in-python/)\n",
+    "* [PEP 3102: Keyword-Only Arguments](https://peps.python.org/pep-3102/)\n",
     "```\n",
     "\n",
     "```{important}\n",
-    "Model function parameters **are required to be keyword-only**.\n",
+    "Model function parameters **are required to be keyword-only**. Syntactically, this means the first argument in the function definition must be `*`.\n",
     "```\n",
     "\n",
     "* In the backend, SAX inspects the model signature and passes in only the requested variables to the model function. \n",
diff --git a/simphony/libraries/sipann.py b/simphony/libraries/sipann.py
index ec4fc7c8..48efc292 100644
--- a/simphony/libraries/sipann.py
+++ b/simphony/libraries/sipann.py
@@ -54,6 +54,7 @@ def _create_sdict_from_model(model, wl: Union[float, ArrayLike]) -> sax.SDict:
 
 
 def gap_func_symmetric(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -110,6 +111,7 @@ def gap_func_symmetric(
 
 
 def gap_func_antisymmetric(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -178,6 +180,7 @@ def gap_func_antisymmetric(
 
 
 def half_ring(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -230,6 +233,7 @@ def half_ring(
 
 
 def straight_coupler(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -280,6 +284,7 @@ def straight_coupler(
 
 
 def standard_coupler(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -339,6 +344,7 @@ def standard_coupler(
 
 
 def double_half_ring(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -393,6 +399,7 @@ def double_half_ring(
 
 
 def angled_half_ring(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -457,6 +464,7 @@ def angled_half_ring(
 
 
 def waveguide(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -496,6 +504,7 @@ def waveguide(
 
 
 def racetrack(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     width: float = 500.0,
     thickness: float = 220.0,
@@ -554,6 +563,7 @@ def racetrack(
 
 
 def premade_coupler(
+    *,
     wl: Union[float, ArrayLike] = 1.55,
     split: int = 50,
 ) -> sax.SDict: