diff --git a/.travis.yml b/.travis.yml
index e4cf6fd9..5f5a2d0c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,6 @@ addons:
   apt:
     packages:
     - pandoc
-    - enchant
   firefox: latest
 before_install:
   - pip install -U pip wheel setuptools
diff --git a/appveyor.yml b/appveyor.yml
index 947f1f0f..e116b6a0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -34,7 +34,7 @@ install:
   - cmd: python -c "import struct; print(struct.calcsize('P') * 8)"
 
   - cmd: pip install -U wheel
-  - cmd: pip install -r dev-requirements-windows.txt .
+  - cmd: pip install -r dev-requirements.txt .
 
   # Install and early check enable extensions before the actual tests
   - cmd: python setup.py install
diff --git a/dev-requirements-windows.txt b/dev-requirements-windows.txt
deleted file mode 100644
index 05d636c0..00000000
--- a/dev-requirements-windows.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-pytest>=4.0
-pytest-cov
-pytest-rerunfailures
-coverage
-selenium
-invoke
-sphinx
-codecov
-nbval
diff --git a/dev-requirements.txt b/dev-requirements.txt
index b1f6c401..d2e3f3d5 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,5 +1,10 @@
--r dev-requirements-windows.txt
-pyenchant
-sphinxcontrib-spelling
+pytest>=4.0
+pytest-cov
+pytest-rerunfailures
+coverage
+selenium
+invoke
+sphinx
 sphinx_rtd_theme
+codecov
 nbval
\ No newline at end of file
diff --git a/nbgrader/api.py b/nbgrader/api.py
index 26adbadb..ab4bf578 100644
--- a/nbgrader/api.py
+++ b/nbgrader/api.py
@@ -275,8 +275,7 @@ class SolutionCell(Base):
         }
 
     def __repr__(self):
-        return "SolutionCell<{}/{}/{}>".format(
-            self.assignment.name, self.notebook.name, self.name)
+        return "{}/{}".format(self.notebook, self.name)
 
 
 class SourceCell(Base):
@@ -333,7 +332,7 @@ class SourceCell(Base):
         }
 
     def __repr__(self):
