Repository: mhostetter/galois (language: python)

Issue:
Incorrect value in `prev_prime()`
Newly introduced bug from #527.

```python
In [2]: galois.prev_prime(100000037)
Out[2]: 100000007
```

Should equal 100000037.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 587b9b753..a1a5cdecb 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -3,11 +3,11 @@ name: Build
 on:
   push:
     branches:
-      - master
+      - main
       - 'release/*'
   pull_request:
     branches:
-      - master
+      - main
       - 'release/*'
   workflow_call:
 
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 18bed60bd..fd80d977f 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -6,7 +6,7 @@ on:
       - 'release/*'
   pull_request:
     branches:
-      - master
+      - main
       - 'release/*'
   workflow_call:
   workflow_dispatch:
@@ -120,6 +120,7 @@ jobs:
       - name: Update versions.json file
         shell: python
         run: |
+          from distutils.version import StrictVersion
           import json
           import pathlib
           import os
@@ -133,6 +134,13 @@ jobs:
           versions.remove("latest")
           os.system("rm latest")
 
+          # Sort versions, ignoring the initial 'v'
+          def sort_version(version):
+            if "x" in version:
+              version = version.replace("x", "1000")
+            return StrictVersion(version[1:])
+          versions = sorted(versions, key=sort_version, reverse=True)
+
           list_of_dicts = []
           latest = None
           for version in versions:
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index 6d7d024d8..9fc88f375 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -3,16 +3,16 @@ name: Lint
 on:
   push:
     branches:
-      - master
+      - main
       - 'release/*'
   pull_request:
     branches:
-      - master
+      - main
       - 'release/*'
 
 jobs:
   run-linter:
-    name: Lint
+    name: Ruff Lint
     runs-on: ubuntu-latest
     strategy:
       matrix:
@@ -28,17 +28,17 @@ jobs:
       - name: Upgrade pip
         run: python3 -m pip install --upgrade pip
 
-      - name: Install the `galois` package with [dev]
-        run: python3 -m pip install .[dev]
+      - name: Install the dev requirements
+        run: python3 -m pip install -r requirements-dev.txt
 
-      - name: Lint code with pylint
-        run: python3 -m pylint src/galois/
+      - name: Install the `galois` package
+        run: python3 -m pip install .
 
-      - name: Lint tests with pylint
-        run: python3 -m pylint tests/
+      - name: Lint with ruff
+        run: python3 -m ruff check --output-format=github .
 
   run-formatter:
-    name: Format
+    name: Ruff Format
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
@@ -51,8 +51,11 @@ jobs:
       - name: Upgrade pip
         run: python3 -m pip install --upgrade pip
 
-      - name: Install the `galois` package with [dev]
-        run: python3 -m pip install .[dev]
+      - name: Install the dev requirements
+        run: python3 -m pip install -r requirements-dev.txt
 
-      - name: Format with black
-        run: python3 -m black . --check
+      - name: Install the `galois` package
+        run: python3 -m pip install .
+
+      - name: Format with ruff
+        run: python3 -m ruff format --check .
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..e6720e7b1
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,14 @@
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+  rev: v2.3.0
+  hooks:
+  - id: check-added-large-files
+  - id: check-yaml
+  - id: check-toml
+  - id: end-of-file-fixer
+  - id: trailing-whitespace
+- repo: https://github.com/astral-sh/ruff-pre-commit
+  rev: v0.1.4
+  hooks:
+  - id: ruff
+  - id: ruff-format
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4511572b0..f8611a6fa 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,20 +1,20 @@
 {
+    "python.testing.pytestEnabled": true,
     "python.testing.pytestArgs": [
         "-c=pyproject.toml",
         "tests/"
     ],
     "python.testing.unittestEnabled": false,
-    "python.testing.pytestEnabled": true,
-    "python.linting.pylintEnabled": true,
-    "python.linting.enabled": true,
-    "python.formatting.provider": "black",
-    "editor.formatOnSave": true,
+    "notebook.formatOnSave.enabled": true,
     "[python]": {
+        "editor.formatOnSave": true,
+        "editor.defaultFormatter": "charliermarsh.ruff",
         "editor.codeActionsOnSave": {
             "source.organizeImports": true
-        }
+        },
     },
+    "editor.formatOnSave": true,
     "editor.rulers": [
         120
-    ]
-}
\ No newline at end of file
+    ],
+}
diff --git a/README.md b/README.md
index 92d6b8101..b4d5877ef 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# ![Galois: A performant NumPy extension for Galois fields and their applications](https://raw.githubusercontent.com/mhostetter/galois/master/logo/galois-heading.png)
+# ![Galois: A performant NumPy extension for Galois fields and their applications](https://raw.githubusercontent.com/mhostetter/galois/main/logo/galois-heading.png)
 
 <div align=center>
   <a href="https://pypi.org/project/galois"><img src="https://img.shields.io/pypi/v/galois"></a>
@@ -14,7 +14,7 @@
   <a href="https://github.com/mhostetter/galois/actions/workflows/lint.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/lint.yaml/badge.svg"></a>
   <a href="https://github.com/mhostetter/galois/actions/workflows/build.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/build.yaml/badge.svg"></a>
   <a href="https://github.com/mhostetter/galois/actions/workflows/test.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/test.yaml/badge.svg"></a>
-  <a href="https://codecov.io/gh/mhostetter/galois"><img src="https://codecov.io/gh/mhostetter/galois/branch/master/graph/badge.svg?token=3FJML79ZUK"></a>
+  <a href="https://codecov.io/gh/mhostetter/galois"><img src="https://codecov.io/gh/mhostetter/galois/branch/main/graph/badge.svg?token=3FJML79ZUK"></a>
 </div>
 
 The `galois` library is a Python 3 package that extends NumPy arrays to operate over finite fields.
@@ -78,7 +78,7 @@ Import the `galois` package in Python.
 In [1]: import galois
 
 In [2]: galois.__version__
-Out[2]: '0.3.6'
+Out[2]: '0.3.7'
 ```
 
 ### Create a [`FieldArray`](https://mhostetter.github.io/galois/latest/api/galois.FieldArray/) subclass
@@ -165,7 +165,7 @@ In [12]: x
 Out[12]: GF([236,  87,  38, 112], order=3^5)
 
 In [13]: GF.repr("poly"); x
-Out[13]: 
+Out[13]:
 GF([2α^4 + 2α^3 + 2α^2 + 2,               α^4 + 2α,
              α^3 + α^2 + 2,      α^4 + α^3 + α + 1], order=3^5)
 
diff --git a/docs/_static/extra.css b/docs/_static/extra.css
index 8ab1bd937..4a07a35ae 100644
--- a/docs/_static/extra.css
+++ b/docs/_static/extra.css
@@ -9,17 +9,20 @@
   --md-primary-fg-color: #EAA915;
   --md-accent-fg-color: #EEBA44;
 }
+
 [data-md-color-scheme="slate"] .md-header {
   background-color: #344FA1;
 }
+
 [data-md-color-scheme="slate"] .md-tabs {
   background-color: #344FA1;
 }
 
 /* @media screen and (max-width: 76.1875em) */
 .md-nav--primary .md-nav__title[for=__drawer] {
-    background-color: #344FA1;
+  background-color: #344FA1;
 }
+
 .md-source {
   background-color: #344FA1;
 }
@@ -39,6 +42,7 @@
 .sig-param a.reference span .pre {
   color: var(--md-code-hl-generic-color);
 }
+
 .sig-param a.reference span .pre:hover {
   color: var(--md-accent-fg-color);
 }
diff --git a/docs/_templates/base.html b/docs/_templates/base.html
index 0985eb37e..085fd392e 100644
--- a/docs/_templates/base.html
+++ b/docs/_templates/base.html
@@ -14,4 +14,4 @@
 <a href="{{ '../' ~ base_url}}">
   <strong>Click here to go to latest.</strong>
 </a>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/docs/basic-usage/element-representation.rst b/docs/basic-usage/element-representation.rst
index 56984cfd5..771f1d1dd 100644
--- a/docs/basic-usage/element-representation.rst
+++ b/docs/basic-usage/element-representation.rst
@@ -67,7 +67,7 @@ In prime fields, the integer representation is simply the integer element in $\{
     GF = galois.GF(31)
     GF(11)
 
-In extension fields, the integer representation converts and element's degree-$m-1$ polynomial over $\mathrm{GF}(p)$ into
+In extension fields, the integer representation converts an element's degree-$m-1$ polynomial over $\mathrm{GF}(p)$ into
 its integer equivalent. The integer equivalent of a polynomial is a radix-$p$ integer of its coefficients, with the highest-degree
 coefficient as the most-significant digit and zero-degree coefficient as the least-significant digit.
 
diff --git a/docs/conf.py b/docs/conf.py
index c7aa8e6d9..5afaf3d3f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -13,6 +13,7 @@
 
 import inspect
 import os
+import re
 import sys
 
 sys.path.insert(0, os.path.abspath("."))
@@ -440,7 +441,8 @@ def modify_type_hints(signature):
     See https://github.com/jbms/sphinx-immaterial/issues/161
     """
     if signature:
-        signature = signature.replace("np", "~numpy")
+        signature = re.sub(r"(?<!~)np\.", "~numpy.", signature)
+        signature = re.sub(r"(?<!~)galois\.", "~galois.", signature)
     return signature
 
 
diff --git a/docs/development/formatting.rst b/docs/development/formatting.rst
new file mode 100644
index 000000000..7f0dc4566
--- /dev/null
+++ b/docs/development/formatting.rst
@@ -0,0 +1,77 @@
+Formatting
+==========
+
+The :obj:`galois` library uses `Ruff <https://docs.astral.sh/ruff/>`_ for static analysis, linting, and code
+formatting.
+
+Install
+-------
+
+First, `ruff` needs to be installed on your system. Easily install it by installing the development dependencies.
+
+.. code-block:: console
+
+   $ python3 -m pip install -r requirements-dev.txt
+
+Configuration
+-------------
+
+The `ruff` configuration is provided in `pyproject.toml`.
+
+.. literalinclude:: ../../pyproject.toml
+   :caption: pyproject.toml
+   :start-at: [tool.ruff]
+   :end-before: [tool.pytest.ini_options]
+   :language: toml
+
+Run the linter
+--------------
+
+Run the Ruff linter manually from the command line.
+
+.. code-block:: console
+
+   $ python3 -m ruff check .
+
+Run the formatter
+-----------------
+
+Run the Ruff formatter manually from the command line.
+
+.. code-block:: console
+
+   $ python3 -m ruff format --check .
+
+Pre-commit
+----------
+
+A `pre-commit` configuration file with various hooks is provided in `.pre-commit-config.yaml`.
+
+.. literalinclude:: ../../.pre-commit-config.yaml
+   :caption: .pre-commit-config.yaml
+   :language: yaml
+
+Enable `pre-commit` by installing the pre-commit hooks.
+
+.. code-block:: console
+
+   $ pre-commit install
+
+Run `pre-commit` on all files.
+
+.. code-block:: console
+
+   $ pre-commit run --all-files
+
+Disable `pre-commit` by uninstalling the pre-commit hooks.
+
+.. code-block:: console
+
+   $ pre-commit uninstall
+
+Run from VS Code
+----------------
+
+Install the `Ruff extension <https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff>`_ for VS Code.
+Included is a VS Code configuration file `.vscode/settings.json`.
+VS Code will run the linter and formatter as you view and edit files.
diff --git a/docs/development/installation.rst b/docs/development/installation.rst
index 9ad003006..5adcba597 100644
--- a/docs/development/installation.rst
+++ b/docs/development/installation.rst
@@ -13,7 +13,7 @@ The latest released version of :obj:`galois` can be installed from `PyPI <https:
 Install from GitHub
 -------------------
 
-The latest code on `master` can be installed using `pip` in this way.
+The latest code on `main` can be installed using `pip` in this way.
 
 .. code-block:: console
 
@@ -46,17 +46,14 @@ Install the local folder using the `-e` or `--editable` flag.
 Install the `dev` dependencies
 ------------------------------
 
-The development dependencies include packages for linting and unit testing. These dependencies are stored
-in `pyproject.toml`.
+The development dependencies include packages for linting and unit testing.
+These dependencies are stored in `requirements-dev.txt`.
 
-.. literalinclude:: ../../pyproject.toml
-   :caption: pyproject.toml
-   :start-at: [project.optional-dependencies]
-   :end-before: [project.urls]
-   :language: toml
+.. literalinclude:: ../../requirements-dev.txt
+   :caption: requirements-dev.txt
 
-Install the development dependencies by passing the `[dev]` extras to `pip install`.
+Install the development dependencies by passing `-r` to `pip install`.
 
 .. code-block:: console
 
-   $ python3 -m pip install galois[dev]
+   $ python3 -m pip install -r requirements-dev.txt
diff --git a/docs/development/linter.rst b/docs/development/linter.rst
deleted file mode 100644
index 14643a0f9..000000000
--- a/docs/development/linter.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-Linter
-======
-
-The :obj:`galois` library uses `pylint <https://pylint.org/>`_ for static analysis and code
-formatting.
-
-Install
--------
-
-First, `pylint` needs to be installed on your system. Easily install it by installing the development dependencies.
-
-.. code-block:: console
-
-   $ python3 -m pip install .[dev]
-
-Configuration
--------------
-
-Various nuisance `pylint` warnings are added to an ignore list in `pyproject.toml`.
-
-.. literalinclude:: ../../pyproject.toml
-   :caption: pyproject.toml
-   :start-at: [tool.pylint]
-   :end-before: [tool.pytest.ini_options]
-   :language: toml
-
-Run from the command line
--------------------------
-
-Run the linter manually from the command line.
-
-.. code-block:: console
-
-    $ python3 -m pylint src/galois/
-
-Run from VS Code
-----------------
-
-Included is a VS Code configuration file `.vscode/settings.json`. This instructs VS Code about how to invoke `pylint`.
-VS Code will run the linter as you view and edit files.
diff --git a/docs/index.rst b/docs/index.rst
index 2d01e8fc6..2c9dcbc87 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,6 +1,22 @@
 .. image:: ../logo/galois-heading.png
    :align: center
 
