Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Spell Checker #103

Merged
merged 49 commits into from
Apr 26, 2024
Merged

Add Spell Checker #103

merged 49 commits into from
Apr 26, 2024

Conversation

bpaul4
Copy link
Contributor

@bpaul4 bpaul4 commented Apr 9, 2024

Add Spell Checker

Fixes #102

{Description}

  • Add CI check on spelling for Python files, documentation and general text files
  • Adds common exceptions (e.g., "IDAES", hexadecimal keys, ...) and fixes a small batch of typos

Legal Acknowledgement

By contributing to this software project, I agree to the following terms and conditions for my contribution:

I agree my contributions are submitted under the license terms described in the LICENSE.txt file at the top level of this directory.
I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

@ksbeattie ksbeattie added the Priority:Normal Normal Priority Issue or PR label Apr 11, 2024
@andrewlee94
Copy link
Member

@bpaul4 I went throguh and fixed most/all of the typos in the idaes-examples/mod folder.

@ksbeattie
Copy link
Member

ksbeattie commented Apr 13, 2024

I just pushed a bunch of changes, one commit per "correction". Please, more knowledgeable people, review.

FWIW, here's an example of how I did the individual "search and replace" via the macos command line:

sed -i '~' 's/intialization/initialization/g' $(grep -rl intialization)

Edit: Use the w option in the grep here if you want correction to be on a word boundary. It may not always be what is needed but it helps in situations where the misspelled word is part of another correctly spelled word, like:

sed -i '~' 's/compressio/compressor/g' $(grep -rwl compressio)

@bpaul4
Copy link
Contributor Author

bpaul4 commented Apr 15, 2024

Thanks @ksbeattie, your commits look good and the regenerated SVG files look good as well. The "search and replace" is an interesting tool to have, can this be done on Windows as well?

@lbianchi-lbl
Copy link
Contributor

lbianchi-lbl commented Apr 25, 2024

@bpaul4 After looking at the notebook where the pandas warnings are causing the spellcheck to fail, I think the code that causes the warnings to be emitted may actually be in the notebook itself, even though the word being flagged as a misspelling (ser) is defined elsewhere (most likely within pandas):

image
image

So, applying the suggested fix (using float(data["my_column"].iloc[0]) instead of float(data["my_column"])) should cause the warnings, and consequently those spellcheck failures, to go away.

@bpaul4
Copy link
Contributor Author

bpaul4 commented Apr 25, 2024

@agarciadiego in the image above from the notebook "Using Parameter Estimation with Modular Property Packages", it appears that in some variables are set to values of float(a dictionary value) and some expressions are defined as float(a dictionary series) - a_model_variable. Would you be able to investigate which are causing the FutureWarnings and push any syntax corrections to this PR?

@lbianchi-lbl
Copy link
Contributor

lbianchi-lbl commented Apr 25, 2024

@agarciadiego in the image above from the notebook "Using Parameter Estimation with Modular Property Packages", it appears that in some variables are set to values of float(a dictionary value) and some expressions are defined as float(a dictionary series) - a_model_variable. Would you be able to investigate which are causing the FutureWarnings and push any syntax corrections to this PR?

@bpaul4 @agarciadiego I've created a dedicated issue to track this separately from this PR: #108.

@lbianchi-lbl
Copy link
Contributor

The spellcheck is now passing, however the notebooks tests are failing because of an AssertionError in active/power_gen/ngcc/ngcc_test.ipynb:

image

I was able to confirm the same failure running locally (Ubuntu 20.04, Python 3.10.14).

Any thoughts on how likely it is that the failure is related to the changes in this PR?

@lbianchi-lbl
Copy link
Contributor

lbianchi-lbl commented Apr 26, 2024

Update: I ran git bisect between 5703f2a (bad) and f62f20f (good) using git bisect run bash -c 'pytest --verbose idaes_examples/notebooks/active/power_gen/ ; status=$? ; git reset --hard ; exit $status' as a "probe". According to this, the commit that introduced the failure is 4b805f3:

4b805f3f04a67e37e0cf3f228d7cdb53a7bdf86d is the first bad commit
commit 4b805f3f04a67e37e0cf3f228d7cdb53a7bdf86d
Author: Andrew Lee <[email protected]>
Date:   Fri Apr 12 12:20:16 2024 -0400

    Fixing typos in idaes_examples/mod

 .../NETL_32D_gas_phase_thermo.py                   |  6 +++---
 .../NETL_32D_solid_phase_thermo.py                 |  6 +++---
 idaes_examples/mod/dae/petsc/pid_steam_tank.py     |  4 ++--
 idaes_examples/mod/hda/hda_ideal_VLE.py            | 14 +++++++-------
 idaes_examples/mod/methanol/methanol_param_VLE.py  |  4 ++--
 .../mod/methanol/methanol_state_block_VLE.py       |  6 +++---
 idaes_examples/mod/power_gen/SOFC_ROM.py           |  2 +-
 idaes_examples/mod/power_gen/gas_turbine.py        | 22 +++++++++++-----------
 idaes_examples/mod/power_gen/hrsg.py               |  4 ++--
 idaes_examples/mod/power_gen/ngcc.py               |  8 ++++----
 idaes_examples/mod/power_gen/ngcc_soec_costing.py  |  4 ++--
 idaes_examples/mod/power_gen/soec.py               |  6 +++---
 .../properties/thermophysical_property_example.py  |  6 +++---
 13 files changed, 46 insertions(+), 46 deletions(-)
bisect run success

I see that this commit doesn't directly affect the failing notebook idaes_examples/notebooks/active/power_gen/ngcc/ngcc_test.ipynb, but it does make some functional (in the sense of "not non-functional") changes to Python modules in idaes_examples/mod/power_gen, which, based on the naming alone, makes me think they might be related. Any idea on what might be happening?

@JavalVyas2000
Copy link
Contributor

idaes_examples/mod/power_gen/gas_turbine.py
idaes_examples/mod/power_gen/hrsg.py
idaes_examples/mod/power_gen/ngcc.py

The above are the files used in ngcc flowsheet. I will look into this and let you know.

@JavalVyas2000
Copy link
Contributor

JavalVyas2000 commented Apr 26, 2024

The commit commit changes a variable name and the model is being initialized from a saved solution which has the incorrect spelling for cap_additional_co2 and I believe this is a reason why there is an assert error.

@lbianchi-lbl
Copy link
Contributor

lbianchi-lbl commented Apr 26, 2024

Thanks @JavalVyas2000 for the tip. I was able to delete the outdated ngcc_init.json.gz and re-run the notebook locally, which resulted in a new file with up-to-date variables being created. All checks are now passing.

@bpaul4
Copy link
Contributor Author

bpaul4 commented Apr 26, 2024

Thank you @andrewlee94 @ksbeattie @JavalVyas2000 @lbianchi-lbl for your contributions to this PR. It looks like everything is passing now and all spelling/other issues have been resolved.

@bpaul4 bpaul4 marked this pull request as ready for review April 26, 2024 13:07
@bpaul4 bpaul4 requested a review from andrewlee94 April 26, 2024 13:07
Copy link
Contributor

@lbianchi-lbl lbianchi-lbl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @bpaul4 for leading this effort!

Copy link
Contributor

@agarciadiego agarciadiego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bpaul4
Copy link
Contributor Author

bpaul4 commented Apr 26, 2024

@andrewlee94 do you have any further suggestions or requests before we merge this?

pyproject.toml Outdated
# Ignore Attemp - assume it is abbreviating attemperator
Attemp = "Attemp"
# Ignore ba in hexadecimal values, or block names
ba = "ba"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ignore still required now that we have the regex later to exclude the hex values in the id field? If not, we should remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might still be needed, it's quick to test though so I'll do that now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it catches block names e.g. ba23 and also atomic element usage of Ba for barium. Those are flagged as typos if this ignore line is taken out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, where is ba23 used? That does not look like a very good name for a block.
Catching Ba for barium is important, but we should update the comment to indicate this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the exception is removed, these typos are flagged:

(all-installed-3.9) C:\Users\Brandon\GitHub\IDAES\examples>typos
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:345:594
    |
345 |        "    <text xml:space=\"preserve\" style=\"font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle;stroke-width:0.264583\" x=\"21.494312\" y=\"157.50975\" id=\"text962-24-7-1-8-9-9-45-7-5-5-8-4-5\"><tspan sodipodi:role=\"line\" id=\"tspan39444\" x=\"21.494312\" y=\"157.50975\" style=\"font-weight:bold\">ba00</tspan></text>\n",
    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:403:606
    |
403 |        "    <text xml:space=\"preserve\" style=\"font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle;stroke-width:0.264583\" x=\"70.442276\" y=\"117.82269\" id=\"text962-24-7-1-8-9-9-45-7-5-5-8-4-5-9-8-0\"><tspan sodipodi:role=\"line\" id=\"tspan39444-3-1-3\" x=\"70.442276\" y=\"117.82269\" style=\"font-weight:bold\">ba03</tspan></text>\n",
    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:409:409
    |
409 |        "    <text xml:space=\"preserve\" style=\"font-style:normal;font-weight:normal;font-size:2.11667px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583\" x=\"42.142143\" y=\"151.60056\" id=\"text29235\"><tspan sodipodi:role=\"line\" id=\"tspan29233\" style=\"font-size:2.11667px;stroke-width:0.264583;font-weight:bold\" x=\"42.142143\" y=\"151.60056\">ba01</tspan></text>\n",
    |                                                                                                                                                                                                                                                                                                                                                                                                                         ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:411:413
    |
411 |        "    <text xml:space=\"preserve\" style=\"font-style:normal;font-weight:normal;font-size:2.11667px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583\" x=\"42.671307\" y=\"123.55508\" id=\"text29235-4\"><tspan sodipodi:role=\"line\" id=\"tspan29233-1\" style=\"font-size:2.11667px;stroke-width:0.264583;font-weight:bold\" x=\"42.671307\" y=\"123.55508\">ba02</tspan></text>\n",
    |                                                                                                                                                                                                                                                                                                                                                                                                                             ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1043:19
     |
1043 |        "      <th>ba00</th>\n",
     |                   ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1063:19
     |
1063 |        "      <th>ba01</th>\n",
     |                   ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1083:19
     |
1083 |        "      <th>ba02</th>\n",
     |                   ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1103:19
     |
1103 |        "      <th>ba03</th>\n",
     |                   ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1916:9
     |
1916 |        "ba00                     68.682089      2380.214335         56.279763   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1917:9
     |
1917 |        "ba01                     68.682089      2380.214335         48.360706   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1918:9
     |
1918 |        "ba02                     15.392573       480.796393          9.768722   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1919:9
     |
1919 |        "ba03                     15.392573       480.796393         13.562943   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1969:9
     |
1969 |        "ba00                   288.150000  1.013250e+05                  0.0092   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1970:9
     |
1970 |        "ba01                   310.930000  1.272390e+05                  0.0092   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1971:9
     |
1971 |        "ba02                   310.930000  1.272390e+05                0.003065   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:228:8
    |
228 |     fs.ba01 = Arc(source=fs.intercooler_s2.outlet, destination=fs.ASU.inlet)
    |        ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:1972:9
     |
1972 |        "ba03                   431.696780  1.272390e+05                0.003065   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:271:8
    |
271 |     fs.ba02 = Arc(source=fs.ASU.O2_outlet, destination=fs.oxygen_preheater.tube_inlet)
    |        ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2022:9
     |
2022 |        "ba00                                  0.0003                     0.0099   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:363:8
    |