-        return "SourceCell<{}/{}/{}>".format(
+        return "SolutionCell<{}/{}/{}>".format(
             self.assignment.name, self.notebook.name, self.name)
 
 
diff --git a/nbgrader/docs/Makefile b/nbgrader/docs/Makefile
index 6f49818c..f8c24928 100644
--- a/nbgrader/docs/Makefile
+++ b/nbgrader/docs/Makefile
@@ -46,7 +46,6 @@ help:
 	@echo "  linkcheck  to check all external links for integrity"
 	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
 	@echo "  coverage   to run coverage check of the documentation (if enabled)"
-	@echo "  spelling   to run the spell checker"
 
 clean:
 	rm -rf $(BUILDDIR)/*
@@ -163,11 +162,6 @@ linkcheck:
 	@echo "Link check complete; look for any errors in the above output " \
 	      "or in $(BUILDDIR)/linkcheck/output.txt."
 
-spelling:
-	$(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling
-	@echo
-	@echo "Spell check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/spelling/output.txt."
 doctest:
 	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
 	@echo "Testing of doctests in the sources finished, look at the " \
diff --git a/nbgrader/docs/source/conf.py b/nbgrader/docs/source/conf.py
index 8054b388..6b608a34 100644
--- a/nbgrader/docs/source/conf.py
+++ b/nbgrader/docs/source/conf.py
@@ -34,13 +34,6 @@ extensions = [
     'sphinx.ext.napoleon'
 ]
 
-try:
-    import sphinxcontrib.spelling
-except ImportError:
-    pass
-else:
-    extensions.append("sphinxcontrib.spelling")
-
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
diff --git a/nbgrader/docs/source/contributor_guide/documentation.rst b/nbgrader/docs/source/contributor_guide/documentation.rst
index edcdd004..fe018d97 100644
--- a/nbgrader/docs/source/contributor_guide/documentation.rst
+++ b/nbgrader/docs/source/contributor_guide/documentation.rst
@@ -30,11 +30,6 @@ the rst version of it to ``.gitignore``.
 Building documentation locally
 ------------------------------
 
-.. warning::
-
-  Building the docs is not currently well-supported on Windows. This is because one of
-  the dependencies (enchant) does not install easily in Windows.
-
 If you have made changes to the user guide or other notebooks that need to be
 executed, please make sure you re-run all the documentation before committing.
 While the documentation gets built automatically on Read The Docs, the notebooks do **not** get execute by Read The Docs -- they must be executed manually.
diff --git a/nbgrader/docs/source/contributor_guide/installation_developer.rst b/nbgrader/docs/source/contributor_guide/installation_developer.rst
index 3302882b..399e5fae 100644
--- a/nbgrader/docs/source/contributor_guide/installation_developer.rst
+++ b/nbgrader/docs/source/contributor_guide/installation_developer.rst
@@ -15,11 +15,6 @@ nbgrader installs and builds with one command::
 
     pip install -r dev-requirements.txt -e .
 
-Currently, building docs is not supported on Windows because some of the dependencies (enchant)
-are not easily installable. Instead of the above command, run the following on windows::
-
-    pip install -r dev-requirements-windows.txt -e .
-
 
 Installing notebook extensions
 ------------------------------
diff --git a/nbgrader/docs/source/spelling_wordlist.txt b/nbgrader/docs/source/spelling_wordlist.txt
deleted file mode 100644
index 659c55e6..00000000
--- a/nbgrader/docs/source/spelling_wordlist.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-adamchainz
-admin
-Afterwards
-ajax
-alchemyst
-alikasamanli
-alope
-api
-app
-apps
-arcticbarra
-aren
-aren’t
-asctime
-auth
-authenticator
-Autograde
-autograde
-autogradeapp
-autograded
-Autograded
-autograder
-Autograder
-autogrades
-autograding
-backends
-basename
-Bitdiddle
-Bitdiddle’s
-bugfix
-bugfixes
-bugtracker
-camelcase
-can’t
-Carreau
-cell’s
-Changelog
-changelog
-checksum
-checksums
-codecov
-cogsci
-conda
-config
-contextmanager
-CSS
-customizable
-cwd
-datefmt
-ddbourgin
-deletable
-delimeters
-dementrock
-deprecations
-dev
-dir
-dirs
-dlsun
-doesn
-doesn’t
-don’t
-Don’t
-dropdown
-dsblank
-duedate
-Duedate
-ellachao
-ellisonbg
-embanner
-entrypoint
-feedstock
-filename
-filenames
-Filenames
-filesystem
-formatters
-formgrade
-formgrader
-frontend
-gif
-globbing
-Gradebook
-gradebook
-Granger
-grepping
-hardcoded
-hasn
-hasn’t
-haven
-HeLLo
-hetland
-hOlle
-Homebrew
-html
-https
-hubapi
-huwf
-Indices
-indices
-init
-inline
-installable
-institution’s
-instructor’s
-io
-iopub
-ipynb
-IPython
-ischurov
-isn
-isn’t
-it’s
-ivanslapnicar
-ixjlyons
-I’m
-I’ve
-Javascript
-jcsutherland
-jdfreder
-jhamrick
-jilljenn
-jklymak
-jonathanmorgan
-joschu
-JUPYTER
-Jupyter
-jupyter
-jupyterhub
-katyhuff
-kernelspec
-ksunden
-Let’s
-let’s
-lgpage
-linkcheck
-linux
-localhost
-logfile
-lphk
-mandli
-Marr
-marr
-mathjax
-matplotlib
-metadata
-mikebolt
-minrk
-misolietavec
-mpacer
-multi
-namespace
-nbconvert
-nbextension
-nbextensions
-nbgrader
-nbgrader’s
-ncclementi
-neuroscience
-np
-npm
-ok
-olgabot
-online
-Ordo
-org
-osx
-overwritekernelspec
-phantomjs
-Phantomjs
-plugin
-plugins
-positionally
-postgres
-prepend
-prepending
-prepopulate
-preprocessor
-Preprocessor
-preprocessors
-prev
-Programmatically
-programmatically
-ps
-py
-quickstart
-rdpratti
-readonly
-readthedocs
-redSlug
-Refactor
-reinstall
-resize
-rst
-runtime
-sansary
-scipy
-serverextension
-sha
-shouldn
-shouldn’t
-smeylan
-spellcheck
-SQL
-sqlite
-startup
-stdin
-stdout
-stoppped
-student’s
-subclasses
-subcommand
-subcommands
-subpackage
-subdirectory
-suchow
-suprocesses
-svurens
-symlink
-sys
-systemwide
-Szepi
-tasilb
-they’d
-threadsafe
-timestamp
-timestamps
-todo
-toolbar
-travis
-un
-undeletable
-Undeprecate
-unicode
-uninstall
-unlink
-untracked
-url
-username
-usernames
-utcnow
-validator
-ve
-vinaykola
-webapp
-webdriver
-weren
-weren’t
-we’ll
-We’re
-we’ve
-What’s
-whitead
-whitespace
-whositwhatnow
-Wildcards
-willingc
-won’t
-wordlist
-wordslist
-Workflow
-workflow
-workflows
-xsrf
-XSRF
-yml
-you’ll
-Zesje
-zpincus
diff --git a/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb b/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb
index 9d543874..1597d9c4 100644
--- a/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb
+++ b/nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb
@@ -858,9 +858,7 @@
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/timestamp.txt -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/timestamp.txt\n",
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/jupyter.png -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/jupyter.png\n",
       "[AutogradeApp | INFO] Creating/updating student with ID 'bitdiddle': {}\n",
-      "/Users/jhamrick/miniconda3/envs/nbgrader/lib/python3.6/site-packages/dateutil/parser/_parser.py:1204: UnknownTimezoneWarning: tzname PST identified but not understood.  Pass `tzinfos` argument in order to correctly return a timezone-aware datetime.  In a future version, this will raise an exception.\n",
-      "  category=UnknownTimezoneWarning)\n",
-      "[AutogradeApp | INFO] SubmittedAssignment<ps1 for bitdiddle> submitted at 2015-02-02 14:58:23.948203\n",
+      "[AutogradeApp | INFO] SubmittedAssignment<ps1 for bitdiddle> submitted at 2015-02-02 22:58:23.948203\n",
       "[AutogradeApp | INFO] Overwriting files with master versions from the source directory\n",
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/source/./ps1/jupyter.png -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/bitdiddle/ps1/jupyter.png\n",
       "[AutogradeApp | INFO] Sanitizing /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/bitdiddle/ps1/problem1.ipynb\n",
@@ -883,9 +881,7 @@
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/hacker/ps1/timestamp.txt -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/hacker/ps1/timestamp.txt\n",
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/hacker/ps1/jupyter.png -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/hacker/ps1/jupyter.png\n",
       "[AutogradeApp | INFO] Creating/updating student with ID 'hacker': {}\n",
-      "/Users/jhamrick/miniconda3/envs/nbgrader/lib/python3.6/site-packages/dateutil/parser/_parser.py:1204: UnknownTimezoneWarning: tzname PST identified but not understood.  Pass `tzinfos` argument in order to correctly return a timezone-aware datetime.  In a future version, this will raise an exception.\n",
-      "  category=UnknownTimezoneWarning)\n",
-      "[AutogradeApp | INFO] SubmittedAssignment<ps1 for hacker> submitted at 2015-02-01 09:28:58.749302\n",
+      "[AutogradeApp | INFO] SubmittedAssignment<ps1 for hacker> submitted at 2015-02-01 17:28:58.749302\n",
       "[AutogradeApp | INFO] Overwriting files with master versions from the source directory\n",
       "[AutogradeApp | INFO] Copying /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/source/./ps1/jupyter.png -> /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/autograded/hacker/ps1/jupyter.png\n",
       "[AutogradeApp | INFO] Sanitizing /Users/jhamrick/project/tools/nbgrader/nbgrader/docs/source/user_guide/submitted/hacker/ps1/problem1.ipynb\n",
@@ -1171,8 +1167,8 @@
      "output_type": "stream",
      "text": [
       "assignment,duedate,timestamp,student_id,last_name,first_name,email,raw_score,late_submission_penalty,score,max_score\n",
-      "ps1,,2015-02-02 14:58:23.948203,bitdiddle,,,,1.5,0.0,1.5,9.0\n",
-      "ps1,,2015-02-01 09:28:58.749302,hacker,,,,3.0,0.0,3.0,9.0\n"
+      "ps1,,2015-02-02 22:58:23.948203,bitdiddle,,,,1.5,0.0,1.5,9.0\n",
+      "ps1,,2015-02-01 17:28:58.749302,hacker,,,,3.0,0.0,3.0,9.0\n"
      ]
     }
    ],
diff --git a/nbgrader/docs/source/user_guide/grades.csv b/nbgrader/docs/source/user_guide/grades.csv
index aef3cf12..39830a95 100644
--- a/nbgrader/docs/source/user_guide/grades.csv
+++ b/nbgrader/docs/source/user_guide/grades.csv
@@ -1,3 +1,3 @@
 assignment,duedate,timestamp,student_id,last_name,first_name,email,raw_score,late_submission_penalty,score,max_score
-ps1,,2015-02-02 14:58:23.948203,bitdiddle,,,,1.5,0.0,1.5,9.0
-ps1,,2015-02-01 09:28:58.749302,hacker,,,,3.0,0.0,3.0,9.0
+ps1,,2015-02-02 22:58:23.948203,bitdiddle,,,,1.5,0.0,1.5,9.0
+ps1,,2015-02-01 17:28:58.749302,hacker,,,,3.0,0.0,3.0,9.0
diff --git a/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb b/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb
index 11d0150d..57b8ce52 100644
--- a/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb
+++ b/nbgrader/docs/source/user_guide/managing_assignment_files.ipynb
@@ -415,9 +415,9 @@
      "output_type": "stream",
      "text": [
       "total 40\n",
-      "-rw-r--r--  1 jhamrick  wheel  5733 Oct  6 17:36 jupyter.png\n",
-      "-rw-r--r--  1 jhamrick  wheel  8126 Oct  6 17:36 problem1.ipynb\n",
-      "-rw-r--r--  1 jhamrick  wheel  2318 Oct  6 17:36 problem2.ipynb\n"
+      "-rw-r--r--  1 jhamrick  wheel  5733 Dec 15 17:17 jupyter.png\n",
+      "-rw-r--r--  1 jhamrick  wheel  8126 Dec 15 17:17 problem1.ipynb\n",
+      "-rw-r--r--  1 jhamrick  wheel  2318 Dec 15 17:17 problem2.ipynb\n"
      ]
     }
    ],
@@ -585,8 +585,8 @@
      "output_type": "stream",
      "text": [
       "[SubmitApp | INFO] Source: /private/tmp/student_home/ps1\n",
-      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-10-06 16:37:03.739479 UTC\n",
-      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-10-06 16:37:03.739479 UTC\n"
+      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-12-15 17:18:32.292300 UTC+SBHB54_xB6XI\n",
+      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-12-15 17:18:32.292300 UTC\n"
      ]
     }
    ],
@@ -614,9 +614,9 @@
      "output_type": "stream",
      "text": [
       "total 8\n",
-      "drwxr-xr-x  3 jhamrick  wheel   96 Oct  6 17:37 Library\n",
-      "-rw-r--r--  1 jhamrick  wheel   91 Oct  6 17:37 nbgrader_config.py\n",
-      "drwxr-xr-x  5 jhamrick  wheel  160 Oct  6 17:36 ps1\n"
+      "drwxr-xr-x  3 jhamrick  wheel   96 Dec 15 17:18 Library\n",
+      "-rw-r--r--  1 jhamrick  wheel   91 Dec 15 17:18 nbgrader_config.py\n",
+      "drwxr-xr-x  5 jhamrick  wheel  160 Dec 15 17:17 ps1\n"
      ]
     }
    ],
@@ -644,7 +644,7 @@
      "output_type": "stream",
      "text": [
       "[ListApp | INFO] Submitted assignments:\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:03.739479 UTC\n"
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:32.292300 UTC\n"
      ]
     }
    ],
@@ -672,8 +672,8 @@
      "output_type": "stream",
      "text": [
       "[SubmitApp | INFO] Source: /private/tmp/student_home/ps1\n",
-      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-10-06 16:37:05.934015 UTC\n",
-      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-10-06 16:37:05.934015 UTC\n"
+      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-12-15 17:18:34.502342 UTC+tgNu5WuM-0ey\n",
+      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-12-15 17:18:34.502342 UTC\n"
      ]
     }
    ],
@@ -701,8 +701,8 @@
      "output_type": "stream",
      "text": [
       "[ListApp | INFO] Submitted assignments:\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:03.739479 UTC\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:05.934015 UTC\n"
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:32.292300 UTC\n",
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:34.502342 UTC\n"
      ]
     }
    ],
@@ -737,7 +737,7 @@
      "output_type": "stream",
      "text": [
       "[SubmitApp | INFO] Source: /private/tmp/student_home/ps1\n",
-      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-10-06 16:37:08.124699 UTC\n",
+      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-12-15 17:18:36.653610 UTC+4SxeiREB6SQ0\n",
       "[SubmitApp | WARNING] Possible missing notebooks and/or extra notebooks submitted for assignment ps1:\n",
       "    Expected:\n",
       "    \tproblem1.ipynb: MISSING\n",
@@ -745,7 +745,7 @@
       "    Submitted:\n",
       "    \tmyproblem1.ipynb: EXTRA\n",
       "    \tproblem2.ipynb: OK\n",
-      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-10-06 16:37:08.124699 UTC\n"
+      "[SubmitApp | INFO] Submitted as: example_course ps1 2018-12-15 17:18:36.653610 UTC\n"
      ]
     }
    ],
@@ -809,7 +809,7 @@
      "output_type": "stream",
      "text": [
       "[SubmitApp | INFO] Source: /private/tmp/student_home/ps1\n",
-      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-10-06 16:37:09.230064 UTC\n",
+      "[SubmitApp | INFO] Destination: /tmp/exchange/example_course/inbound/jhamrick+ps1+2018-12-15 17:18:38.230320 UTC+4CSjGeK7SEjh\n",
       "[SubmitApp | CRITICAL] Assignment ps1 not submitted. There are missing notebooks for the submission:\n",
       "    Expected:\n",
       "    \tproblem1.ipynb: MISSING\n",
@@ -935,9 +935,9 @@
      "output_type": "stream",
      "text": [
       "[ListApp | INFO] Submitted assignments:\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:03.739479 UTC\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:05.934015 UTC\n",
-      "[ListApp | INFO] example_course jhamrick ps1 2018-10-06 16:37:08.124699 UTC\n"
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:32.292300 UTC\n",
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:34.502342 UTC\n",
+      "[ListApp | INFO] example_course jhamrick ps1 2018-12-15 17:18:36.653610 UTC\n"
      ]
     }
    ],
@@ -993,7 +993,7 @@
       "total 0\n",
       "drwxr-xr-x  3 jhamrick  staff  96 May 31  2017 bitdiddle\n",
       "drwxr-xr-x  3 jhamrick  staff  96 May 31  2017 hacker\n",
-      "drwxr-xr-x  3 jhamrick  staff  96 Oct  6 17:37 jhamrick\n"
+      "drwxr-xr-x  3 jhamrick  staff  96 Dec 15 17:18 jhamrick\n"
      ]
     }
    ],
diff --git a/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb b/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb
index 4870b947..dd51e04b 100644
--- a/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb
+++ b/nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb
@@ -180,8 +180,8 @@
      "output_type": "stream",
      "text": [
       "total 64\n",
-      "-rw-r--r--  1 jhamrick  staff  18465 May  7 23:26 notebooks.zip\n",
-      "-rw-------  1 jhamrick  staff   8870 Oct  6 17:36 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n"
+      "-rw-r--r--  1 jhamrick  staff  18465 Dec 15 16:15 notebooks.zip\n",
+      "-rw-r--r--  1 jhamrick  staff   8870 Dec 15 17:17 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n"
      ]
     }
    ],
@@ -259,8 +259,8 @@
      "output_type": "stream",
      "text": [
       "total 64\n",
-      "-rw-r--r--  1 jhamrick  staff  18465 May  7 23:26 notebooks.zip\n",
-      "-rw-------  1 jhamrick  staff   8870 Oct  6 17:36 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n"
+      "-rw-r--r--  1 jhamrick  staff  18465 Dec 15 16:15 notebooks.zip\n",
+      "-rw-r--r--  1 jhamrick  staff   8870 Dec 15 17:17 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n"
      ]
     }
    ],
@@ -410,15 +410,15 @@
      "output_type": "stream",
      "text": [
       "total 24\n",
-      "drwxr-xr-x  8 jhamrick  staff   256 Oct  6 17:37 notebooks\n",
-      "-rw-------  1 jhamrick  staff  8870 Oct  6 17:37 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n",
+      "drwxr-xr-x  8 jhamrick  staff   256 Dec 15 17:18 notebooks\n",
+      "-rw-r--r--  1 jhamrick  staff  8870 Dec 15 17:18 ps1_hacker_attempt_2016-01-30-20-30-10_problem1.ipynb\n",
       "total 88\n",
-      "-rw-rw-r--  1 jhamrick  staff  5733 Oct  6 17:37 ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n",
-      "-rw-rw-r--  1 jhamrick  staff  7954 Oct  6 17:37 ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n",
-      "-rw-rw-r--  1 jhamrick  staff  2288 Oct  6 17:37 ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem2.ipynb\n",
-      "-rw-rw-r--  1 jhamrick  staff  5733 Oct  6 17:37 ps1_hacker_attempt_2016-01-30-16-30-10_jupyter.png\n",
-      "-rw-rw-r--  1 jhamrick  staff  9072 Oct  6 17:37 ps1_hacker_attempt_2016-01-30-16-30-10_myproblem1.ipynb\n",
-      "-rw-rw-r--  1 jhamrick  staff  2418 Oct  6 17:37 ps1_hacker_attempt_2016-01-30-16-30-10_problem2.ipynb\n"
+      "-rw-rw-r--  1 jhamrick  staff  5733 Dec 15 17:18 ps1_bitdiddle_attempt_2016-01-30-15-30-10_jupyter.png\n",
+      "-rw-rw-r--  1 jhamrick  staff  7954 Dec 15 17:18 ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem1.ipynb\n",
+      "-rw-rw-r--  1 jhamrick  staff  2288 Dec 15 17:18 ps1_bitdiddle_attempt_2016-01-30-15-30-10_problem2.ipynb\n",
+      "-rw-rw-r--  1 jhamrick  staff  5733 Dec 15 17:18 ps1_hacker_attempt_2016-01-30-16-30-10_jupyter.png\n",
+      "-rw-rw-r--  1 jhamrick  staff  9072 Dec 15 17:18 ps1_hacker_attempt_2016-01-30-16-30-10_myproblem1.ipynb\n",
+      "-rw-rw-r--  1 jhamrick  staff  2418 Dec 15 17:18 ps1_hacker_attempt_2016-01-30-16-30-10_problem2.ipynb\n"
      ]
     }
    ],
@@ -448,8 +448,8 @@
      "output_type": "stream",
      "text": [
       "total 0\n",
-      "drwxr-xr-x  3 jhamrick  staff  96 Oct  6 17:37 bitdiddle\n",
-      "drwxr-xr-x  3 jhamrick  staff  96 Oct  6 17:37 hacker\n"
+      "drwxr-xr-x  3 jhamrick  staff  96 Dec 15 17:18 bitdiddle\n",
+      "drwxr-xr-x  3 jhamrick  staff  96 Dec 15 17:18 hacker\n"
      ]
     }
    ],
@@ -469,9 +469,9 @@
      "output_type": "stream",
      "text": [
       "total 40\n",
-      "-rw-------  1 jhamrick  staff  8870 Oct  6 17:37 problem1.ipynb\n",
-      "-rw-rw-r--  1 jhamrick  staff  2418 Oct  6 17:37 problem2.ipynb\n",
-      "-rw-r--r--  1 jhamrick  staff    19 Oct  6 17:37 timestamp.txt\n"
+      "-rw-r--r--  1 jhamrick  staff  8870 Dec 15 17:18 problem1.ipynb\n",
+      "-rw-rw-r--  1 jhamrick  staff  2418 Dec 15 17:18 problem2.ipynb\n",
+      "-rw-r--r--  1 jhamrick  staff    19 Dec 15 17:18 timestamp.txt\n"
      ]
     }
    ],
diff --git a/tasks.py b/tasks.py
index 23083d9f..dca25883 100644
--- a/tasks.py
+++ b/tasks.py
@@ -45,7 +45,6 @@ def docs(ctx):
     run(ctx, 'python nbgrader/docs/source/clear_docs.py')
     run(ctx, 'make -C nbgrader/docs html')
     run(ctx, 'make -C nbgrader/docs linkcheck')
-    run(ctx, 'make -C nbgrader/docs spelling')
 
 
 @task

pyenchant is unmaintained
There doesn't appear to be anyone stepping forward to take over maintenance. This dependency may be an issue going forward. https://github.com/rfk/pyenchant/network

Cc: https://github.com/openjournals/jose-reviews/issues/32
diff --git a/nbgrader/docs/source/contributor_guide/testing.rst b/nbgrader/docs/source/contributor_guide/testing.rst
index c70730a5..b5e72302 100644
--- a/nbgrader/docs/source/contributor_guide/testing.rst
+++ b/nbgrader/docs/source/contributor_guide/testing.rst
@@ -28,7 +28,7 @@ commands:
 | ``invoke tests --group=nbextensions`` | Run tests only for the notebook    |
 |                                       | extensions                         |
 +---------------------------------------+------------------------------------+
-| ``invoke tests --group=docs``         | Build the docs and check spelling  |
+| ``invoke tests --group=docs``         | Build the docs                     |
 +---------------------------------------+------------------------------------+
 | ``invoke tests --group=all``          | Same as ``invoke tests``           |
 +---------------------------------------+------------------------------------+
diff --git a/nbgrader/tests/api/test_models.py b/nbgrader/tests/api/test_models.py
index ad307399..1585d298 100644
--- a/nbgrader/tests/api/test_models.py
+++ b/nbgrader/tests/api/test_models.py
@@ -146,8 +146,6 @@ def test_create_solution_cell(db):
     assert s.comments == []
     assert n.solution_cells == [s]
 
-    assert repr(s) == "SolutionCell<foo/blah/foo>"
-
 
 def test_create_source_cell(db):
     now = datetime.datetime.utcnow()
@@ -169,7 +167,7 @@ def test_create_source_cell(db):
     assert s.notebook == n
     assert n.source_cells == [s]
 
-    assert repr(s) == "SourceCell<foo/blah/foo>"
+    assert repr(s) == "SolutionCell<foo/blah/foo>"
 
 
 def test_create_student(db):

pip install -e .[dev]
parse_log_pytest
requirements.txt
pyenchant sphinxcontrib-spelling sphinx_rtd_theme nbval pytest
apt-get update apt-get install -y gcc
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
alembic==1.7.7
anyio==3.6.2
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
async-generator==1.10
attrs==22.2.0
Babel==2.11.0
backcall==0.2.0
bleach==4.1.0
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
comm==0.1.4
contextvars==2.4
coverage==6.2
dataclasses==0.8
decorator==5.1.1
defusedxml==0.7.1
docutils==0.18.1
entrypoints==0.4
fuzzywuzzy==0.18.0
greenlet==2.0.2
idna==3.10
imagesize==1.4.1
immutables==0.19
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
ipykernel==5.5.6
ipython==7.16.3
ipython-genutils==0.2.0
ipywidgets==7.8.5
jedi==0.17.2
Jinja2==3.0.3
json5==0.9.16
jsonschema==3.2.0
jupyter==1.1.1
jupyter-client==7.1.2
jupyter-console==6.4.3
jupyter-core==4.9.2
jupyter-server==1.13.1
jupyterlab==3.2.9
jupyterlab-pygments==0.1.2
jupyterlab-server==2.10.3
jupyterlab_widgets==1.1.11
Mako==1.1.6
MarkupSafe==2.0.1
mistune==0.8.4
nbclassic==0.3.5
nbclient==0.5.9
nbconvert==6.0.7
nbformat==5.1.3
-e git+https://github.com/jupyter/nbgrader.git@fb677016e974bfe1764028b8358cce7bb277443d#egg=nbgrader
nbval==0.10.0
nest-asyncio==1.6.0
notebook==6.4.10
packaging==21.3
pandocfilters==1.5.1
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
pluggy==1.0.0
prometheus-client==0.17.1
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
pycparser==2.21
pyenchant==3.2.2
Pygments==2.14.0
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==25.1.2
requests==2.27.1
Send2Trash==1.8.3
six==1.17.0
sniffio==1.2.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-spelling==7.7.0
SQLAlchemy==1.4.54
terminado==0.12.1
testpath==0.6.0
tomli==1.2.3
tornado==6.1
traitlets==4.3.3
typing_extensions==4.1.1
urllib3==1.26.20
wcwidth==0.2.13
webencodings==0.5.1
websocket-client==1.3.1
widgetsnbextension==3.6.10
zipp==3.6.0

name: nbgrader
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - alembic==1.7.7
      - anyio==3.6.2
      - argon2-cffi==21.3.0
      - argon2-cffi-bindings==21.2.0
      - async-generator==1.10
      - attrs==22.2.0
      - babel==2.11.0
      - backcall==0.2.0
      - bleach==4.1.0
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - comm==0.1.4
      - contextvars==2.4
      - coverage==6.2
      - dataclasses==0.8
      - decorator==5.1.1
      - defusedxml==0.7.1
      - docutils==0.18.1
      - entrypoints==0.4
      - fuzzywuzzy==0.18.0
      - greenlet==2.0.2
      - idna==3.10
      - imagesize==1.4.1
      - immutables==0.19
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - ipykernel==5.5.6
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - ipywidgets==7.8.5
      - jedi==0.17.2
      - jinja2==3.0.3
      - json5==0.9.16
      - jsonschema==3.2.0
      - jupyter==1.1.1
      - jupyter-client==7.1.2
      - jupyter-console==6.4.3
      - jupyter-core==4.9.2
      - jupyter-server==1.13.1
      - jupyterlab==3.2.9
      - jupyterlab-pygments==0.1.2
      - jupyterlab-server==2.10.3
      - jupyterlab-widgets==1.1.11
      - mako==1.1.6
      - markupsafe==2.0.1
      - mistune==0.8.4
      - nbclassic==0.3.5
      - nbclient==0.5.9
      - nbconvert==6.0.7
      - nbformat==5.1.3
      - nbval==0.10.0
      - nest-asyncio==1.6.0
      - notebook==6.4.10
      - packaging==21.3
      - pandocfilters==1.5.1
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pluggy==1.0.0
      - prometheus-client==0.17.1
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pycparser==2.21
      - pyenchant==3.2.2
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyzmq==25.1.2
      - requests==2.27.1
      - send2trash==1.8.3
      - six==1.17.0
      - sniffio==1.2.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - sphinxcontrib-spelling==7.7.0
      - sqlalchemy==1.4.54
      - terminado==0.12.1
      - testpath==0.6.0
      - tomli==1.2.3
      - tornado==6.1
      - traitlets==4.3.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - websocket-client==1.3.1
      - widgetsnbextension==3.6.10
      - zipp==3.6.0
prefix: /opt/conda/envs/nbgrader

nbgrader/tests/api/test_models.py::test_create_source_cell
nbgrader/tests/api/test_models.py::test_create_assignment nbgrader/tests/api/test_models.py::test_create_notebook nbgrader/tests/api/test_models.py::test_create_grade_cell nbgrader/tests/api/test_models.py::test_create_solution_cell nbgrader/tests/api/test_models.py::test_create_student nbgrader/tests/api/test_models.py::test_create_submitted_assignment nbgrader/tests/api/test_models.py::test_submission_timestamp_ontime nbgrader/tests/api/test_models.py::test_submission_timestamp_late nbgrader/tests/api/test_models.py::test_submission_timestamp_with_extension nbgrader/tests/api/test_models.py::test_submission_timestamp_late_with_extension nbgrader/tests/api/test_models.py::test_create_submitted_notebook nbgrader/tests/api/test_models.py::test_create_code_grade nbgrader/tests/api/test_models.py::test_create_written_grade nbgrader/tests/api/test_models.py::test_create_comment nbgrader/tests/api/test_models.py::test_query_needs_manual_grade_ungraded nbgrader/tests/api/test_models.py::test_query_needs_manual_grade_autograded nbgrader/tests/api/test_models.py::test_query_needs_manual_grade_manualgraded nbgrader/tests/api/test_models.py::test_query_max_score nbgrader/tests/api/test_models.py::test_query_score_ungraded nbgrader/tests/api/test_models.py::test_query_comment_unchanged nbgrader/tests/api/test_models.py::test_query_score_autograded nbgrader/tests/api/test_models.py::test_query_auto_comment nbgrader/tests/api/test_models.py::test_query_score_manualgraded nbgrader/tests/api/test_models.py::test_query_manual_comment nbgrader/tests/api/test_models.py::test_query_max_written_score nbgrader/tests/api/test_models.py::test_query_written_score_ungraded nbgrader/tests/api/test_models.py::test_query_written_score_autograded nbgrader/tests/api/test_models.py::test_query_written_score_manualgraded nbgrader/tests/api/test_models.py::test_query_max_code_score nbgrader/tests/api/test_models.py::test_query_code_score_ungraded nbgrader/tests/api/test_models.py::test_query_code_score_autograded nbgrader/tests/api/test_models.py::test_query_code_score_manualgraded nbgrader/tests/api/test_models.py::test_query_auto_score_extra_credit nbgrader/tests/api/test_models.py::test_query_manual_score_extra_credit nbgrader/tests/api/test_models.py::test_query_num_submissions nbgrader/tests/api/test_models.py::test_student_max_score nbgrader/tests/api/test_models.py::test_query_grade_cell_types nbgrader/tests/api/test_models.py::test_query_failed_tests_failed nbgrader/tests/api/test_models.py::test_query_failed_tests_ok nbgrader/tests/api/test_models.py::test_assignment_to_dict nbgrader/tests/api/test_models.py::test_notebook_to_dict nbgrader/tests/api/test_models.py::test_gradecell_to_dict nbgrader/tests/api/test_models.py::test_solutioncell_to_dict nbgrader/tests/api/test_models.py::test_sourcecell_to_dict nbgrader/tests/api/test_models.py::test_student_to_dict nbgrader/tests/api/test_models.py::test_submittedassignment_to_dict nbgrader/tests/api/test_models.py::test_submittednotebook_to_dict nbgrader/tests/api/test_models.py::test_grade_to_dict nbgrader/tests/api/test_models.py::test_comment_to_dict
nbgrader/docs/source/user_guide/managing_assignment_files.ipynb nbgrader/api.py nbgrader/docs/source/user_guide/grades.csv dev-requirements.txt nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb tasks.py .travis.yml nbgrader/docs/source/contributor_guide/documentation.rst nbgrader/docs/source/conf.py appveyor.yml nbgrader/docs/source/spelling_wordlist.txt nbgrader/docs/Makefile dev-requirements-windows.txt nbgrader/docs/source/contributor_guide/installation_developer.rst
nbgrader/docs/source/user_guide/managing_assignment_files.ipynb nbgrader/api.py nbgrader/docs/source/user_guide/grades.csv dev-requirements.txt nbgrader/docs/source/user_guide/managing_assignment_files_manually.ipynb nbgrader/docs/source/user_guide/creating_and_grading_assignments.ipynb tasks.py .travis.yml nbgrader/docs/source/contributor_guide/documentation.rst nbgrader/docs/source/conf.py appveyor.yml nbgrader/docs/source/spelling_wordlist.txt nbgrader/docs/Makefile dev-requirements-windows.txt nbgrader/docs/source/contributor_guide/installation_developer.rst