+.. raw:: html
+
+   <div align=center>
+      <a href="https://pypi.org/project/galois"><img src="https://img.shields.io/pypi/v/galois"></a>
+      <a href="https://pypi.org/project/galois"><img src="https://img.shields.io/pypi/pyversions/galois"></a>
+      <a href="https://pypi.org/project/galois"><img src="https://img.shields.io/pypi/wheel/galois"></a>
+      <a href="https://pypistats.org/packages/galois"><img src="https://img.shields.io/pypi/dm/galois"></a>
+      <a href="https://pypi.org/project/galois"><img src="https://img.shields.io/pypi/l/galois"></a>
+      <a href="https://twitter.com/galois_py"><img src="https://img.shields.io/static/v1?label=follow&message=@galois_py&color=blue&logo=twitter"></a>
+      <a href="https://github.com/mhostetter/galois/actions/workflows/docs.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/docs.yaml/badge.svg"></a>
+      <a href="https://github.com/mhostetter/galois/actions/workflows/lint.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/lint.yaml/badge.svg"></a>
+      <a href="https://github.com/mhostetter/galois/actions/workflows/build.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/build.yaml/badge.svg"></a>
+      <a href="https://github.com/mhostetter/galois/actions/workflows/test.yaml"><img src="https://github.com/mhostetter/galois/actions/workflows/test.yaml/badge.svg"></a>
+      <a href="https://codecov.io/gh/mhostetter/galois"><img src="https://codecov.io/gh/mhostetter/galois/branch/main/graph/badge.svg?token=3FJML79ZUK"></a>
+   </div>
+
 The :obj:`galois` library is a Python 3 package that extends NumPy arrays to operate over finite fields.
 
 The user creates a :obj:`~galois.FieldArray` subclass using `GF = galois.GF(p**m)`. `GF` is a subclass of :obj:`numpy.ndarray`
@@ -128,7 +144,7 @@ If this library was useful to you in your research, please cite us. Following th
    :hidden:
 
    development/installation.rst
-   development/linter.rst
+   development/formatting.rst
    development/unit-tests.rst
    development/documentation.rst
 
diff --git a/docs/performance/benchmarks.rst b/docs/performance/benchmarks.rst
index 8665920bb..1f87ee0b5 100644
--- a/docs/performance/benchmarks.rst
+++ b/docs/performance/benchmarks.rst
@@ -129,22 +129,22 @@ advised to pass extra arguments to format the display `--benchmark-columns=min,m
 Compare with a previous benchmark
 ---------------------------------
 
-If you would like to compare the performance impact of a branch, first run a benchmark on `master` using the `--benchmark-save` option.
+If you would like to compare the performance impact of a branch, first run a benchmark on `main` using the `--benchmark-save` option.
 This will save the file `.benchmarks/0001_master.json`.
 
 .. code-block:: console
 
-   $ git checkout master
-   $ python3 -m pytest benchmarks/test_field_arithmetic.py --benchmark-save=master --benchmark-columns=min,max,mean,stddev,median --benchmark-sort=name
+   $ git checkout main
+   $ python3 -m pytest benchmarks/test_field_arithmetic.py --benchmark-save=main --benchmark-columns=min,max,mean,stddev,median --benchmark-sort=name
 
-Next, run a benchmark on the branch under test while comparing against the benchmark from `master`.
+Next, run a benchmark on the branch under test while comparing against the benchmark from `main`.
 
 .. code-block:: console
 
    $ git checkout branch
    $ python3 -m pytest benchmarks/test_field_arithmetic.py --benchmark-compare=0001_master --benchmark-columns=min,max,mean,stddev,median --benchmark-sort=name
 
-Or, save a benchmark run from `branch` and compare it explicitly against the one from `master`. This benchmark run will save the file `.benchmarks/0001_branch.json`.
+Or, save a benchmark run from `branch` and compare it explicitly against the one from `main`. This benchmark run will save the file `.benchmarks/0001_branch.json`.
 
 .. code-block:: console
 
diff --git a/docs/release-notes/v0.2.md b/docs/release-notes/v0.2.md
index 80eff1b3d..b186925a5 100644
--- a/docs/release-notes/v0.2.md
+++ b/docs/release-notes/v0.2.md
@@ -27,7 +27,7 @@ tocdepth: 2
     >>> for d in range(3, 10):
     ...     bch = galois.BCH(5**2 - 1, d=d, field=GF)
     ...     print(repr(bch))
-    ... 
+    ...
     <BCH Code: [24, 20, 3] over GF(5)>
     <BCH Code: [24, 18, 4] over GF(5)>
     <BCH Code: [24, 16, 5] over GF(5)>
diff --git a/docs/release-notes/v0.3.md b/docs/release-notes/v0.3.md
index c1f9c93da..d26a4a597 100644
--- a/docs/release-notes/v0.3.md
+++ b/docs/release-notes/v0.3.md
@@ -110,11 +110,11 @@ tocdepth: 2
   This speeds up the creation of large finite fields. ([#452](https://github.com/mhostetter/galois/pull/452))
   ```ipython
   In [1]: import galois
-  
+
   # v0.3.1
   In [2]: %time galois.factors(2**256 - 1)
   # Took forever...
-  
+
   # v0.3.2
   In [2]: %time galois.factors(2**256 - 1)
   Wall time: 1 ms