363 |     fs.ba03 = Arc(
    |        ^^
    |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2023:9
     |
2023 |        "ba01                                  0.0003                     0.0099   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2024:9
     |
2024 |        "ba02                                     0.0                        0.0   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2025:9
     |
2025 |        "ba03                                     0.0                        0.0   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2075:9
     |
2075 |        "ba00                    0.7732       0.2074                                \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:1515:30
     |
1515 |     iinit.propagate_state(fs.ba01)
     |                              ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2076:9
     |
2076 |        "ba01                    0.7732       0.2074                                \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:1517:30
     |
1517 |     iinit.propagate_state(fs.ba02)
     |                              ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2077:9
     |
2077 |        "ba02                  0.001914     0.995021                                \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:1521:30
     |
1521 |     iinit.propagate_state(fs.ba03)
     |                              ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2078:9
     |
2078 |        "ba03                  0.001914     0.995021           0.0            0.0   \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:1887:14
     |
1887 |             "ba00": fs.air_compressor_s1.inlet,
     |              ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2128:9
     |
2128 |        "ba00                                              \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_flowsheet.py:2048:14
     |
2048 |             "ba00": fs.air_compressor_s1.inlet,
     |              ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2129:9
     |
2129 |        "ba01                                              \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2130:9
     |
2130 |        "ba02                                              \n",
     |         ^^
     |
error: `ba` should be `by`, `be`
  --> .\idaes_examples\archive\power_gen\rsofc\rsofc_soec_src.ipynb:2131:9
     |
2131 |        "ba03                         0.0             0.0  \n",
     |         ^^
     |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:117:22
    |
117 |     "Atoms = [Atom(\"Ba\"), Atom(\"Fe\"), Atom(\"In\"), Atom(\"O\")]"
    |                      ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:225:169
    |
225 |     "For this system, we introduce several rules about the allowed placement of atoms in the design. First, we require that all A-sites in the material are occupied by Ba. Next, we require that all O-sites are occupied by O. Thirdly, we forbid Ba and O from being placed in B-sites. And finally, we require that some atom be placed in each B-site. These four rules  effectively limit the scope of the optimization to focus on the labeling of B-sites as either Fe or In. "
    |                                                                                                                                                                         ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:225:245
    |
225 |     "For this system, we introduce several rules about the allowed placement of atoms in the design. First, we require that all A-sites in the material are occupied by Ba. Next, we require that all O-sites are occupied by O. Thirdly, we forbid Ba and O from being placed in B-sites. And finally, we require that some atom be placed in each B-site. These four rules  effectively limit the scope of the optimization to focus on the labeling of B-sites as either Fe or In. "
    |                                                                                                                                                                                                                                                     ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:234:69
    |
234 |     "m.Yik.rules.append(FixedTo(1, sites=ASites, site_types=[Atom(\"Ba\")]))\n",
    |                                                                     ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:236:69
    |
236 |     "m.Yik.rules.append(FixedTo(0, sites=BSites, site_types=[Atom(\"Ba\"), Atom(\"O\")]))\n",
    |                                                                     ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design_src.ipynb:246:342
    |
246 |     "Notice that in each case, we specify a subset of locations or atoms of interest. This is because, for example, our material activity depends on oxygen sites only and it would be nonsensical to try to interpret one of the conformations on a different type of site. Similarly, the dopant budgets are written only over In atoms and not on Ba, Fe, or O. "
    |                                                                                                                                                                                                                                                                                                                                                      ^^
    |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design.py:32:20
   |
32 |     Atoms = [Atom('Ba'), Atom('Fe'), Atom('In'), Atom('O')]
   |                    ^^
   |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design.py:54:67
   |
54 |     m.Yik.rules.append(FixedTo(1, sites=ASites, site_types=[Atom('Ba')]))
   |                                                                   ^^
   |
error: `Ba` should be `By`, `Be`
  --> .\idaes_examples\archive\matopt\metal_oxide_bulk_design.py:56:67
   |
56 |     m.Yik.rules.append(FixedTo(0, sites=BSites, site_types=[Atom('Ba'), Atom('O')]))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK - we should update the comment however to indicate that it is there to catch these (as otherwise someone else might as k the same question I did).

@lbianchi-lbl lbianchi-lbl enabled auto-merge (squash) April 26, 2024 14:36
@lbianchi-lbl lbianchi-lbl merged commit b4badf7 into IDAES:main Apr 26, 2024
8 checks passed
@bpaul4 bpaul4 deleted the spell-checker branch October 1, 2024 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:Normal Normal Priority Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Spellchecker to CI checks
6 participants