@@ -135,12 +135,12 @@ tocdepth: 2
 - Added speed-up when factoring powers of small primes. This speeds up the creation of large finite fields. ([#454](https://github.com/mhostetter/galois/pull/454))
   ```ipython
   In [1]: import galois
-  
+
   # v0.3.1
   In [2]: %time galois.factors(2**471)
   Wall time: 4.18 s
   Out[2]: ([2], [471])
-  
+
   # v0.3.2
   In [2]: %time galois.factors(2**471)
   Wall time: 2 ms
@@ -177,13 +177,13 @@ tocdepth: 2
   `irreducible_poly()` when `terms="min"` and `method="min"`. ([#462](https://github.com/mhostetter/galois/pull/462))
   ```ipython
   In [1]: import galois
-  
+
   # Manual search
   In [2]: %time galois.irreducible_poly(2, 1001)
   CPU times: user 6.8 s, sys: 0 ns, total: 6.8 s
   Wall time: 6.81 s
   Out[2]: Poly(x^1001 + x^5 + x^3 + x + 1, GF(2))
-  
+
   # With the database
   In [3]: %time galois.irreducible_poly(2, 1001, terms="min")
   CPU times: user 745 µs, sys: 0 ns, total: 745 µs
@@ -194,15 +194,15 @@ tocdepth: 2
   calculations for a given polynomial is only incurred once. ([#470](https://github.com/mhostetter/galois/pull/470))
   ```ipython
   In [1]: import galois
-  
+
   In [2]: f = galois.Poly.Str("x^1001 + x^17 + 1"); f
   Out[2]: Poly(x^1001 + x^17 + 1, GF(2))
-  
+
   In [3]: %time f.is_irreducible()
   CPU times: user 1.05 s, sys: 3.47 ms, total: 1.05 s
   Wall time: 1.06 s
   Out[3]: True
-  
+
   In [4]: %time f.is_irreducible()
   CPU times: user 57 µs, sys: 30 µs, total: 87 µs
   Wall time: 68.2 µs
@@ -262,3 +262,19 @@ tocdepth: 2
 - Iyán Méndez Veiga ([@iyanmv](https://github.com/iyanmv))
 - [@Lasagnenator](https://github.com/Lasagnenator)
 - Matt Hostetter ([@mhostetter](https://github.com/mhostetter))
+
+## v0.3.7
+
+*Released November 30, 2023*
+
+### Changes
+
+- Added wheel factorization for finding large primes. ([#527](https://github.com/mhostetter/galois/pull/527))
+- Improved type annotations. ([#510](https://github.com/mhostetter/galois/pull/510), [#511](https://github.com/mhostetter/galois/pull/511))
+- Removed optional `[dev]` extra. If developing, install from `requirements-dev.txt`. ([#521](https://github.com/mhostetter/galois/pull/521))
+- Fixed bugs in `prev_prime()` and `next_prime()` for large primes. ([#527](https://github.com/mhostetter/galois/pull/527))
+
+### Contributors
+
+- [@avadov](https://github.com/avadov)
+- Matt Hostetter ([@mhostetter](https://github.com/mhostetter))
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 85884270f..0b7fb3192 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,7 +1,10 @@
-sphinx < 5.4
-sphinx-immaterial == 0.11.5
-myst-parser
-sphinx-design
-sphinx-last-updated-by-git
-sphinx-math-dollar
-ipykernel
+sphinx < 7.3
+sphinx-immaterial == 0.11.9
+# For some reason, if the below versions aren't specified, the dependency resolution takes 18 minutes in CI.
+myst-parser == 0.18.1
+sphinx-design  == 0.5.0
+sphinx-last-updated-by-git == 0.3.6
+sphinx-math-dollar == 1.2.1
+ipykernel == 6.26.0
+myst-nb == 0.17.2
+pickleshare == 0.7.5  # Needed by ipykernel
diff --git a/pyproject.toml b/pyproject.toml
index 9cc952097..ff9c6206c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -55,17 +55,7 @@ dependencies = [
 ]
 dynamic = ["version"]
 
-[project.optional-dependencies]
-dev = [
-    "pylint >= 2.14",
-    "black >= 22.8.0",
-    "pytest",
-    "pytest-cov[toml]",
-    "pytest-xdist",
-    "pytest-benchmark >= 4.0.0",
-    "requests",
-    "pdfminer.six",
-]
+# [project.optional-dependencies]
 
 [project.urls]
 Homepage = "https://github.com/mhostetter/galois"
@@ -89,39 +79,25 @@ where = ["src"]
 [tool.distutils.bdist_wheel]
 universal = false
 
-[tool.pylint]
-ignore-paths = ["src/galois/_version.py"]
-disable = [
-    "comparison-with-callable",     # pylint doesn't understand metaclass properties
-    "fixme",
-    "global-statement",
-    "invalid-name",
-    "missing-function-docstring",
-    "protected-access",
-    "too-many-ancestors",
-    "too-many-arguments",
-    "too-many-branches",
-    "too-many-instance-attributes",
-    "too-many-lines",
-    "too-many-locals",
-    "unneeded-not",
-]
-min-similarity-lines = 100
-max-line-length = 120
-
-[tool.black]
+[tool.ruff]
+src = ["src"]
+extend-include = ["*.ipynb"]
+extend-exclude = ["build", "dist", "docs", "src/galois/_version.py"]
 line-length = 120
-exclude = '''
-/(
-      build
-)/
-    | src/galois/_version.py
-'''
-# NOTE: You must use single-quoted strings in TOML for regular expressions. It's the equivalent of r-strings in Python.
-# For some reason, this exclude line doesn't work when on a single line.
 
-[tool.isort]
-profile = "black"
+[tool.ruff.lint]
+select = [
+    "E",  # pycodestyle
+    "F",  # Pyflakes
+    "UP", # pyupgrade
+    "B",  # flake8-bugbear
+    # "SIM",# flake8-simplify
+    "I", # isort
+]
+ignore = ["E501", "E713", "E714", "E741"]
+
+[tool.ruff.lint.per-file-ignores]
+"__init__.py" = ["F401", "F403"]
 
 [tool.pytest.ini_options]
 minversion = "6.2"
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 000000000..ad5b14f2a
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,7 @@
+ruff == 0.1.4
+pytest
+pytest-cov[toml]
+pytest-xdist
+pytest-benchmark >= 4.0.0
+requests
+pdfminer.six
diff --git a/scripts/create_conway_polys_database.py b/scripts/create_conway_polys_database.py
index ae9643c05..49ff425f9 100644
--- a/scripts/create_conway_polys_database.py
+++ b/scripts/create_conway_polys_database.py
@@ -38,7 +38,7 @@ def main():
         degree = int(items[1])
 
         # Degree-descending coefficients
-        coeffs = np.array(eval(items[2])[::-1])  # pylint: disable=eval-used
+        coeffs = np.array(eval(items[2])[::-1])
 
         idxs = np.nonzero(coeffs)[0]
         nonzero_degrees = (degree - idxs).tolist()
diff --git a/scripts/create_irreducible_polys_database.py b/scripts/create_irreducible_polys_database.py
index 44e8b9045..d86427b5a 100644
--- a/scripts/create_irreducible_polys_database.py
+++ b/scripts/create_irreducible_polys_database.py
@@ -7,13 +7,13 @@
 """
 from __future__ import annotations
 
+import hashlib
+import io
 import os
 import sqlite3
 from pathlib import Path
 
 import requests
-import hashlib
-import io
 from pdfminer.high_level import extract_text
 
 
diff --git a/src/galois/__init__.py b/src/galois/__init__.py
index 54c61aee1..4c2dbeeac 100644
--- a/src/galois/__init__.py
+++ b/src/galois/__init__.py
@@ -1,7 +1,7 @@
 """
 A performant NumPy extension for Galois fields and their applications.
 """
-# pylint: disable=wrong-import-position
+# ruff: noqa: F405, E402
 # isort: skip_file
 
 try:
@@ -13,9 +13,11 @@
     __version_tuple__ = (0, 0, 0)
     warnings.warn(
         "An error occurred during package install where setuptools_scm failed to create a _version.py file."
-        "Defaulting version to 0.0.0."
+        "Defaulting version to 0.0.0.",
+        stacklevel=3,
     )
 
+
 # Import class/functions from nested private modules
 from ._domains import *
 from ._polys import *  # Needs to be imported before _fields
diff --git a/src/galois/_codes/_bch.py b/src/galois/_codes/_bch.py
index 4df4cffe7..c8f5920e2 100644
--- a/src/galois/_codes/_bch.py
+++ b/src/galois/_codes/_bch.py
@@ -3,7 +3,7 @@
 """
 from __future__ import annotations
 
-from typing import Type, overload
+from typing import overload
 
 import numba
 import numpy as np
@@ -77,15 +77,14 @@ class BCH(_CyclicCode):
     Group:
         fec
     """
-    # pylint: disable=no-member
 
     def __init__(
         self,
         n: int,
         k: int | None = None,
         d: int | None = None,
-        field: Type[FieldArray] | None = None,
-        extension_field: Type[FieldArray] | None = None,
+        field: type[FieldArray] | None = None,
+        extension_field: type[FieldArray] | None = None,
         alpha: ElementLike | None = None,
         c: int = 1,
         systematic: bool = True,
@@ -474,7 +473,6 @@ def encode(self, message: ArrayLike, output: Literal["codeword", "parity"] = "co
         """,
     )
     def detect(self, codeword: ArrayLike) -> bool | np.ndarray:
-        # pylint: disable=useless-super-delegation
         return super().detect(codeword)
 
     @overload
@@ -685,11 +683,11 @@ def _decode_codeword(self, codeword: FieldArray) -> tuple[FieldArray, np.ndarray
                 print(bch.field.properties)
         """,
     )
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         return super().field
 
     @property
-    def extension_field(self) -> Type[FieldArray]:
+    def extension_field(self) -> type[FieldArray]:
         r"""
         The Galois field $\mathrm{GF}(q^m)$ that defines the BCH syndrome arithmetic.
 
@@ -1113,7 +1111,7 @@ def is_systematic(self) -> bool:
 
 def _generator_poly_from_d(
     d: int,
-    field: Type[FieldArray],
+    field: type[FieldArray],
     alpha: FieldArray,
     c: int,
 ) -> tuple[Poly, FieldArray]:
@@ -1136,8 +1134,8 @@ def _generator_poly_from_d(
 def _generator_poly_from_k(
     n: int,
     k: int,
-    field: Type[FieldArray],
-    extension_field: Type[FieldArray],
+    field: type[FieldArray],
+    extension_field: type[FieldArray],
     alpha: FieldArray,
     c: int,
 ) -> tuple[Poly, FieldArray]:
@@ -1196,7 +1194,7 @@ class bch_decode_jit(Function):
         - Lin, S. and Costello, D. Error Control Coding. Section 7.4.
     """
 
-    def __init__(self, field: Type[FieldArray], extension_field: Type[FieldArray]):
+    def __init__(self, field: type[FieldArray], extension_field: type[FieldArray]):
         super().__init__(field)
         self.extension_field = extension_field
 
@@ -1225,7 +1223,6 @@ def __call__(self, codeword, design_n, alpha, c, roots):
         return dec_codeword, N_errors
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global CHARACTERISTIC, SUBTRACT, MULTIPLY, RECIPROCAL, POWER
         global CONVOLVE, POLY_ROOTS, POLY_EVALUATE, BERLEKAMP_MASSEY
 
diff --git a/src/galois/_codes/_cyclic.py b/src/galois/_codes/_cyclic.py
index a76281e91..f9ab04c67 100644
--- a/src/galois/_codes/_cyclic.py
+++ b/src/galois/_codes/_cyclic.py
@@ -21,8 +21,6 @@ class _CyclicCode(_LinearCode):
     A FEC base class for cyclic codes.
     """
 
-    # pylint: disable=abstract-method
-
     def __init__(
         self,
         n: int,
diff --git a/src/galois/_codes/_linear.py b/src/galois/_codes/_linear.py
index 39b93bcd6..91e4de64a 100644
--- a/src/galois/_codes/_linear.py
+++ b/src/galois/_codes/_linear.py
@@ -3,7 +3,7 @@
 """
 from __future__ import annotations
 
-from typing import Type, overload
+from typing import overload
 
 import numpy as np
 from typing_extensions import Literal
@@ -302,7 +302,7 @@ def _decode_codeword(self, codeword: FieldArray) -> tuple[FieldArray, np.ndarray
     ###############################################################################
 
     @property
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         r"""
         The Galois field $\mathrm{GF}(q)$ that defines the codeword alphabet.
         """
diff --git a/src/galois/_codes/_reed_solomon.py b/src/galois/_codes/_reed_solomon.py
index 25740972d..44503f5f6 100644
--- a/src/galois/_codes/_reed_solomon.py
+++ b/src/galois/_codes/_reed_solomon.py
@@ -3,7 +3,7 @@
 """
 from __future__ import annotations
 
-from typing import Type, overload
+from typing import overload
 
 import numpy as np
 from typing_extensions import Literal
@@ -73,14 +73,13 @@ class ReedSolomon(_CyclicCode):
     Group:
         fec
     """
-    # pylint: disable=no-member
 
     def __init__(
         self,
         n: int,
         k: int | None = None,
         d: int | None = None,
-        field: Type[FieldArray] | None = None,
+        field: type[FieldArray] | None = None,
         alpha: ElementLike | None = None,
         c: int = 1,
         systematic: bool = True,
@@ -430,7 +429,6 @@ def encode(self, message: ArrayLike, output: Literal["codeword", "parity"] = "co
         """,
     )
     def detect(self, codeword: ArrayLike) -> bool | np.ndarray:
-        # pylint: disable=useless-super-delegation
         return super().detect(codeword)
 
     @overload
@@ -637,7 +635,7 @@ def _decode_codeword(self, codeword: FieldArray) -> tuple[FieldArray, np.ndarray
                 print(rs.field.properties)
         """,
     )
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         return super().field
 
     @extend_docstring(
diff --git a/src/galois/_databases/_interface.py b/src/galois/_databases/_interface.py
index a9696338c..699545d48 100644
--- a/src/galois/_databases/_interface.py
+++ b/src/galois/_databases/_interface.py
@@ -3,12 +3,10 @@
 """
 from __future__ import annotations
 
-import sys
 import sqlite3
+import sys
 from pathlib import Path
 
-# pylint: disable=too-few-public-methods
-
 
 class DatabaseInterface:
     """
diff --git a/src/galois/_domains/_array.py b/src/galois/_domains/_array.py
index 108330272..897f0f916 100644
--- a/src/galois/_domains/_array.py
+++ b/src/galois/_domains/_array.py
@@ -9,6 +9,7 @@
 from typing import Generator
 
 import numpy as np
+import numpy.typing as npt
 from typing_extensions import Literal, Self
 
 from .._helper import export, verify_isinstance, verify_literal
@@ -446,3 +447,97 @@ def astype(self, dtype, order="K", casting="unsafe", subok=True, copy=True):
                 f"{type(self)._name} arrays can only be cast as integer dtypes in {type(self)._dtypes}, not {dtype}."
             )
         return super().astype(dtype, order=order, casting=casting, subok=subok, copy=copy)
+
+    ###############################################################################
+    # Override arithmetic operators so type checking is appeased
+    ###############################################################################
+
+    def __add__(self, other: npt.NDArray) -> Self:
+        return super().__add__(other)
+
+    def __iadd__(self, other: npt.NDArray) -> Self:
+        return super().__iadd__(other)
+
+    def __radd__(self, other: npt.NDArray) -> Self:
+        return super().__radd__(other)
+
+    def __sub__(self, other: npt.NDArray) -> Self:
+        return super().__sub__(other)
+
+    def __isub__(self, other: npt.NDArray) -> Self:
+        return super().__isub__(other)
+
+    def __rsub__(self, other: npt.NDArray) -> Self:
+        return super().__rsub__(other)
+
+    def __mul__(self, other: int | npt.NDArray) -> Self:
+        return super().__mul__(other)
+
+    def __imul__(self, other: int | npt.NDArray) -> Self:
+        return super().__imul__(other)
+
+    def __rmul__(self, other: int | npt.NDArray) -> Self:
+        return super().__rmul__(other)
+
+    def __truediv__(self, other: npt.NDArray) -> Self:
+        return super().__truediv__(other)
+
+    def __itruediv__(self, other: npt.NDArray) -> Self:
+        return super().__itruediv__(other)
+
+    def __rtruediv__(self, other: npt.NDArray) -> Self:
+        return super().__rtruediv__(other)
+
+    def __floordiv__(self, other: npt.NDArray) -> Self:
+        return super().__floordiv__(other)
+
+    def __ifloordiv__(self, other: npt.NDArray) -> Self:
+        return super().__ifloordiv__(other)
+
+    def __rfloordiv__(self, other: npt.NDArray) -> Self:
+        return super().__rfloordiv__(other)
+
+    def __neg__(self) -> Self:
+        return super().__neg__()
+
+    def __mod__(self, other: npt.NDArray) -> Self:
+        return super().__mod__(other)
+
+    def __imod__(self, other: npt.NDArray) -> Self:
+        return super().__imod__(other)
+
+    def __rmod__(self, other: npt.NDArray) -> Self:
+        return super().__rmod__(other)
+
+    def __pow__(self, other: int | npt.NDArray) -> Self:
+        return super().__pow__(other)
+
+    def __ipow__(self, other: int | npt.NDArray) -> Self:
+        return super().__ipow__(other)
+
+    # def __rpow__(self, other) -> Self:
+    #     return super().__rpow__(other)
+
+    def __matmul__(self, other: npt.NDArray) -> Self:
+        return super().__matmul__(other)
+
+    def __rmatmul__(self, other: npt.NDArray) -> Self:
+        return super().__rmatmul__(other)
+
+    def __lshift__(self, other: int | npt.NDArray) -> Self:
+        return super().__lshift__(other)
+
+    def __ilshift__(self, other: int | npt.NDArray) -> Self:
+        return super().__ilshift__(other)
+
+    # def __rlshift__(self, other) -> Self:
+    #     return super().__rlshift__(other)
+
+    def __rshift__(self, other: int | npt.NDArray) -> Self:
+        return super().__rshift__(other)
+
+    def __irshift__(self, other: int | npt.NDArray) -> Self:
+        return super().__irshift__(other)
+
+    # def __rrshift__(self, other) -> Self:
+    #     return super().__rrshift__(other)
diff --git a/src/galois/_domains/_calculate.py b/src/galois/_domains/_calculate.py
index 5e1c74461..43f42e895 100644
--- a/src/galois/_domains/_calculate.py
+++ b/src/galois/_domains/_calculate.py
@@ -11,9 +11,6 @@
 from . import _lookup
 from ._array import Array
 
-# pylint: disable=global-variable-undefined
-
-
 ###############################################################################
 # Helper JIT functions
 ###############################################################################
diff --git a/src/galois/_domains/_factory.py b/src/galois/_domains/_factory.py
index 3e953836e..ff07af27e 100644
--- a/src/galois/_domains/_factory.py
+++ b/src/galois/_domains/_factory.py
@@ -11,7 +11,6 @@ def FIELD_FACTORY(*args, **kwargs) -> Type[Array]:  # pragma: no cover
     """
     This will be monkey-patched to be `galois.GF()` in galois/__init__.py.
     """
-    # pylint: disable=unused-argument
     return Array
 
 
diff --git a/src/galois/_domains/_function.py b/src/galois/_domains/_function.py
index 29137591b..d0a9d058e 100644
--- a/src/galois/_domains/_function.py
+++ b/src/galois/_domains/_function.py
@@ -4,7 +4,7 @@
 """
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Callable, Type
+from typing import TYPE_CHECKING, Callable
 
 import numba
 import numpy as np
@@ -16,8 +16,6 @@
 if TYPE_CHECKING:
     from ._array import Array
 
-# pylint: disable=global-variable-undefined
-
 
 class Function:
     """
@@ -27,7 +25,7 @@ class Function:
 
     _CACHE = {}  # A cache of compiled functions
 
-    def __init__(self, field: Type[Array]):
+    def __init__(self, field: type[Array]):
         self.field = field
 
     def __call__(self):
@@ -145,7 +143,7 @@ def implementation(a, b):
                 max_sum = np.iinfo(dtype).max // (CHARACTERISTIC - 1) ** 2
                 n_sum = min(a.size, b.size)
                 overflow = n_sum > max_sum
-            except:  # pylint: disable=bare-except
+            except:  # noqa: E722
                 # This happens when the dtype is np.object_
                 overflow = False
 
@@ -185,7 +183,7 @@ def __call__(self, x: Array, n=None, axis=-1, norm=None) -> Array:
             n = x.size
         x = np.append(x, np.zeros(n - x.size, dtype=x.dtype))
 
-        omega = self.field.primitive_root_of_unity(x.size)  # pylint: disable=no-member
+        omega = self.field.primitive_root_of_unity(x.size)
         if self._direction == "backward":
             omega = omega**-1
 
@@ -220,8 +218,8 @@ def implementation(x, omega):  # pragma: no cover
         elif N % 2 == 0:
             # Radix-2 Cooley-Tukey FFT
             omega2 = MULTIPLY(omega, omega)
-            EVEN = implementation(x[0::2], omega2)  # pylint: disable=undefined-variable
-            ODD = implementation(x[1::2], omega2)  # pylint: disable=undefined-variable
+            EVEN = implementation(x[0::2], omega2)  # noqa: F821
+            ODD = implementation(x[1::2], omega2)  # noqa: F821
 
             twiddle = 1
             for k in range(0, N // 2):
@@ -256,8 +254,8 @@ def implementation_2(x, omega):
         elif N % 2 == 0:
             # Radix-2 Cooley-Tukey FFT
             omega2 = MULTIPLY(omega, omega)
-            EVEN = fft_jit.implementation_2(x[0::2], omega2)  # pylint: disable=undefined-variable
-            ODD = fft_jit.implementation_2(x[1::2], omega2)  # pylint: disable=undefined-variable
+            EVEN = fft_jit.implementation_2(x[0::2], omega2)
+            ODD = fft_jit.implementation_2(x[1::2], omega2)
 
             twiddle = 1
             for k in range(0, N // 2):
@@ -371,7 +369,7 @@ def __array_function__(self, func, types, args, kwargs):
                 args[2] = self._verify_array_like_types_and_values(args[2])
                 args = tuple(args)
 
-            output = super().__array_function__(func, types, args, kwargs)  # pylint: disable=no-member
+            output = super().__array_function__(func, types, args, kwargs)
 
             if func in field._FUNCTIONS_REQUIRING_VIEW:
                 output = field._view(output) if not np.isscalar(output) else field(output, dtype=self.dtype)
diff --git a/src/galois/_domains/_linalg.py b/src/galois/_domains/_linalg.py
index ed7bf79cd..ea454a2aa 100644
--- a/src/galois/_domains/_linalg.py
+++ b/src/galois/_domains/_linalg.py
@@ -4,7 +4,7 @@
 """
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Type
+from typing import TYPE_CHECKING
 
 import numba
 import numpy as np
@@ -18,7 +18,7 @@
     from ._array import Array
 
 
-def _lapack_linalg(field: Type[Array], a: Array, b: Array, function, out=None, n_sum=None) -> Array:
+def _lapack_linalg(field: type[Array], a: Array, b: Array, function, out=None, n_sum=None) -> Array:
     """
     In prime fields GF(p), it's much more efficient to use LAPACK/BLAS implementations of linear algebra
     and then reduce modulo p rather than compute manually.
@@ -172,7 +172,7 @@ class matmul_jit(Function):
         - https://numpy.org/doc/stable/reference/generated/numpy.matmul.html#numpy.matmul
     """
 
-    def __call__(self, A: Array, B: Array, out=None, **kwargs) -> Array:  # pylint: disable=unused-argument
+    def __call__(self, A: Array, B: Array, out=None, **kwargs) -> Array:
         verify_isinstance(A, self.field)
         verify_isinstance(B, self.field)
         if not (A.ndim >= 1 and B.ndim >= 1):
@@ -233,7 +233,6 @@ def __call__(self, A: Array, B: Array, out=None, **kwargs) -> Array:  # pylint:
         return C
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD, MULTIPLY
         ADD = self.field._add.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -249,8 +248,8 @@ def implementation(A, B):
         M, K = A.shape
         K, N = B.shape
         C = np.zeros((M, N), dtype=A.dtype)
-        for i in numba.prange(M):  # pylint: disable=not-an-iterable
-            for j in numba.prange(N):  # pylint: disable=not-an-iterable
+        for i in numba.prange(M):
+            for j in numba.prange(N):
                 for k in range(K):
                     C[i, j] = ADD(C[i, j], MULTIPLY(A[i, k], B[k, j]))
 
@@ -318,7 +317,7 @@ def __call__(self, A: Array) -> tuple[Array, Array]:
         for i in range(0, m - 1):
             if Ai[i, i] == 0:
                 idxs = np.nonzero(Ai[i:, i])[0]  # The first non-zero entry in column `i` below row `i`
-                if idxs.size == 0:  # pylint: disable=no-else-continue
+                if idxs.size == 0:
                     L[i, i] = 1
                     continue
                 else:
diff --git a/src/galois/_domains/_lookup.py b/src/galois/_domains/_lookup.py
index 4e5db909b..1c6606f1b 100644
--- a/src/galois/_domains/_lookup.py
+++ b/src/galois/_domains/_lookup.py
@@ -21,7 +21,6 @@ class add_ufunc(_ufunc.add_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global EXP, LOG, ZECH_LOG, ZECH_E
         EXP = self.field._EXP
         LOG = self.field._LOG
@@ -66,7 +65,6 @@ class negative_ufunc(_ufunc.negative_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global EXP, LOG, ZECH_E
         EXP = self.field._EXP
         LOG = self.field._LOG
@@ -96,7 +94,6 @@ class subtract_ufunc(_ufunc.subtract_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global ORDER, EXP, LOG, ZECH_LOG, ZECH_E
         ORDER = self.field.order
         EXP = self.field._EXP
@@ -148,7 +145,6 @@ class multiply_ufunc(_ufunc.multiply_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global EXP, LOG
         EXP = self.field._EXP
         LOG = self.field._LOG
@@ -177,7 +173,6 @@ class reciprocal_ufunc(_ufunc.reciprocal_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global ORDER, EXP, LOG
         ORDER = self.field.order
         EXP = self.field._EXP
@@ -208,7 +203,6 @@ class divide_ufunc(_ufunc.divide_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global ORDER, EXP, LOG
         ORDER = self.field.order
         EXP = self.field._EXP
@@ -244,7 +238,6 @@ class power_ufunc(_ufunc.power_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global ORDER, EXP, LOG
         ORDER = self.field.order
         EXP = self.field._EXP
@@ -282,7 +275,6 @@ class log_ufunc(_ufunc.log_ufunc):
     """
 
     def set_lookup_globals(self):
-        # pylint: disable=global-variable-undefined
         global LOG
         LOG = self.field._LOG
 
@@ -295,7 +287,6 @@ def lookup(a: int, b: int) -> int:  # pragma: no cover
         log(a, b) = log(b^m, b)
                   = c
         """
-        # pylint: disable=unused-argument
         if a == 0:
             raise ArithmeticError("Cannot compute the discrete logarithm of 0 in a Galois field.")
 
diff --git a/src/galois/_domains/_meta.py b/src/galois/_domains/_meta.py
index e8aa737c4..a74e8f4ea 100644
--- a/src/galois/_domains/_meta.py
+++ b/src/galois/_domains/_meta.py
@@ -23,9 +23,7 @@ class ArrayMeta(abc.ABCMeta):
     A metaclass that provides class properties for `Array` subclasses.
     """
 
-    # pylint: disable=no-value-for-parameter
-
-    def __new__(mcs, name, bases, namespace, **kwargs):  # pylint: disable=unused-argument
+    def __new__(mcs, name, bases, namespace, **kwargs):
         return super().__new__(mcs, name, bases, namespace)
 
     def __init__(cls, name, bases, namespace, **kwargs):
diff --git a/src/galois/_domains/_ufunc.py b/src/galois/_domains/_ufunc.py
index e0a21c6e3..bec89c549 100644
--- a/src/galois/_domains/_ufunc.py
+++ b/src/galois/_domains/_ufunc.py
@@ -8,7 +8,7 @@
 """
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Callable, Type
+from typing import TYPE_CHECKING, Callable
 
 import numba
 import numpy as np
@@ -32,7 +32,7 @@ class UFunc:
     _CACHE_CALCULATE = {}  # A cache of compiled ufuncs using explicit calculation
     _CACHE_LOOKUP = {}  # A cache of compiled ufuncs using lookup tables
 
-    def __init__(self, field: Type[Array], override=None, always_calculate=False):
+    def __init__(self, field: type[Array], override=None, always_calculate=False):
         self.field = field
         self.override = override  # A NumPy ufunc used instead of a custom one
         self.always_calculate = always_calculate  # Indicates to never use lookup tables for this ufunc
@@ -270,7 +270,7 @@ def _verify_operands_first_field_second_int(self, ufunc, inputs, meta):
 
     def _convert_inputs_to_vector(self, inputs, kwargs):
         v_inputs = list(inputs)
-        for i in range(len(inputs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(inputs)):
             if issubclass(type(inputs[i]), self.field):
                 v_inputs[i] = inputs[i].vector()
 
@@ -301,7 +301,7 @@ def _convert_output_from_vector(self, output, dtype):
     def _view_inputs_as_ndarray(self, inputs, kwargs, dtype=None):
         # View all inputs that are FieldArrays as np.ndarray to avoid infinite recursion
         v_inputs = list(inputs)
-        for i in range(len(inputs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(inputs)):
             if issubclass(type(inputs[i]), self.field):
                 v_inputs[i] = inputs[i].view(np.ndarray) if dtype is None else inputs[i].view(np.ndarray).astype(dtype)
 
@@ -428,7 +428,7 @@ def __call__(self, ufunc, method, inputs, kwargs, meta):
         if method == "__call__":
             # When dividing two arrays, instead multiply by the reciprocal. This is vastly
             # more efficient when the denominator is a scalar or smaller (broadcasted) array.
-            inputs[1] = getattr(self.field._reciprocal.ufunc, "__call__")(inputs[1])
+            inputs[1] = self.field._reciprocal.ufunc(inputs[1])
             output = getattr(self.field._multiply.ufunc, method)(*inputs, **kwargs)
         else:
             output = getattr(self.ufunc, method)(*inputs, **kwargs)
@@ -510,7 +510,7 @@ class log_ufunc(UFunc):
 
     type = "binary"
 
-    def __call__(self, ufunc, method, inputs, kwargs, meta):  # pylint: disable=unused-argument
+    def __call__(self, ufunc, method, inputs, kwargs, meta):
         self._verify_method_only_call(ufunc, method)
         inputs = list(inputs) + [int(self.field.primitive_element)]
         inputs, kwargs = self._view_inputs_as_ndarray(inputs, kwargs)
@@ -525,7 +525,7 @@ class sqrt_ufunc(UFunc):
 
     type = "unary"
 
-    def __call__(self, ufunc, method, inputs, kwargs, meta):  # pylint: disable=unused-argument
+    def __call__(self, ufunc, method, inputs, kwargs, meta):
         self._verify_method_only_call(ufunc, method)
         return self.implementation(*inputs)
 
@@ -543,7 +543,7 @@ class matmul_ufunc(UFunc):
 
     type = "binary"
 
-    def __call__(self, ufunc, method, inputs, kwargs, meta):  # pylint: disable=unused-argument
+    def __call__(self, ufunc, method, inputs, kwargs, meta):
         self._verify_method_only_call(ufunc, method)
         return matmul_jit(self.field)(*inputs, **kwargs)
 
@@ -698,7 +698,7 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
             kwargs["casting"] = "unsafe"
 
         inputs, kwargs = UFunc(field)._view_inputs_as_ndarray(inputs, kwargs)
-        output = super().__array_ufunc__(ufunc, method, *inputs, **kwargs)  # pylint: disable=no-member
+        output = super().__array_ufunc__(ufunc, method, *inputs, **kwargs)
 
         if ufunc in field._UFUNCS_REQUIRING_VIEW and output is not None:
             output = field._view(output) if not np.isscalar(output) else field(output, dtype=self.dtype)
diff --git a/src/galois/_fields/_array.py b/src/galois/_fields/_array.py
index 8b7bf5e5c..2b978dc36 100644
--- a/src/galois/_fields/_array.py
+++ b/src/galois/_fields/_array.py
@@ -51,7 +51,6 @@ class FieldArray(Array, metaclass=FieldArrayMeta):
     Group:
         galois-fields
     """
-    # pylint: disable=no-value-for-parameter,abstract-method,too-many-public-methods
 
     def __new__(
         cls,
@@ -116,7 +115,6 @@ def __init__(
                 GF([["x^2 + 2x + 2", 4], ["x^4 + 2x^3 + x^2 + x + 1", 205]])
                 alpha ** np.array([[222, 69], [54, 24]])
         """
-        # pylint: disable=unused-argument,super-init-not-called
         # Adding __init__ and not doing anything is done to overwrite the superclass's __init__ docstring
         return
 
@@ -783,7 +781,7 @@ def arithmetic_table(
 
         if cls.element_repr == "power":
             # Order elements by powers of the primitive element
-            dtype = cls.dtypes[-1]  # pylint: disable=unsubscriptable-object
+            dtype = cls.dtypes[-1]
             x_default = np.concatenate(
                 (np.atleast_1d(cls(0)), cls.primitive_element ** np.arange(0, cls.order - 1, dtype=dtype))
             )
@@ -1339,7 +1337,7 @@ def column_space(self) -> Self:
         if not A.ndim == 2:
             raise ValueError(f"Only 2-D matrices have a column space, not {A.ndim}-D.")
 
-        return (A.T).row_space()  # pylint: disable=no-member
+        return (A.T).row_space()
 
     def left_null_space(self) -> Self:
         r"""
@@ -1457,7 +1455,7 @@ def null_space(self) -> Self:
         if not A.ndim == 2:
             raise ValueError(f"Only 2-D matrices have a null space, not {A.ndim}-D.")
 
-        return (A.T).left_null_space()  # pylint: disable=no-member
+        return (A.T).left_null_space()
 
     def field_trace(self) -> FieldArray:
         r"""
@@ -1497,7 +1495,7 @@ def field_trace(self) -> FieldArray:
             subfield = field.prime_subfield
             p = field.characteristic
             m = field.degree
-            dtype = field.dtypes[-1]  # pylint: disable=unsubscriptable-object
+            dtype = field.dtypes[-1]
             conjugates = np.power.outer(x, p ** np.arange(0, m, dtype=dtype))
             trace = np.add.reduce(conjugates, axis=-1)
             trace = subfield._view(trace)
@@ -1725,7 +1723,7 @@ def log(self, base: ElementLike | ArrayLike | None = None) -> int | np.ndarray:
             ufunc = field._log.jit_calculate
         else:
             ufunc = field._log.ufunc
-        output = getattr(ufunc, "__call__")(*inputs, **kwargs)
+        output = ufunc(*inputs, **kwargs)
 
         # TODO: Could add a method keyword argument to the function to allow different modes.
 
@@ -1786,7 +1784,7 @@ def _display(self, mode: Literal["repr", "str"], separator=", ") -> str:
 
         string = np.array2string(x, separator=separator, prefix=prefix, suffix=suffix, formatter=formatter)
 
-        if formatter != {}:
+        if formatter:
             # We are using special print methods and must perform element alignment ourselves. We will print each
             # element a second time use the max width of any element observed on the first array2string() call.
             field._element_fixed_width = field._element_fixed_width_counter
diff --git a/src/galois/_fields/_factory.py b/src/galois/_fields/_factory.py
index dab519816..9c89b013b 100644
--- a/src/galois/_fields/_factory.py
+++ b/src/galois/_fields/_factory.py
@@ -5,7 +5,7 @@
 
 import sys
 import types
-from typing import Type, overload
+from typing import overload
 
 from typing_extensions import Literal
 
@@ -19,8 +19,6 @@
 from ._primitive_element import is_primitive_element, primitive_element
 from ._ufunc import UFuncMixin_2_m, UFuncMixin_p_1, UFuncMixin_p_m
 
-# pylint: disable=redefined-outer-name,redefined-builtin
-
 
 @overload
 def GF(
@@ -31,7 +29,7 @@ def GF(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     ...
 
 
@@ -45,7 +43,7 @@ def GF(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     ...
 
 
@@ -309,7 +307,7 @@ def Field(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     ...
 
 
@@ -323,7 +321,7 @@ def Field(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     ...
 
 
@@ -358,7 +356,7 @@ def _GF_prime(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     """
     Class factory for prime fields GF(p).
     """
@@ -428,11 +426,10 @@ def _GF_extension(
     verify: bool = True,
     compile: Literal["auto", "jit-lookup", "jit-calculate", "python-calculate"] | None = None,
     repr: Literal["int", "poly", "power"] | None = None,
-) -> Type[FieldArray]:
+) -> type[FieldArray]:
     """
     Class factory for extension fields GF(p^m).
     """
-    # pylint: disable=too-many-statements
     prime_subfield = _GF_prime(p)
     is_primitive_poly = None
     verify_poly = verify
diff --git a/src/galois/_fields/_meta.py b/src/galois/_fields/_meta.py
index 53a04bf91..2e4d57058 100644
--- a/src/galois/_fields/_meta.py
+++ b/src/galois/_fields/_meta.py
@@ -3,7 +3,7 @@
 """
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Type
+from typing import TYPE_CHECKING
 
 import numpy as np
 from typing_extensions import Literal
@@ -23,9 +23,7 @@ class FieldArrayMeta(ArrayMeta):
     A metaclass that provides documented class properties for `FieldArray` subclasses.
     """
 
-    # pylint: disable=no-value-for-parameter,too-many-public-methods
-
-    def __new__(mcs, name, bases, namespace, **kwargs):  # pylint: disable=unused-argument
+    def __new__(mcs, name, bases, namespace, **kwargs):
         return super().__new__(mcs, name, bases, namespace)
 
     def __init__(cls, name, bases, namespace, **kwargs):
@@ -371,7 +369,7 @@ def squares(cls) -> FieldArray:
         """
         x = cls.elements
         is_square = x.is_square()
-        return x[is_square]  # pylint: disable=unsubscriptable-object
+        return x[is_square]
 
     @property
     def non_squares(cls) -> FieldArray:
@@ -408,7 +406,7 @@ def non_squares(cls) -> FieldArray:
         """
         x = cls.elements
         is_square = x.is_square()
-        return x[~is_square]  # pylint: disable=unsubscriptable-object
+        return x[~is_square]
 
     @property
     def is_prime_field(cls) -> bool:
@@ -441,7 +439,7 @@ def is_extension_field(cls) -> bool:
         return cls._degree > 1
 
     @property
-    def prime_subfield(cls) -> Type[FieldArray]:
+    def prime_subfield(cls) -> type[FieldArray]:
         r"""
         The prime subfield $\mathrm{GF}(p)$ of the extension field $\mathrm{GF}(p^m)$.
 
diff --git a/src/galois/_helper.py b/src/galois/_helper.py
index b9cbacc4c..0e15d0bd5 100644
--- a/src/galois/_helper.py
+++ b/src/galois/_helper.py
@@ -76,7 +76,7 @@ def export(obj):
     # Append this object to the private module's "all" list
     public_members = getattr(module, "__all__", [])
     public_members.append(obj.__name__)
-    setattr(module, "__all__", public_members)
+    module.__all__ = public_members
 
     return obj
 
@@ -92,7 +92,7 @@ def method_of(class_):
 
     def decorator(func):
         setattr(class_, func.__name__, func)
-        setattr(getattr(class_, func.__name__), "__doc__", func.__doc__)
+        getattr(class_, func.__name__).__doc__ = func.__doc__
 
         return func
 
diff --git a/src/galois/_lfsr.py b/src/galois/_lfsr.py
index 9709204d2..f7b3df70d 100644
--- a/src/galois/_lfsr.py
+++ b/src/galois/_lfsr.py
@@ -4,7 +4,7 @@
 """
 from __future__ import annotations
 
-from typing import Type, overload
+from typing import overload
 
 import numba
 import numpy as np
@@ -142,7 +142,7 @@ def _step_backward(self, steps):
         return y
 
     @property
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         return self._field
 
     @property
@@ -425,7 +425,6 @@ def reset(self, state: ArrayLike | None = None):
                 lfsr.reset([1, 2, 3, 4])
                 lfsr.state
         """
-        # pylint: disable=useless-super-delegation
         return super().reset(state)
 
     def step(self, steps: int = 1) -> FieldArray:
@@ -474,7 +473,6 @@ def step(self, steps: int = 1) -> FieldArray:
                 lfsr.step(-5)
                 lfsr.state
         """
-        # pylint: disable=useless-super-delegation
         return super().step(steps)
 
     def to_galois_lfsr(self) -> GLFSR:
@@ -528,7 +526,7 @@ def to_galois_lfsr(self) -> GLFSR:
         return GLFSR(self.feedback_poly, state=state)
 
     @property
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         """
         The :obj:`~galois.FieldArray` subclass for the finite field that defines the linear arithmetic.
 
@@ -710,7 +708,6 @@ def __call__(self, taps, state, steps):
         return y, state_
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD, MULTIPLY
         ADD = self.field._add.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -772,7 +769,6 @@ def __call__(self, taps, state, steps):
         return y, state_
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT, MULTIPLY, RECIPROCAL
         SUBTRACT = self.field._subtract.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -1052,7 +1048,6 @@ def reset(self, state: ArrayLike | None = None):
                 lfsr.reset([1, 2, 3, 4])
                 lfsr.state
         """
-        # pylint: disable=useless-super-delegation
         return super().reset(state)
 
     def step(self, steps: int = 1) -> FieldArray:
@@ -1100,7 +1095,6 @@ def step(self, steps: int = 1) -> FieldArray:
                 lfsr.step(-5)
                 lfsr.state
         """
-        # pylint: disable=useless-super-delegation
         return super().step(steps)
 
     def to_fibonacci_lfsr(self) -> FLFSR:
@@ -1141,7 +1135,7 @@ def to_fibonacci_lfsr(self) -> FLFSR:
         return FLFSR(self.feedback_poly, state=state)
 
     @property
-    def field(self) -> Type[FieldArray]:
+    def field(self) -> type[FieldArray]:
         """
         The :obj:`~galois.FieldArray` subclass for the finite field that defines the linear arithmetic.
 
@@ -1321,7 +1315,6 @@ def __call__(self, taps, state, steps):
         return y, state_
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD, MULTIPLY
         ADD = self.field._add.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -1386,7 +1379,6 @@ def __call__(self, taps, state, steps):
         return y, state_
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT, MULTIPLY, RECIPROCAL
         SUBTRACT = self.field._subtract.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -1543,7 +1535,6 @@ def __call__(self, sequence):
         return coeffs
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD, SUBTRACT, MULTIPLY, RECIPROCAL
         ADD = self.field._add.ufunc_call_only
         SUBTRACT = self.field._subtract.ufunc_call_only
diff --git a/src/galois/_math.py b/src/galois/_math.py
index 22ce1c18b..5c68963f8 100644
--- a/src/galois/_math.py
+++ b/src/galois/_math.py
@@ -103,7 +103,7 @@ def isqrt(n: int) -> int:
         number-theory-integer
     """
     if sys.version_info.major == 3 and sys.version_info.minor >= 8:
-        return math.isqrt(n)  # pylint: disable=no-member
+        return math.isqrt(n)
 
     verify_isinstance(n, int)
     if not n >= 0:
diff --git a/src/galois/_polys/_binary.py b/src/galois/_polys/_binary.py
index 582f13a37..b0745522c 100644
--- a/src/galois/_polys/_binary.py
+++ b/src/galois/_polys/_binary.py
@@ -45,7 +45,7 @@ def multiply(a: int, b: int) -> int:
     return c
 
 
-def divmod(a: int, b: int) -> tuple[int, int]:  # pylint: disable=redefined-builtin
+def divmod(a: int, b: int) -> tuple[int, int]:
     """
     a(x) = q(x)*b(x) + r(x)
     """
@@ -87,7 +87,7 @@ def mod(a: int, b: int) -> int:
     return divmod(a, b)[1]
 
 
-def pow(a: int, b: int, c: int | None = None) -> int:  # pylint: disable=redefined-builtin
+def pow(a: int, b: int, c: int | None = None) -> int:
     """
     d(x) = a(x)^b % c(x)
     """
diff --git a/src/galois/_polys/_conversions.py b/src/galois/_polys/_conversions.py
index d9c6cea7d..d1788ca8e 100644
--- a/src/galois/_polys/_conversions.py
+++ b/src/galois/_polys/_conversions.py
@@ -91,7 +91,7 @@ def sparse_poly_to_str(degrees: list[int], coeffs: list[int], poly_var: str = "x
     x = []
 
     # Use brackets around coefficients only when using the "poly" or "power" element representation
-    brackets = hasattr(type(coeffs), "_element_repr") and getattr(type(coeffs), "_element_repr") in ["poly", "power"]
+    brackets = hasattr(type(coeffs), "_element_repr") and type(coeffs)._element_repr in ["poly", "power"]
 
     for degree, coeff in zip(degrees, coeffs):
         if coeff == 0:
diff --git a/src/galois/_polys/_dense.py b/src/galois/_polys/_dense.py
index 40f79df36..42ef5932b 100644
--- a/src/galois/_polys/_dense.py
+++ b/src/galois/_polys/_dense.py
@@ -11,8 +11,6 @@
 from .._domains._function import Function
 from .._helper import verify_isinstance
 
-# pylint: disable=unidiomatic-typecheck
-
 
 class add_jit(Function):
     """
@@ -38,7 +36,6 @@ def __call__(self, a: Array, b: Array) -> Array:
         return r
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD
         ADD = self.field._add.ufunc_call_only
 
@@ -99,7 +96,6 @@ def __call__(self, a: Array, b: Array) -> Array:
         return r
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT
         SUBTRACT = self.field._subtract.ufunc_call_only
 
@@ -175,7 +171,6 @@ def __call__(self, a: Array, b: Array) -> tuple[Array, Array]:
         return q, r
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT, MULTIPLY, RECIPROCAL
         SUBTRACT = self.field._subtract.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -226,7 +221,6 @@ def __call__(self, a: Array, b: Array) -> Array:
         return q
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT, MULTIPLY, RECIPROCAL
         SUBTRACT = self.field._subtract.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -280,7 +274,6 @@ def __call__(self, a: Array, b: Array) -> Array:
         return r
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global SUBTRACT, MULTIPLY, RECIPROCAL
         SUBTRACT = self.field._subtract.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -363,7 +356,6 @@ def __call__(self, a: Array, b: int, c: Array | None = None) -> Array:
         return z
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global POLY_MULTIPLY, POLY_MOD
         POLY_MULTIPLY = self.field._convolve.function
         POLY_MOD = mod_jit(self.field).function
@@ -429,7 +421,6 @@ def __call__(self, coeffs: Array, x: Array) -> Array:
         return y
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ADD, MULTIPLY
         ADD = self.field._add.ufunc_call_only
         MULTIPLY = self.field._multiply.ufunc_call_only
@@ -440,7 +431,7 @@ def set_globals(self):
     @staticmethod
     def implementation(coeffs, values):
         y = np.zeros(values.size, dtype=values.dtype)
-        for i in numba.prange(values.size):  # pylint: disable=not-an-iterable
+        for i in numba.prange(values.size):
             y[i] = coeffs[0]
             for j in range(1, coeffs.size):
                 y[i] = ADD(coeffs[j], MULTIPLY(y[i], values[i]))
@@ -473,7 +464,6 @@ def __call__(self, nonzero_degrees: np.ndarray, nonzero_coeffs: Array) -> Array:
         return roots[idxs]
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global ORDER, ADD, MULTIPLY, POWER
         ORDER = self.field.order
         ADD = self.field._add.ufunc_call_only
diff --git a/src/galois/_polys/_irreducible.py b/src/galois/_polys/_irreducible.py
index 5cb377c54..a9c4c0f86 100644
--- a/src/galois/_polys/_irreducible.py
+++ b/src/galois/_polys/_irreducible.py
@@ -79,7 +79,6 @@ def is_irreducible(f: Poly) -> bool:
             f.is_irreducible()
     """
 
-    # pylint: disable=too-many-return-statements
     if f.degree == 0:
         # Over fields, f(x) = 0 is the zero element of GF(p^m)[x] and f(x) = c are the units of GF(p^m)[x].
         # Both the zero element and the units are not irreducible over the polynomial ring GF(p^m)[x].
diff --git a/src/galois/_polys/_lagrange.py b/src/galois/_polys/_lagrange.py
index 0e4695134..7cb84d441 100644
--- a/src/galois/_polys/_lagrange.py
+++ b/src/galois/_polys/_lagrange.py
@@ -81,7 +81,7 @@ class lagrange_poly_jit(Function):
     def __call__(self, x: Array, y: Array) -> Array:
         verify_isinstance(x, Array)
         verify_isinstance(y, Array)
-        if not type(x) == type(y):  # pylint: disable=unidiomatic-typecheck
+        if not type(x) == type(y):
             raise TypeError(f"Arguments 'x' and 'y' must be over the same Galois field, not {type(x)} and {type(y)}.")
         if not x.ndim == 1:
             raise ValueError(f"Argument 'x' must be 1-D, not have shape {x.shape}.")
@@ -103,7 +103,6 @@ def __call__(self, x: Array, y: Array) -> Array:
         return coeffs
 
     def set_globals(self):
-        # pylint: disable=global-variable-undefined
         global NEGATIVE, SUBTRACT, MULTIPLY, RECIPROCAL, POLY_ADD, POLY_FLOORDIV, POLY_MULTIPLY
         NEGATIVE = self.field._negative.ufunc_call_only
         SUBTRACT = self.field._subtract.ufunc_call_only
diff --git a/src/galois/_polys/_poly.py b/src/galois/_polys/_poly.py
index 833a6b11a..9f459b4ca 100644
--- a/src/galois/_polys/_poly.py
+++ b/src/galois/_polys/_poly.py
@@ -3,7 +3,7 @@
 """
 from __future__ import annotations
 
-from typing import Sequence, Type, overload
+from typing import Sequence, overload
 
 import numpy as np
 from typing_extensions import Literal, Self
@@ -51,14 +51,13 @@ class Poly:
     Group:
         polys
     """
-    # pylint: disable=too-many-public-methods
 
     __slots__ = ["_field", "_degrees", "_coeffs", "_nonzero_degrees", "_nonzero_coeffs", "_integer", "_degree", "_type"]
 
     # Special private attributes that are once computed. There are three arithmetic types for polynomials: "dense",
     # "binary", and "sparse". All types define _field, "dense" defines _coeffs, "binary" defines "_integer", and
     # "sparse" defines _nonzero_degrees and _nonzero_coeffs. The other properties are created when needed.
-    _field: Type[Array]
+    _field: type[Array]
     _degrees: np.ndarray
     _coeffs: Array
     _nonzero_degrees: np.ndarray
@@ -73,7 +72,7 @@ class Poly:
     def __init__(
         self,
         coeffs: ArrayLike,
-        field: Type[Array] | None = None,
+        field: type[Array] | None = None,
         order: Literal["desc", "asc"] = "desc",
     ):
         r"""
@@ -127,7 +126,7 @@ def __init__(
             self._type = "dense"
 
     @classmethod
-    def _PolyLike(cls, poly_like: PolyLike, field: Type[Array] | None = None) -> Self:
+    def _PolyLike(cls, poly_like: PolyLike, field: type[Array] | None = None) -> Self:
         """
         A private alternate constructor that converts a poly-like object into a polynomial, given a finite field.
         """
@@ -152,7 +151,7 @@ def _PolyLike(cls, poly_like: PolyLike, field: Type[Array] | None = None) -> Sel
     ###############################################################################
 
     @classmethod
-    def Zero(cls, field: Type[Array] | None = None) -> Self:
+    def Zero(cls, field: type[Array] | None = None) -> Self:
         r"""
         Constructs the polynomial $f(x) = 0$ over $\mathrm{GF}(p^m)$.
 
@@ -180,7 +179,7 @@ def Zero(cls, field: Type[Array] | None = None) -> Self:
         return Poly([0], field=field)
 
     @classmethod
-    def One(cls, field: Type[Array] | None = None) -> Self:
+    def One(cls, field: type[Array] | None = None) -> Self:
         r"""
         Constructs the polynomial $f(x) = 1$ over $\mathrm{GF}(p^m)$.
 
@@ -208,7 +207,7 @@ def One(cls, field: Type[Array] | None = None) -> Self:
         return Poly([1], field=field)
 
     @classmethod
-    def Identity(cls, field: Type[Array] | None = None) -> Self:
+    def Identity(cls, field: type[Array] | None = None) -> Self:
         r"""
         Constructs the polynomial $f(x) = x$ over $\mathrm{GF}(p^m)$.
 
@@ -240,7 +239,7 @@ def Random(
         cls,
         degree: int,
         seed: int | np.integer | np.random.Generator | None = None,
-        field: Type[Array] | None = None,
+        field: type[Array] | None = None,
     ) -> Self:
         r"""
         Constructs a random polynomial over $\mathrm{GF}(p^m)$ with degree $d$.
@@ -301,7 +300,7 @@ def Random(
         return Poly(coeffs)
 
     @classmethod
-    def Str(cls, string: str, field: Type[Array] | None = None) -> Self:
+    def Str(cls, string: str, field: type[Array] | None = None) -> Self:
         r"""
         Constructs a polynomial over $\mathrm{GF}(p^m)$ from its string representation.
 
@@ -351,7 +350,7 @@ def Str(cls, string: str, field: Type[Array] | None = None) -> Self:
         return Poly.Degrees(degrees, coeffs, field=field)
 
     @classmethod
-    def Int(cls, integer: int, field: Type[Array] | None = None) -> Self:
+    def Int(cls, integer: int, field: type[Array] | None = None) -> Self:
         r"""
         Constructs a polynomial over $\mathrm{GF}(p^m)$ from its integer representation.
 
@@ -430,7 +429,7 @@ def Degrees(
         cls,
         degrees: Sequence[int] | np.ndarray,
         coeffs: ArrayLike | None = None,
-        field: Type[Array] | None = None,
+        field: type[Array] | None = None,
     ) -> Self:
         r"""
         Constructs a polynomial over $\mathrm{GF}(p^m)$ from its non-zero degrees.
@@ -519,7 +518,7 @@ def Roots(
         cls,
         roots: ArrayLike,
         multiplicities: Sequence[int] | np.ndarray | None = None,
-        field: Type[Array] | None = None,
+        field: type[Array] | None = None,
     ) -> Self:
         r"""
         Constructs a monic polynomial over $\mathrm{GF}(p^m)$ from its roots.
@@ -1003,7 +1002,7 @@ def __hash__(self):
 
     @overload
     def __call__(
-        self, at: ElementLike | ArrayLike, field: Type[Array] | None = None, elementwise: bool = True
+        self, at: ElementLike | ArrayLike, field: type[Array] | None = None, elementwise: bool = True
     ) -> Array:
         ...
 
@@ -1450,7 +1449,7 @@ def __pow__(self, exponent: int, modulus: Poly | None = None) -> Poly:
     ###############################################################################
 
     @property
-    def field(self) -> Type[Array]:
+    def field(self) -> type[Array]:
         """
         The :obj:`~galois.Array` subclass for the finite field the coefficients are over.
 
@@ -1633,7 +1632,7 @@ def is_monic(self) -> bool:
         return self.nonzero_coeffs[0] == 1
 
 
-def _convert_coeffs(coeffs: ArrayLike, field: Type[Array] | None = None) -> tuple[Array, Type[Array]]:
+def _convert_coeffs(coeffs: ArrayLike, field: type[Array] | None = None) -> tuple[Array, type[Array]]:
     """
     Converts the coefficient-like input into a Galois field array based on the `field` keyword argument.
     """
@@ -1641,7 +1640,7 @@ def _convert_coeffs(coeffs: ArrayLike, field: Type[Array] | None = None) -> tupl
         if field is None:
             # Infer the field from the coefficients provided
             field = type(coeffs)
-        elif type(coeffs) is not field:  # pylint: disable=unidiomatic-typecheck
+        elif type(coeffs) is not field:
             # Convert coefficients into the specified field
             coeffs = field(coeffs)
     else:
@@ -1713,7 +1712,7 @@ def _evaluate_poly(f: Poly, g: Poly) -> Poly:
     return h
 
 
-def _check_input_is_poly(a: Poly | Array, field: Type[Array]):
+def _check_input_is_poly(a: Poly | Array, field: type[Array]):
     """
     Verify polynomial arithmetic operands are either galois.Poly or scalars in a finite field.
     """
@@ -1735,7 +1734,7 @@ def _check_input_is_poly(a: Poly | Array, field: Type[Array]):
         raise TypeError(f"Both polynomial operands must be over the same field, not {a_field.name} and {field.name}.")
 
 
-def _check_input_is_poly_or_int(a: Poly | Array | int, field: Type[Array]):
+def _check_input_is_poly_or_int(a: Poly | Array | int, field: type[Array]):
     """
     Verify polynomial arithmetic operands are either galois.Poly, scalars in a finite field, or an integer scalar.
     """
@@ -1744,7 +1743,7 @@ def _check_input_is_poly_or_int(a: Poly | Array | int, field: Type[Array]):
     _check_input_is_poly(a, field)
 
 
-def _check_input_is_poly_or_none(a: Poly | Array | None, field: Type[Array]):
+def _check_input_is_poly_or_none(a: Poly | Array | None, field: type[Array]):
     """
     Verify polynomial arithmetic operands are either galois.Poly, scalars in a finite field, or None.
     """
@@ -1753,7 +1752,7 @@ def _check_input_is_poly_or_none(a: Poly | Array | None, field: Type[Array]):
     _check_input_is_poly(a, field)
 
 
-def _convert_to_coeffs(a: Poly | Array | int, field: Type[Array]) -> Array:
+def _convert_to_coeffs(a: Poly | Array | int, field: type[Array]) -> Array:
     """
     Convert the polynomial or finite field scalar into a coefficient array.
     """
@@ -1768,7 +1767,7 @@ def _convert_to_coeffs(a: Poly | Array | int, field: Type[Array]) -> Array:
     return coeffs
 
 
-def _convert_to_integer(a: Poly | Array | int, field: Type[Array]) -> int:
+def _convert_to_integer(a: Poly | Array | int, field: type[Array]) -> int:
     """
     Convert the polynomial or finite field scalar into its integer representation.
     """
@@ -1781,7 +1780,7 @@ def _convert_to_integer(a: Poly | Array | int, field: Type[Array]) -> int:
     return integer
 
 
-def _convert_to_sparse_coeffs(a: Poly | Array | int, field: Type[Array]) -> tuple[np.ndarray, Array]:
+def _convert_to_sparse_coeffs(a: Poly | Array | int, field: type[Array]) -> tuple[np.ndarray, Array]:
     """
     Convert the polynomial or finite field scalar into its non-zero degrees and coefficients.
     """
diff --git a/src/galois/_polys/_search.py b/src/galois/_polys/_search.py
index c0b3d2a5f..2a8aa1b54 100644
--- a/src/galois/_polys/_search.py
+++ b/src/galois/_polys/_search.py
@@ -8,7 +8,7 @@
 
 import functools
 import random
-from typing import Iterator, Sequence, Type
+from typing import Iterator, Sequence
 
 import numpy as np
 
@@ -18,7 +18,7 @@
 
 @functools.lru_cache(maxsize=8192)
 def _deterministic_search(
-    field: Type[Array],
+    field: type[Array],
     start: int,
     stop: int,
     step: int,
diff --git a/src/galois/_prime.py b/src/galois/_prime.py
index 359aa94f3..cb919b698 100644
--- a/src/galois/_prime.py
+++ b/src/galois/_prime.py
@@ -84,7 +84,7 @@ def primes(n: int) -> list[int]:
             # Mark multiples of the prime that are odd (and in the composite array) as composite
             composite[first_multiple::delta] = True
 
-    prime_idxs = np.where(composite == False)[0]  # pylint: disable=singleton-comparison
+    prime_idxs = np.where(composite == False)[0]  # noqa: E712
     p = (prime_idxs * 2 + 3).tolist()  # Convert indices back to odd integers
     p.insert(0, 2)  # Add the only even prime, 2
 
@@ -170,14 +170,17 @@ def prev_prime(n: int) -> int:
     if n <= MAX_N:
         return PRIMES[bisect.bisect_right(PRIMES, n) - 1]
 
-    # TODO: Make this faster using wheel factorization
-    n = n - 1 if n % 2 == 0 else n  # The next possible prime (which is odd)
-    while True:
-        n -= 2  # Only check odds
-        if is_prime(n):
-            break
+    shifts = [29, 23, 19, 17, 13, 11, 7, 1]  # Factorization wheel for basis {2, 3, 5}
+    base = n // 30 * 30  # Wheel factorization starting point
 
-    return n
+    while True:
+        for shift in shifts:
+            i = base + shift  # May be bigger than n
+            if i > n:
+                continue
+            if is_prime(i):
+                return i
+        base -= 30
 
 
 @export
@@ -210,14 +213,17 @@ def next_prime(n: int) -> int:
     if n < PRIMES[-1]:
         return PRIMES[bisect.bisect_right(PRIMES, n)]
 
-    # TODO: Make this faster using wheel factorization
-    n = n + 1 if n % 2 == 0 else n + 2  # The next possible prime (which is odd)
-    while True:
-        n += 2  # Only check odds
-        if is_prime(n):
-            break
+    shifts = [1, 7, 11, 13, 17, 19, 23, 29]  # Factorization wheel for basis {2, 3, 5}
+    base = n // 30 * 30  # Wheel factorization starting point. May be less than n.
 
-    return n
+    while True:
+        for shift in shifts:
+            i = base + shift
+            if i <= n:
+                continue
+            if is_prime(i):
+                return i
+        base += 30
 
 
 @export
@@ -255,7 +261,6 @@ def random_prime(bits: int, seed: int | None = None) -> int:
 
         .. code-block:: console
 
-            # pylint: disable=line-too-long
             $ openssl prime 327845897586213436751081882871255331286648902836386839087617368608439574698192016043769533823474001379935585889197488144338014865193967937011638431094821943416361149113909692569658970713864593781874423564706915495970135894084612689487074397782022398597547611189482697523681694691585678818112329605903872356773
             1D2DE38DE88C67E1EAFDEEAE77C40B8709ED9C275522C6D5578976B1ABCBE7E0F8C6DE1271EEC6EB3827649164189788F9F3A622AEA5F4039761EC708B5841DE88566D9B5BAF49BA92DCE5A300297A9E0E890E4103ED2AD4B5E0553CE56E8C34758CD45900125DBA1553AE73AA0CBD6018A2A8713D46E475BF058D1AAA52EF1A5 (327845897586213436751081882871255331286648902836386839087617368608439574698192016043769533823474001379935585889197488144338014865193967937011638431094821943416361149113909692569658970713864593781874423564706915495970135894084612689487074397782022398597547611189482697523681694691585678818112329605903872356773) is prime
 
@@ -764,7 +769,6 @@ def kronecker_symbol(a: int, n: int) -> int:
     Group:
         number-theory-congruences
     """
-    # pylint: disable=too-many-return-statements
     verify_isinstance(a, int)
     verify_isinstance(n, int)
 
diff --git a/src/galois/typing.py b/src/galois/typing.py
index 807b07604..26ea007f8 100644
--- a/src/galois/typing.py
+++ b/src/galois/typing.py
@@ -1,6 +1,8 @@
 """
 A public module containing type hints for the :obj:`galois` library.
 """
+# ruff: noqa: F821
+
 from __future__ import annotations
 
 from typing import TYPE_CHECKING, Sequence, Union
@@ -12,7 +14,6 @@
     from ._domains._array import Array
     from ._polys._poly import Poly
 
-
 ElementLike = Union[int, str, "Array"]
 """
 A :obj:`~typing.Union` representing objects that can be coerced into a Galois field element.


Test patch:
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 23c599f80..2a8f6e8a1 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -3,11 +3,11 @@ name: Test
 on:
   push:
     branches:
-      - master
+      - main
       - 'release/*'
   pull_request:
     branches:
-      - master
+      - main
       - 'release/*'
 
 jobs:
@@ -59,8 +59,11 @@ jobs:
           files: galois-*.whl
           working-directory: dist/
 
-      - name: Install the `galois` package wheel with upgraded [dev]
-        run: python3 -m pip install --upgrade dist/${{ steps.glob.outputs.paths }}[dev]
+      - name: Install the dev dependencies
+        run: python3 -m pip install -r requirements-dev.txt
+
+      - name: Install the `galois` package wheel with upgraded dependencies
+        run: python3 -m pip install --upgrade dist/${{ steps.glob.outputs.paths }}
 
       - name: Test with pytest
         run: python3 -m pytest -n auto --cov=galois --cov-report=xml tests/
@@ -109,8 +112,11 @@ jobs:
       - name: Install minimum package dependencies
         run: python3 -m pip install -r requirements-min.txt
 
-      - name: Install the `galois` package wheel with [dev]
-        run: python3 -m pip install dist/${{ steps.glob.outputs.paths }}[dev]
+      - name: Install the dev dependencies
+        run: python3 -m pip install -r requirements-dev.txt
+
+      - name: Install the `galois` package wheel
+        run: python3 -m pip install dist/${{ steps.glob.outputs.paths }}
 
       - name: Test with pytest
         run: python3 -m pytest -n auto tests/
@@ -156,8 +162,11 @@ jobs:
           files: galois-*.whl
           working-directory: dist/
 
-      - name: Install the `galois` package wheel with upgraded [dev]
-        run: python3 -m pip install --upgrade dist/${{ steps.glob.outputs.paths }}[dev]
+      - name: Install the dev dependencies
+        run: python3 -m pip install -r requirements-dev.txt
+
+      - name: Install the `galois` package wheel with upgraded dependencies
+        run: python3 -m pip install --upgrade dist/${{ steps.glob.outputs.paths }}
 
       - name: Test with pytest
         run: python3 -m pytest -n auto tests/
diff --git a/docs/development/unit-tests.rst b/docs/development/unit-tests.rst
index 9b601f932..7ab301772 100644
--- a/docs/development/unit-tests.rst
+++ b/docs/development/unit-tests.rst
@@ -10,7 +10,7 @@ First, `pytest` needs to be installed on your system. Easily install it by insta
 
 .. code-block:: console
 
-   $ python3 -m pip install .[dev]
+   $ python3 -m pip install -r requirements-dev.txt
 
 Configuration
 -------------
diff --git a/scripts/generate_fec_test_vectors.py b/scripts/generate_fec_test_vectors.py
index f03213dba..44de5f2c7 100644
--- a/scripts/generate_fec_test_vectors.py
+++ b/scripts/generate_fec_test_vectors.py
@@ -4,10 +4,8 @@
 Install SageMath:
 * `sudo apt install sagemath`
 """
-import json
 import os
 import pickle
-import random
 import shutil
 
 import numpy as np
@@ -42,7 +40,7 @@ def to_field(field, integer):
         return field(" + ".join(l))
     try:
         return field.fetch_int(int(integer))
-    except:
+    except:  # noqa: E722
         return field(integer)
 
 
diff --git a/scripts/generate_field_test_vectors.py b/scripts/generate_field_test_vectors.py
index f6d3a5438..4749df9fe 100644
--- a/scripts/generate_field_test_vectors.py
+++ b/scripts/generate_field_test_vectors.py
@@ -38,7 +38,7 @@ def set_seed(seed):
     random.seed(seed)
 
 
-def I(element):
+def I(element):  # noqa: E743
     """Convert from various finite field elements to an integer"""
     if isinstance(element, sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt):
         coeffs = element._vector_()
@@ -63,7 +63,7 @@ def F(integer):
         return FIELD(" + ".join(l))
     try:
         return FIELD.fetch_int(int(integer))
-    except:
+    except:  # noqa: E722
         return FIELD(integer)
 
 
@@ -74,7 +74,7 @@ def arange(low, high, sparse=False):
         else:
             X = np.empty(SPARSE_SIZE, dtype=object)
             iterator = np.nditer(X, flags=["multi_index", "refs_ok"])
-            for i in iterator:
+            for _ in iterator:
                 X[iterator.multi_index] = random.randint(low, high - 1)
     else:
         X = np.arange(low, high, dtype=np.int64)
@@ -270,7 +270,7 @@ def make_luts(field, sub_folder, seed, sparse=False):
     for i in range(Z.shape[0]):
         try:
             Z[i] = I(field.fetch_int(X[i]).log(alpha))
-        except:
+        except:  # noqa: E722
             Z[i] = I(log(F(X[i]), alpha))
     d = {"X": X, "Z": Z}
     save_pickle(d, folder, "log.pkl")
@@ -364,7 +364,7 @@ def make_luts(field, sub_folder, seed, sparse=False):
     X = []
     Y = []
     Z = []
-    for i in range(3):
+    for _ in range(3):
         x = randint_matrix(0, order, (10,))
         y = randint_matrix(0, order, (10,))
         X.append(x)
@@ -801,8 +801,9 @@ def make_luts(field, sub_folder, seed, sparse=False):
     Y = [random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS) for i in range(20)]
     # Add some specific polynomial types
     X.append([0]), Y.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS))  # 0 / y
-    X.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS // 2)), Y.append(
-        random_coeffs(0, order, MAX_COEFFS // 2, MAX_COEFFS)
+    (
+        X.append(random_coeffs(0, order, MIN_COEFFS, MAX_COEFFS // 2)),
+        Y.append(random_coeffs(0, order, MAX_COEFFS // 2, MAX_COEFFS)),
     )  # x / y with x.degree < y.degree
     X.append(random_coeffs(0, order, 2, MAX_COEFFS)), Y.append(random_coeffs(0, order, 1, 2))  # x / y with y.degree = 0
     Q = []
@@ -994,7 +995,7 @@ def make_luts(field, sub_folder, seed, sparse=False):
     for i in range(20):
         n = random.randint(2, 4)  # The number of polynomials
         x, y = [], []
-        for j in range(n):
+        for _ in range(n):
             d = random.randint(3, 5)
             x.append(random_coeffs(0, order, d, d + 1))
             y.append(random_coeffs(0, order, d + 1, d + 2))  # Ensure modulus degree is greater than remainder degree
@@ -1005,7 +1006,7 @@ def make_luts(field, sub_folder, seed, sparse=False):
             y = [list_to_poly(yy) for yy in y]
             z = crt(x, y)
             Z[i] = poly_to_list(z)
-        except:
+        except:  # noqa: E722
             Z[i] = None
     d = {"X": X, "Y": Y, "Z": Z}
     save_pickle(d, folder, "crt.pkl")
diff --git a/scripts/generate_int_test_vectors.py b/scripts/generate_int_test_vectors.py
index e30519a85..9e91d07c1 100644
--- a/scripts/generate_int_test_vectors.py
+++ b/scripts/generate_int_test_vectors.py
@@ -3,7 +3,6 @@
 
 * `sudo apt install sagemath`
 """
-import json
 import os
 import pickle
 import random
@@ -156,7 +155,7 @@ def save_pickle(d, folder, name):
     try:
         z = crt(X[i], Y[i])
         Z[i] = int(z)
-    except:
+    except:  # noqa: E722
         Z[i] = None
 d = {"X": X, "Y": Y, "Z": Z}
 save_pickle(d, FOLDER, "crt.pkl")
diff --git a/scripts/sparse_poly_performance_test.py b/scripts/sparse_poly_performance_test.py
index b14970a79..69b2699a3 100644
--- a/scripts/sparse_poly_performance_test.py
+++ b/scripts/sparse_poly_performance_test.py
@@ -1,11 +1,11 @@
 import numpy as np
 from IPython import get_ipython
 
+import galois
+
 ipython = get_ipython()
 assert ipython is not None, "Must run this script with ipython3"
 
-import galois
-
 
 def get_coeffs(degree, N, field):
     while True:
@@ -55,13 +55,13 @@ def get_coeffs(degree, N, field):
     print("  SparsePoly:\t", end="")
     p1._type = "sparse"
     p2._type = "sparse"
-    p1.nonzero_degrees, p1.nonzero_coeffs, p2.nonzero_degrees, p2.nonzero_coeffs
+    print(p1.nonzero_degrees, p1.nonzero_coeffs, p2.nonzero_degrees, p2.nonzero_coeffs)
     ipython.run_line_magic("timeit", "p1 * p2")
 
     print("  DensePoly:\t", end="")
     p1._type = "dense"
     p2._type = "dense"
-    p1.coeffs, p2.coeffs  # Ensure _coeffs is created for arithmetic
+    print(p1.coeffs, p2.coeffs)  # Ensure _coeffs is created for arithmetic
     ipython.run_line_magic("timeit", "p1 * p2")
 
     degree += 100
diff --git a/tests/codes/conftest.py b/tests/codes/conftest.py
index 0d7960b89..eb88174d8 100644
--- a/tests/codes/conftest.py
+++ b/tests/codes/conftest.py
@@ -12,8 +12,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def get_filenames(path: pathlib.Path) -> list[str]:
     filenames = []
diff --git a/tests/codes/test_bch.py b/tests/codes/test_bch.py
index 1d8f378bd..c4f20191f 100644
--- a/tests/codes/test_bch.py
+++ b/tests/codes/test_bch.py
@@ -15,8 +15,6 @@
     verify_encode_shortened,
 )
 
-# pylint: disable=line-too-long
-
 
 def test_exceptions():
     with pytest.raises(TypeError):
diff --git a/tests/codes/test_reed_solomon.py b/tests/codes/test_reed_solomon.py
index 0152dd8a0..08e2842e9 100644
--- a/tests/codes/test_reed_solomon.py
+++ b/tests/codes/test_reed_solomon.py
@@ -13,8 +13,6 @@
     verify_encode_shortened,
 )
 
-# pylint: disable=line-too-long
-
 
 def test_exceptions():
     with pytest.raises(TypeError):
diff --git a/tests/fields/conftest.py b/tests/fields/conftest.py
index 81fce0b7e..794b15f5c 100644
--- a/tests/fields/conftest.py
+++ b/tests/fields/conftest.py
@@ -11,8 +11,6 @@
 
 import galois
 
-# pylint: disable=redefined-outer-name
-
 PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
 
 FIELDS = [
diff --git a/tests/fields/data/GF(109987^4)/properties.json b/tests/fields/data/GF(109987^4)/properties.json
index f0bb508a5..5afff3143 100644
--- a/tests/fields/data/GF(109987^4)/properties.json
+++ b/tests/fields/data/GF(109987^4)/properties.json
@@ -10,4 +10,4 @@
         100525,
         3
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2)/properties.json b/tests/fields/data/GF(2)/properties.json
index 5ab0a1019..cc5dacf68 100644
--- a/tests/fields/data/GF(2)/properties.json
+++ b/tests/fields/data/GF(2)/properties.json
@@ -7,4 +7,4 @@
         1,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2147483647)/properties.json b/tests/fields/data/GF(2147483647)/properties.json
index 481d707e2..28d05b55b 100644
--- a/tests/fields/data/GF(2147483647)/properties.json
+++ b/tests/fields/data/GF(2147483647)/properties.json
@@ -7,4 +7,4 @@
         1,
         2147483640
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^100)/properties.json b/tests/fields/data/GF(2^100)/properties.json
index b5bb61e6a..8cd9775a2 100644
--- a/tests/fields/data/GF(2^100)/properties.json
+++ b/tests/fields/data/GF(2^100)/properties.json
@@ -106,4 +106,4 @@
         0,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^2)/properties.json b/tests/fields/data/GF(2^2)/properties.json
index 26bf4a337..a5720231c 100644
--- a/tests/fields/data/GF(2^2)/properties.json
+++ b/tests/fields/data/GF(2^2)/properties.json
@@ -8,4 +8,4 @@
         1,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^3)/properties.json b/tests/fields/data/GF(2^3)/properties.json
index e9ff927ba..f5d74240e 100644
--- a/tests/fields/data/GF(2^3)/properties.json
+++ b/tests/fields/data/GF(2^3)/properties.json
@@ -9,4 +9,4 @@
         1,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^32)/properties.json b/tests/fields/data/GF(2^32)/properties.json
index eb00d9c13..a3c989cfb 100644
--- a/tests/fields/data/GF(2^32)/properties.json
+++ b/tests/fields/data/GF(2^32)/properties.json
@@ -38,4 +38,4 @@
         0,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^8)/properties.json b/tests/fields/data/GF(2^8)/properties.json
index 2d6982b36..6e1f00af7 100644
--- a/tests/fields/data/GF(2^8)/properties.json
+++ b/tests/fields/data/GF(2^8)/properties.json
@@ -14,4 +14,4 @@
         0,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(2^8, 283, 19)/properties.json b/tests/fields/data/GF(2^8, 283, 19)/properties.json
index 220b15e2e..0751e3745 100644
--- a/tests/fields/data/GF(2^8, 283, 19)/properties.json
+++ b/tests/fields/data/GF(2^8, 283, 19)/properties.json
@@ -14,4 +14,4 @@
         1,
         1
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(31)/properties.json b/tests/fields/data/GF(31)/properties.json
index 978d4b90a..8b7f48be1 100644
--- a/tests/fields/data/GF(31)/properties.json
+++ b/tests/fields/data/GF(31)/properties.json
@@ -7,4 +7,4 @@
         1,
         28
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(3191)/properties.json b/tests/fields/data/GF(3191)/properties.json
index d75e057ca..385c0c405 100644
--- a/tests/fields/data/GF(3191)/properties.json
+++ b/tests/fields/data/GF(3191)/properties.json
@@ -7,4 +7,4 @@
         1,
         3180
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(36893488147419103183)/properties.json b/tests/fields/data/GF(36893488147419103183)/properties.json
index 131b417f1..f79abd0ee 100644
--- a/tests/fields/data/GF(36893488147419103183)/properties.json
+++ b/tests/fields/data/GF(36893488147419103183)/properties.json
@@ -7,4 +7,4 @@
         1,
         36893488147419103180
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(5)/properties.json b/tests/fields/data/GF(5)/properties.json
index 2354ce0bf..cfe6e7c8f 100644
--- a/tests/fields/data/GF(5)/properties.json
+++ b/tests/fields/data/GF(5)/properties.json
@@ -7,4 +7,4 @@
         1,
         3
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(7)/properties.json b/tests/fields/data/GF(7)/properties.json
index e45cef186..239be083b 100644
--- a/tests/fields/data/GF(7)/properties.json
+++ b/tests/fields/data/GF(7)/properties.json
@@ -7,4 +7,4 @@
         1,
         4
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(7^3)/properties.json b/tests/fields/data/GF(7^3)/properties.json
index ab8231bca..7624ceae0 100644
--- a/tests/fields/data/GF(7^3)/properties.json
+++ b/tests/fields/data/GF(7^3)/properties.json
@@ -9,4 +9,4 @@
         0,
         4
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/data/GF(7^3, 643, 244)/properties.json b/tests/fields/data/GF(7^3, 643, 244)/properties.json
index c74521b7e..d0d7a5e13 100644
--- a/tests/fields/data/GF(7^3, 643, 244)/properties.json
+++ b/tests/fields/data/GF(7^3, 643, 244)/properties.json
@@ -9,4 +9,4 @@
         0,
         6
     ]
-}
\ No newline at end of file
+}
diff --git a/tests/fields/test_advanced_arithmetic.py b/tests/fields/test_advanced_arithmetic.py
index 44ffc12a5..a7ef7b7bc 100644
--- a/tests/fields/test_advanced_arithmetic.py
+++ b/tests/fields/test_advanced_arithmetic.py
@@ -5,8 +5,6 @@
 
 import numpy as np
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_convolve(field_convolve):
     GF, X, Y, Z = field_convolve["GF"], field_convolve["X"], field_convolve["Y"], field_convolve["Z"]
diff --git a/tests/fields/test_arithmetic.py b/tests/fields/test_arithmetic.py
index 9b93d3a06..f0ff13120 100644
--- a/tests/fields/test_arithmetic.py
+++ b/tests/fields/test_arithmetic.py
@@ -9,8 +9,6 @@
 
 from .conftest import randint
 
-# pylint: disable=unidiomatic-typecheck
-
 # TODO: Add scalar arithmetic and array/scalar and radd, etc
 
 
diff --git a/tests/fields/test_arithmetic_exceptions.py b/tests/fields/test_arithmetic_exceptions.py
index 4a60f4d38..9c934091a 100644
--- a/tests/fields/test_arithmetic_exceptions.py
+++ b/tests/fields/test_arithmetic_exceptions.py
@@ -6,8 +6,6 @@
 
 from .conftest import randint
 
-# pylint: disable=pointless-statement
-
 
 def test_add_int_scalar(field):
     x = field.Random(10)
diff --git a/tests/fields/test_arithmetic_methods.py b/tests/fields/test_arithmetic_methods.py
index 68680051f..bb6a2ddf3 100644
--- a/tests/fields/test_arithmetic_methods.py
+++ b/tests/fields/test_arithmetic_methods.py
@@ -6,8 +6,6 @@
 import numpy as np
 import pytest
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_additive_order(field_additive_order):
     GF, X, Z = field_additive_order["GF"], field_additive_order["X"], field_additive_order["Z"]
diff --git a/tests/fields/test_broadcasting.py b/tests/fields/test_broadcasting.py
index 6c1c1f189..3176dab15 100644
--- a/tests/fields/test_broadcasting.py
+++ b/tests/fields/test_broadcasting.py
@@ -5,7 +5,6 @@
 
 from .conftest import randint
 
-# pylint: disable=unidiomatic-typecheck
 # NOTE: We don't need to verify the arithmetic is correct here, that was done in test_field_arithmetic.py
 
 
diff --git a/tests/fields/test_classes.py b/tests/fields/test_classes.py
index 3e1757119..e65562ab4 100644
--- a/tests/fields/test_classes.py
+++ b/tests/fields/test_classes.py
@@ -8,8 +8,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 
 def test_repr_str():
     GF = galois.GF(7)
diff --git a/tests/fields/test_constructors.py b/tests/fields/test_constructors.py
index c168f4236..279c64c20 100644
--- a/tests/fields/test_constructors.py
+++ b/tests/fields/test_constructors.py
@@ -8,8 +8,6 @@
 
 from .conftest import invalid_dtype, randint, valid_dtype
 
-# pylint: disable=unidiomatic-typecheck
-
 RANDOM_REPRODUCIBLE = {
     "GF(2)-42": galois.GF2([1, 0, 1, 0]),
     "GF(2)-1337": galois.GF2([1, 1, 1, 1]),
diff --git a/tests/fields/test_conversion.py b/tests/fields/test_conversion.py
index ecf90182f..c24ffbf2d 100644
--- a/tests/fields/test_conversion.py
+++ b/tests/fields/test_conversion.py
@@ -6,8 +6,6 @@
 
 from .conftest import DTYPES
 
-# pylint: disable=unidiomatic-typecheck
-
 
 class TestView:
     """
diff --git a/tests/fields/test_instantiation.py b/tests/fields/test_instantiation.py
index e9d962223..5b4fa2dda 100644
--- a/tests/fields/test_instantiation.py
+++ b/tests/fields/test_instantiation.py
@@ -8,8 +8,6 @@
 
 from .conftest import array_equal, invalid_dtype, valid_dtype
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_cant_instantiate_GF():
     v = [0, 1, 0, 1]
diff --git a/tests/fields/test_linalg.py b/tests/fields/test_linalg.py
index 4c5eb5bb5..e2ca1a6ba 100644
--- a/tests/fields/test_linalg.py
+++ b/tests/fields/test_linalg.py
@@ -10,8 +10,6 @@
 
 from .conftest import array_equal
 
-# pylint: disable=unidiomatic-typecheck,pointless-statement
-
 
 def test_dot_exceptions():
     with pytest.raises(TypeError):
diff --git a/tests/fields/test_methods.py b/tests/fields/test_methods.py
index 5c5e053e5..3ef0c81ec 100644
--- a/tests/fields/test_methods.py
+++ b/tests/fields/test_methods.py
@@ -8,8 +8,6 @@
 
 from .conftest import invalid_dtype, valid_dtype
 
-# pylint: disable=unidiomatic-typecheck,line-too-long
-
 
 def test_repr():
     GF = galois.GF(2**3)
diff --git a/tests/fields/test_numpy_functions.py b/tests/fields/test_numpy_functions.py
index 512f68e4c..39ebd9c06 100644
--- a/tests/fields/test_numpy_functions.py
+++ b/tests/fields/test_numpy_functions.py
@@ -10,8 +10,6 @@
 
 from .conftest import array_equal, randint
 
-# pylint: disable=unidiomatic-typecheck
-
 ###############################################################################
 # Basic operations
 ###############################################################################
@@ -244,7 +242,7 @@ def test_split(field):
     shape = (6,)
     new_shape = (3,)
     a = field.Random(shape, dtype=dtype)
-    b1, b2 = np.split(a, 2)  # pylint: disable=unbalanced-tuple-unpacking
+    b1, b2 = np.split(a, 2)
     assert b1.shape == new_shape
     assert type(b1) is field
     assert b1.dtype == dtype
diff --git a/tests/fields/test_numpy_ufuncs.py b/tests/fields/test_numpy_ufuncs.py
index 48790975e..4cf6b575e 100644
--- a/tests/fields/test_numpy_ufuncs.py
+++ b/tests/fields/test_numpy_ufuncs.py
@@ -8,8 +8,6 @@
 
 # TODO: Test using "out" keyword argument
 
-# pylint: disable=no-value-for-parameter
-
 
 class TestReduce:
     """
@@ -166,7 +164,7 @@ def test_add(self, field):
         idxs = [1, 4, 5, 8]
         b = np.add.reduceat(a, idxs)
         b_truth = field.Zeros(len(idxs))
-        for i in range(len(idxs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(idxs)):
             if i == len(idxs) - 1:
                 b_truth[i] = np.add.reduce(a[idxs[i] :])
             else:
@@ -184,7 +182,7 @@ def test_subtract(self, field):
         idxs = [1, 4, 5, 8]
         b = np.subtract.reduceat(a, idxs)
         b_truth = field.Zeros(len(idxs))
-        for i in range(len(idxs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(idxs)):
             if i == len(idxs) - 1:
                 b_truth[i] = np.subtract.reduce(a[idxs[i] :])
             else:
@@ -196,7 +194,7 @@ def test_multiply(self, field):
         idxs = [1, 4, 5, 8]
         b = np.multiply.reduceat(a, idxs)
         b_truth = field.Zeros(len(idxs))
-        for i in range(len(idxs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(idxs)):
             if i == len(idxs) - 1:
                 b_truth[i] = np.multiply.reduce(a[idxs[i] :])
             else:
@@ -214,7 +212,7 @@ def test_divide(self, field):
         idxs = [1, 4, 5, 8]
         b = np.true_divide.reduceat(a, idxs)
         b_truth = field.Zeros(len(idxs))
-        for i in range(len(idxs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(idxs)):
             if i == len(idxs) - 1:
                 b_truth[i] = np.true_divide.reduce(a[idxs[i] :])
             else:
@@ -225,7 +223,7 @@ def test_divide(self, field):
         idxs = [1, 4, 5, 8]
         b = np.floor_divide.reduceat(a, idxs)
         b_truth = field.Zeros(len(idxs))
-        for i in range(len(idxs)):  # pylint: disable=consider-using-enumerate
+        for i in range(len(idxs)):
             if i == len(idxs) - 1:
                 b_truth[i] = np.floor_divide.reduce(a[idxs[i] :])
             else:
diff --git a/tests/fields/test_sqrt.py b/tests/fields/test_sqrt.py
index 9dbf0e01d..5371d2573 100644
--- a/tests/fields/test_sqrt.py
+++ b/tests/fields/test_sqrt.py
@@ -39,8 +39,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 
 def test_binary_field():
     GF = galois.GF(2)
diff --git a/tests/fields/test_squares.py b/tests/fields/test_squares.py
index d6a000a41..394b05575 100644
--- a/tests/fields/test_squares.py
+++ b/tests/fields/test_squares.py
@@ -41,8 +41,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck,line-too-long
-
 
 def test_shapes():
     GF = galois.GF(31)
diff --git a/tests/polys/conftest.py b/tests/polys/conftest.py
index 461a5d475..0e8df4997 100644
--- a/tests/polys/conftest.py
+++ b/tests/polys/conftest.py
@@ -1,6 +1,8 @@
 """
 A pytest conftest module that provides pytest fixtures for galois/polys/ tests.
 """
+# ruff: noqa: F401, F811
+
 import os
 import pickle
 
@@ -9,9 +11,7 @@
 
 import galois
 
-from ..fields.conftest import field, field_folder  # pylint: disable=unused-import
-
-# pylint: disable=redefined-outer-name
+from ..fields.conftest import field, field_folder
 
 ###############################################################################
 # Helper functions
diff --git a/tests/polys/test_arithmetic.py b/tests/polys/test_arithmetic.py
index 6d65abee2..59491e7fd 100644
--- a/tests/polys/test_arithmetic.py
+++ b/tests/polys/test_arithmetic.py
@@ -5,8 +5,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_add(poly_add):
     GF, X, Y, Z = poly_add["GF"], poly_add["X"], poly_add["Y"], poly_add["Z"]
@@ -280,7 +278,7 @@ def test_modular_power_large_exponent_python():
 
 def test_evaluate_constant(poly_evaluate):
     GF, X, Y, Z = poly_evaluate["GF"], poly_evaluate["X"], poly_evaluate["Y"], poly_evaluate["Z"]
-    for i in range(len(X)):  # pylint: disable=consider-using-enumerate
+    for i in range(len(X)):
         j = np.random.default_rng().integers(0, Y.size)
         x = X[i]  # Polynomial
         y = Y[j]  # GF element
@@ -291,7 +289,7 @@ def test_evaluate_constant(poly_evaluate):
 
 def test_evaluate_vector(poly_evaluate):
     GF, X, Y, Z = poly_evaluate["GF"], poly_evaluate["X"], poly_evaluate["Y"], poly_evaluate["Z"]
-    for i in range(len(X)):  # pylint: disable=consider-using-enumerate
+    for i in range(len(X)):
         x = X[i]  # Polynomial
         y = Y  # GF array
         z = x(y)  # GF array
@@ -306,7 +304,7 @@ def test_evaluate_matrix(poly_evaluate_matrix):
         poly_evaluate_matrix["Y"],
         poly_evaluate_matrix["Z"],
     )
-    for i in range(len(X)):  # pylint: disable=consider-using-enumerate
+    for i in range(len(X)):
         x = X[i]  # Polynomial
         y = Y[i]  # GF square matrix
         z = x(y, elementwise=False)  # GF square matrix
diff --git a/tests/polys/test_arithmetic_exceptions.py b/tests/polys/test_arithmetic_exceptions.py
index 0ad763bf6..703cd8530 100644
--- a/tests/polys/test_arithmetic_exceptions.py
+++ b/tests/polys/test_arithmetic_exceptions.py
@@ -5,8 +5,6 @@
 
 import galois
 
-# pylint: disable=pointless-statement
-
 
 def test_true_division_exceptions():
     GF = galois.GF(7)
diff --git a/tests/polys/test_arithmetic_functions.py b/tests/polys/test_arithmetic_functions.py
index 4a1e92e5e..84e173c0f 100644
--- a/tests/polys/test_arithmetic_functions.py
+++ b/tests/polys/test_arithmetic_functions.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck,no-member
-
 
 def test_gcd_exceptions():
     a = galois.Poly.Degrees([10, 9, 8, 6, 5, 4, 0])
diff --git a/tests/polys/test_arithmetic_methods.py b/tests/polys/test_arithmetic_methods.py
index 8d82693b0..2c6094ba4 100644
--- a/tests/polys/test_arithmetic_methods.py
+++ b/tests/polys/test_arithmetic_methods.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_reverse(poly_reverse):
     GF, X, Z = poly_reverse["GF"], poly_reverse["X"], poly_reverse["Z"]
diff --git a/tests/polys/test_constructors.py b/tests/polys/test_constructors.py
index 32e59e21a..0661549aa 100644
--- a/tests/polys/test_constructors.py
+++ b/tests/polys/test_constructors.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 FIELDS = [
     galois.GF2,  # GF(2)
     galois.GF(31),  # GF(p) with np.int dtypes
diff --git a/tests/polys/test_instantiation.py b/tests/polys/test_instantiation.py
index 6ab354d4d..afe4188a5 100644
--- a/tests/polys/test_instantiation.py
+++ b/tests/polys/test_instantiation.py
@@ -8,8 +8,6 @@
 
 import galois
 
-# pylint: disable=redefined-outer-name
-
 FIELDS = [
     galois.GF2,  # GF(2)
     galois.GF(31),  # GF(p) with np.int dtypes
diff --git a/tests/polys/test_lagrange_poly.py b/tests/polys/test_lagrange_poly.py
index 0b2e411fd..ec0a2cf16 100644
--- a/tests/polys/test_lagrange_poly.py
+++ b/tests/polys/test_lagrange_poly.py
@@ -13,8 +13,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_exceptions():
     GF = galois.GF(251)
diff --git a/tests/polys/test_non_poly_arithmetic.py b/tests/polys/test_non_poly_arithmetic.py
index f5e22cda1..1c32cef6f 100644
--- a/tests/polys/test_non_poly_arithmetic.py
+++ b/tests/polys/test_non_poly_arithmetic.py
@@ -5,8 +5,6 @@
 
 import galois
 
-# pylint: disable=pointless-statement,expression-not-assigned
-
 
 def test_add():
     GF = galois.GF(3)
diff --git a/tests/polys/test_operations.py b/tests/polys/test_operations.py
index 3aa1727ba..7711b8195 100644
--- a/tests/polys/test_operations.py
+++ b/tests/polys/test_operations.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=unidiomatic-typecheck
-
 
 def test_coefficients_exceptions():
     GF = galois.GF(7)
diff --git a/tests/test_berlekamp_massey.py b/tests/test_berlekamp_massey.py
index c0872f1c6..7fc353ca4 100644
--- a/tests/test_berlekamp_massey.py
+++ b/tests/test_berlekamp_massey.py
@@ -10,8 +10,6 @@
 
 import galois
 
-# pylint: disable=line-too-long,unidiomatic-typecheck
-
 
 def test_berlekamp_massey_exceptions():
     GF = galois.GF(2)
diff --git a/tests/test_factor.py b/tests/test_factor.py
index 3ff7a7477..4e787c45f 100644
--- a/tests/test_factor.py
+++ b/tests/test_factor.py
@@ -24,8 +24,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 FACTORS_SMALL = [
     (311633, [7, 44519], [1, 1]),
     (557246, [2, 278623], [1, 1]),
diff --git a/tests/test_fibonacci_lfsr.py b/tests/test_fibonacci_lfsr.py
index a4e147dd5..00e55aad3 100644
--- a/tests/test_fibonacci_lfsr.py
+++ b/tests/test_fibonacci_lfsr.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=line-too-long,unidiomatic-typecheck
-
 # These two polys allow for testing JIT compiled and pure-Python implementations
 CHARACTERISTIC_POLYS = [
     galois.primitive_poly(7, 4),
diff --git a/tests/test_galois_lfsr.py b/tests/test_galois_lfsr.py
index a590b9f18..d26cb9767 100644
--- a/tests/test_galois_lfsr.py
+++ b/tests/test_galois_lfsr.py
@@ -6,8 +6,6 @@
 
 import galois
 
-# pylint: disable=line-too-long,unidiomatic-typecheck
-
 # These two polys allow for testing JIT compiled and pure-Python implementations
 CHARACTERISTIC_POLYS = [
     galois.primitive_poly(7, 4),
diff --git a/tests/test_modular.py b/tests/test_modular.py
index 01e2b9eff..75f85a4b6 100644
--- a/tests/test_modular.py
+++ b/tests/test_modular.py
@@ -7,8 +7,6 @@
 
 import galois
 
-# pylint: disable=line-too-long,use-implicit-booleaness-not-comparison
-
 
 def test_smallest_primitive_root():
     # https://oeis.org/A046145
diff --git a/tests/test_number_theory.py b/tests/test_number_theory.py
index 6c28ab1e4..5439311a3 100644
--- a/tests/test_number_theory.py
+++ b/tests/test_number_theory.py
@@ -5,8 +5,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 
 def test_totatives_exceptions():
     with pytest.raises(TypeError):
diff --git a/tests/test_primes.py b/tests/test_primes.py
index 682048a83..d86990c36 100644
--- a/tests/test_primes.py
+++ b/tests/test_primes.py
@@ -7,8 +7,6 @@
 
 import galois
 
-# pylint: disable=line-too-long
-
 
 def test_primes_exceptions():
     with pytest.raises(TypeError):
@@ -49,6 +47,17 @@ def test_prev_prime(prev_prime):
         assert galois.prev_prime(x) == z
 
 
+def test_prev_prime_large():
+    """
+    https://github.com/mhostetter/galois/issues/529
+    """
+    assert galois.prev_prime(100000034) == 100000007
+    assert galois.prev_prime(100000035) == 100000007
+    assert galois.prev_prime(100000036) == 100000007
+    assert galois.prev_prime(100000037) == 100000037
+    assert galois.prev_prime(100000038) == 100000037
+
+
 def test_next_prime_exceptions():
     with pytest.raises(TypeError):
         galois.next_prime(20.0)
@@ -60,6 +69,17 @@ def test_next_prime(next_prime):
         assert galois.next_prime(x) == z
 
 
+def test_next_prime_large():
+    """
+    https://github.com/mhostetter/galois/issues/528
+    """
+    assert galois.next_prime(100000034) == 100000037
+    assert galois.next_prime(100000035) == 100000037
+    assert galois.next_prime(100000036) == 100000037
+    assert galois.next_prime(100000037) == 100000039
+    assert galois.next_prime(100000038) == 100000039
+
+
 def test_random_prime_exceptions():
     with pytest.raises(TypeError):
         galois.random_prime(10.0)