Repository: pydicom/pynetdicom
Pull request #681 (2021-09-08 17:53:13)

[MRG] Work around LGTM errors: Clear-text logging of sensitive information
Disable false positives that cannot be fixed by LGTM, because their heuristic detects strings such "`id`" that are actually very common in DICOM, for example in "`UID`".

#### Tasks
- [ ] Unit tests added that reproduce issue or prove feature is working
- [X] Fix or feature added
- [ ] Documentation and examples updated (if relevant)
- [ ] Unit tests passing and coverage at 100% after adding fix/feature
- [ ] Type annotations updated and passing with mypy
- [ ] Apps updated and tested (if relevant)


codecov[bot]: # [Codecov](https://codecov.io/gh/pydicom/pynetdicom/pull/681?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) Report
> Merging [#681](https://codecov.io/gh/pydicom/pynetdicom/pull/681?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (f8f7c39) into [master](https://codecov.io/gh/pydicom/pynetdicom/commit/d36ac1993c4faa7a6d254c7a00b772c4b4a0653d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (d36ac19) will **decrease** coverage by `0.15%`.
> The diff coverage is `n/a`.

```diff
@@             Coverage Diff             @@
##            master     #681      +/-   ##
===========================================
- Coverage   100.00%   99.84%   -0.16%     
===========================================
  Files           28       28              
  Lines         8620     8620              
===========================================
- Hits          8620     8607      -13     
- Misses           0       13      +13     
```

| [Impacted Files](https://codecov.io/gh/pydicom/pynetdicom/pull/681?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) | Coverage Δ | |
|---|---|---|
| [pynetdicom/utils.py](https://codecov.io/gh/pydicom/pynetdicom/pull/681/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHluZXRkaWNvbS91dGlscy5weQ==) | `89.25% <0.00%> (-10.75%)` | :arrow_down: |


Patch:
diff --git a/.github/workflows/pr-linter.yml b/.github/workflows/pr-linter.yml
index cf021ecb4..2d772c7ab 100644
--- a/.github/workflows/pr-linter.yml
+++ b/.github/workflows/pr-linter.yml
@@ -37,7 +37,11 @@ jobs:
     - name: Install dependencies
       run: |
         python -m pip install --upgrade pip
-        pip install flake8
+        pip install flake8 black codespell
+    - name: Check code formatting
+      run: black . --check
+    - name: Check spelling
+      run: codespell -L halp,ot,pres -d pynetdicom
     - name: Check for syntax errors
       run: python -m flake8 --select=E901,E999,F821,F822,F823 ${{ steps.pydiff.outputs.pyfiles }} --ignore F821
     - name: Check for style warnings
diff --git a/build_tools/circle/push_doc.sh b/build_tools/circle/push_doc.sh
index c3666883e..62de10be5 100755
--- a/build_tools/circle/push_doc.sh
+++ b/build_tools/circle/push_doc.sh
@@ -3,7 +3,7 @@
 # This script is meant to be called in the "deploy" step defined
 # in .circleci/config.yml. See https://circleci.com/docs/2.0 for more details.
 
-# We have three possibily workflows:
+# We have three possible workflows:
 #   If the git branch is 'master' then we want to commit and merge the dev/
 #       docs on gh-pages
 #   If the git branch is [0-9].[0.9].X (i.e. 0.9.X, 1.0.X, 1.2.X, 41.21.X) then
diff --git a/docs/apps/echoscu.rst b/docs/apps/echoscu.rst
index b69c9f9e3..84c32dcfe 100644
--- a/docs/apps/echoscu.rst
+++ b/docs/apps/echoscu.rst
@@ -20,7 +20,7 @@ The source code for the application can be found `here
 Usage
 =====
 
-The following example shows what happens when it's succesfully run on
+The following example shows what happens when it is successfully run on
 an SCP at IP ``127.0.0.1`` and listen port ``11112`` that supports the
 Verification service:
 
diff --git a/docs/apps/findscu.rst b/docs/apps/findscu.rst
index 494f2af22..293883fae 100644
--- a/docs/apps/findscu.rst
+++ b/docs/apps/findscu.rst
@@ -23,7 +23,7 @@ The source code for the application can be found `here
 Usage
 =====
 
-The following example shows what happens when it is succesfully run on
+The following example shows what happens when it is successfully run on
 an SCP at IP ``127.0.0.1`` and listen port ``11112`` that supports the
 Query/Retrieve (Find) service:
 
diff --git a/docs/apps/getscu.rst b/docs/apps/getscu.rst
index 0dfdec136..e3050bb12 100644
--- a/docs/apps/getscu.rst
+++ b/docs/apps/getscu.rst
@@ -23,7 +23,7 @@ The source code for the application can be found `here
 Usage
 =====
 
-The following example shows what happens when it is succesfully run on
+The following example shows what happens when it is successfully run on
 an SCP at IP ``127.0.0.1`` and listen port ``11112`` that supports the
 Query/Retrieve (Get) service:
 
diff --git a/docs/apps/movescu.rst b/docs/apps/movescu.rst
index 6d48adf3b..d3f124970 100644
--- a/docs/apps/movescu.rst
+++ b/docs/apps/movescu.rst
@@ -25,7 +25,7 @@ The source code for the application can be found `here
 Usage
 =====
 
-The following example shows what happens when it is succesfully run on
+The following example shows what happens when it is successfully run on
 an SCP at IP ``127.0.0.1`` and listen port ``11112`` that supports the
 Query/Retrieve service with the default *Move Destination* AE title
 ``STORESCP``:
diff --git a/docs/apps/storescu.rst b/docs/apps/storescu.rst
index 40655902f..84df6274b 100644
--- a/docs/apps/storescu.rst
+++ b/docs/apps/storescu.rst
@@ -19,7 +19,7 @@ The source code for the application can be found `here
 Usage
 =====
 
-The following example shows what happens when it is succesfully run on
+The following example shows what happens when it is successfully run on
 an SCP at IP ``127.0.0.1`` and listen port ``11112`` that supports the *Storage
 Service*:
 
diff --git a/docs/changelog/v2.0.0.rst b/docs/changelog/v2.0.0.rst
index b356a2079..79ed59ee4 100644
--- a/docs/changelog/v2.0.0.rst
+++ b/docs/changelog/v2.0.0.rst
@@ -9,8 +9,8 @@ The major breaking changes with the version 2.0 release are:
   * SOP class variable names now use their `new DICOM UID keywords
     <https://dicom.nema.org/medical/dicom/current/output/chtml/part06/chapter_A.html#table_A-1>`_
     (for example, *VerificationSOPClass* becomes simply *Verification*)
-  * AE titles values should be :class:`str` rather than :class:`bytes` and no
-    longer contain any trailing padding bytes
+  * AE titles values should be :class:`str` rather than :class:`bytes` and will no
+    longer contain any trailing padding spaces
 
 
 Fixes
@@ -32,6 +32,7 @@ Fixes
   :meth:`ServiceUser.supported_contexts
   <pynetdicom.association.ServiceUser.supported_contexts>` not returning the
   expected contexts (:issue:`636`)
+* Fixed `qrscp --clean` (:issue:`681`, :issue:`682`)
 
 Enhancements
 ............
diff --git a/docs/examples/mpps.rst b/docs/examples/mpps.rst
index 2cb5da496..98edf0867 100644
--- a/docs/examples/mpps.rst
+++ b/docs/examples/mpps.rst
@@ -125,7 +125,7 @@ MPPS - Set SCU
 Once the MPPS SOP Instance has successfully been created, the modality can send
 one or more N-SET requests to the MPPS SCP in order to update the attributes
 of the SOP Instance. When the procedure has been completed a final N-SET
-request is sent containing a *Modification List* with an (0040,0252) *Peformed
+request is sent containing a *Modification List* with an (0040,0252) *Performed
 Procedure Step Status* of ``"COMPLETED"``.
 
 .. code-block:: python
diff --git a/docs/examples/print.rst b/docs/examples/print.rst
index 4e80f3f15..f71d1176e 100644
--- a/docs/examples/print.rst
+++ b/docs/examples/print.rst
@@ -38,7 +38,7 @@ Which utilise the following SOP Classes:
   of the printer.
 
 There are also the following SOP Classes that are not included under
-the Meta Print Mangement SOP Classes and which may optionally be supported:
+the Meta Print Management SOP Classes and which may optionally be supported:
 
 * *Basic Annotation Box SOP Class* used with N-SET to describe the presentation
   of an annotation on a film.
diff --git a/docs/examples/qr_find.rst b/docs/examples/qr_find.rst
index 8a859e9ba..9c033cc57 100644
--- a/docs/examples/qr_find.rst
+++ b/docs/examples/qr_find.rst
@@ -121,7 +121,7 @@ to see the requirements for the ``evt.EVT_C_FIND`` handler.
                         inst for inst in instances if inst.PatientName == ds.PatientName
                     ]
 
-                # Skip the other possibile values...
+                # Skip the other possible values...
 
             # Skip the other possible attributes...
 
diff --git a/docs/examples/qr_get.rst b/docs/examples/qr_get.rst
index 727b1cc85..3c34616fe 100644
--- a/docs/examples/qr_get.rst
+++ b/docs/examples/qr_get.rst
@@ -39,7 +39,7 @@ the SERIES level.
 
 One extra step needed with the Query/Retrieve (Get) Service is
 that during association we need to include a :class:`SCP/SCU Role Selection
-Negotation <pynetdicom.pdu_items.SCP_SCU_RoleSelectionSubItem>`
+Negotiation <pynetdicom.pdu_items.SCP_SCU_RoleSelectionSubItem>`
 item for each of the supported presentation contexts that may be used with
 the C-STORE requests.
 
diff --git a/docs/reference/sop_classes.rst b/docs/reference/sop_classes.rst
index 4ebbe2fe4..71a70997e 100644
--- a/docs/reference/sop_classes.rst
+++ b/docs/reference/sop_classes.rst
@@ -128,6 +128,7 @@ Non-patient Object
    ImplantAssemblyTemplateStorage
    ImplantTemplateGroupStorage
    ProtocolApprovalStorage
+   XADefinedProcedureProtocolStorage
 
 Print Management
 ................
@@ -280,6 +281,7 @@ Storage
    LensometryMeasurementsStorage
    MacularGridThicknessAndVolumeReportStorage
    MammographyCADSRStorage
+   MicroscopyBulkSimpleAnnotationsStorage
    MRImageStorage
    MRSpectroscopyStorage
    MultichannelRespiratoryWaveformStorage
@@ -323,9 +325,11 @@ Storage
    RTPlanStorage
    RTRadiationRecordSetStorage
    RTRadiationSalvageRecordStorage
+   RTRadiationSetDeliveryInstructionStorage
    RTRadiationSetStorage
    RTSegmentAnnotationStorage
    RTStructureSetStorage
+   RTTreatmentPreparationStorage
    RTTreatmentSummaryRecordStorage
    SecondaryCaptureImageStorage
    SegmentationStorage
@@ -358,6 +362,7 @@ Storage
    VolumeRenderingVolumetricPresentationStateStorage
    WideFieldOphthalmicPhotography3DCoordinatesImageStorage
    WideFieldOphthalmicPhotographyStereographicProjectionImageStorage
+   XAPerformedProcedureProtocolStorage
    XAXRFGrayscaleSoftcopyPresentationStateStorage
    XRay3DAngiographicImageStorage
    XRay3DCraniofacialImageStorage
diff --git a/docs/service_classes/rt_machine.rst b/docs/service_classes/rt_machine.rst
index 5835de7d6..cc35951d9 100644
--- a/docs/service_classes/rt_machine.rst
+++ b/docs/service_classes/rt_machine.rst
@@ -6,7 +6,7 @@ The :dcm:`RT Machine Verification Service Class<part04/chapter_DD.html>`
 defines a service that uses the DIMSE N-CREATE, N-SET, N-DELETE, N-ACTION,
 N-EVENT-REPORT and N-GET services to
 facilitate the independent verification of geometric and dosimetric settings
-on a radiation delivery system priot to delivery of treatment.
+on a radiation delivery system prior to delivery of treatment.
 
 .. _rt_machine_sops:
 
diff --git a/lgtm.yml b/lgtm.yml
new file mode 100644
index 000000000..98aea9b0a
--- /dev/null
+++ b/lgtm.yml
@@ -0,0 +1,4 @@
+---
+queries:
+  # https://lgtm.com/rules/1510014536001/
+  - exclude: py/clear-text-logging-sensitive-data
diff --git a/pynetdicom/_validators.py b/pynetdicom/_validators.py
index 355006cad..eb508d4bd 100644
--- a/pynetdicom/_validators.py
+++ b/pynetdicom/_validators.py
@@ -1,11 +1,9 @@
 """Validation functions used by pynetdicom"""
 
-from collections import OrderedDict
 import logging
-from typing import Union, Dict, Optional, cast, Tuple
+from typing import Tuple
 import unicodedata
 
-from pydicom.dataset import Dataset
 from pydicom.uid import UID
 
 
diff --git a/pynetdicom/acse.py b/pynetdicom/acse.py
index e2b1b4bcd..fa7698ab3 100644
--- a/pynetdicom/acse.py
+++ b/pynetdicom/acse.py
@@ -162,7 +162,7 @@ class ACSE:
 
         if not isinstance(user_response, (type(None), dict)):
             LOGGER.error(
-                "Invalid type returned by handler bount to " "'evt.EVT_SOP_EXTENDED'"
+                "Invalid type returned by handler bound to " "'evt.EVT_SOP_EXTENDED'"
             )
             user_response = {}
 
@@ -428,7 +428,7 @@ class ACSE:
         # Callbacks/Logging
         evt.trigger(self.assoc, evt.EVT_ACCEPTED, {})
 
-        # Assocation established OK
+        # Association established OK
         self.assoc.is_established = True
         evt.trigger(self.assoc, evt.EVT_ESTABLISHED, {})
 
diff --git a/pynetdicom/apps/common.py b/pynetdicom/apps/common.py
index c731d26c6..957c26291 100644
--- a/pynetdicom/apps/common.py
+++ b/pynetdicom/apps/common.py
@@ -421,7 +421,6 @@ class ElementPath:
         ]
         _int = ["SL", "SS", "SV", "UL", "US", "UV"]
         _float = ["FD", "FL"]
-        _byte = ["OB", "OD", "OF", "OL", "OW", "OV", "UN"]
         # Try to convert value to appropriate type
         if self.VR == "AT" and "\\" in value:
             value = value.split("\\")
@@ -627,7 +626,7 @@ def handle_store(event, args, app_logger):
             with open(filename, "wb") as f:
                 f.write(b"\x00" * 128)
                 f.write(b"DICM")
-                f.write(write_file_meta_info(f, event.file_meta))
+                write_file_meta_info(f, event.file_meta)
                 f.write(encode(ds, False, True, True))
         else:
             # We use `write_like_original=False` to ensure that a compliant
diff --git a/pynetdicom/apps/echoscu/echoscu.py b/pynetdicom/apps/echoscu/echoscu.py
index 9da684d5d..2a8175b23 100755
--- a/pynetdicom/apps/echoscu/echoscu.py
+++ b/pynetdicom/apps/echoscu/echoscu.py
@@ -221,8 +221,7 @@ def main(args=None):
     # If we successfully associated then send C-ECHO
     if assoc.is_established:
         for ii in range(args.repeat):
-            # `status` is a pydicom Dataset
-            status = assoc.send_c_echo()
+            assoc.send_c_echo()
 
         # Abort or release association
         if args.abort:
diff --git a/pynetdicom/apps/findscu/findscu.py b/pynetdicom/apps/findscu/findscu.py
index b74c5c1d6..91e36c115 100755
--- a/pynetdicom/apps/findscu/findscu.py
+++ b/pynetdicom/apps/findscu/findscu.py
@@ -6,10 +6,8 @@ requests to a QR/BWM - Find SCP.
 """
 
 import argparse
-import os
 import sys
 
-from pydicom import dcmread
 from pydicom.dataset import Dataset
 from pydicom.uid import (
     ExplicitVRLittleEndian,
@@ -297,7 +295,6 @@ def main(args=None):
         identifier = create_dataset(args, APP_LOGGER)
     except Exception as exc:
         APP_LOGGER.exception(exc)
-        raise exc
         sys.exit(1)
 
     # Create application entity
diff --git a/pynetdicom/apps/getscu/getscu.py b/pynetdicom/apps/getscu/getscu.py
index 14c1314b9..beb9c0026 100755
--- a/pynetdicom/apps/getscu/getscu.py
+++ b/pynetdicom/apps/getscu/getscu.py
@@ -5,10 +5,8 @@ For sending Query/Retrieve (QR) C-GET requests to a QR Get SCP.
 """
 
 import argparse
-import os
 import sys
 
-from pydicom.dataset import Dataset
 from pydicom.uid import (
     ExplicitVRLittleEndian,
     ImplicitVRLittleEndian,
diff --git a/pynetdicom/apps/movescu/movescu.py b/pynetdicom/apps/movescu/movescu.py
index 0dfd54113..071328f89 100755
--- a/pynetdicom/apps/movescu/movescu.py
+++ b/pynetdicom/apps/movescu/movescu.py
@@ -5,11 +5,8 @@ For sending Query/Retrieve (QR) C-MOVE requests to a QR Move SCP.
 """
 
 import argparse
-import os
 import sys
 
-from pydicom.dataset import Dataset
-
 from pynetdicom import (
     AE,
     evt,
diff --git a/pynetdicom/apps/qrscp/handlers.py b/pynetdicom/apps/qrscp/handlers.py
index a24d3f7f1..f91288b12 100644
--- a/pynetdicom/apps/qrscp/handlers.py
+++ b/pynetdicom/apps/qrscp/handlers.py
@@ -310,7 +310,6 @@ def handle_store(event, storage_dir, db_path, cli_config, logger):
     # Try and add the instance to the database
     #   If we fail then don't even try to store
     fpath = os.path.join(storage_dir, sop_instance)
-    db_dir = os.path.dirname(db_path)
 
     if os.path.exists(fpath):
         logger.warning("Instance already exists in storage directory, overwriting")
diff --git a/pynetdicom/apps/qrscp/qrscp.py b/pynetdicom/apps/qrscp/qrscp.py
index 591da10a6..f1cb0703d 100755
--- a/pynetdicom/apps/qrscp/qrscp.py
+++ b/pynetdicom/apps/qrscp/qrscp.py
@@ -4,10 +4,12 @@
 import argparse
 from configparser import ConfigParser
 import os
+from pathlib import Path
 import sys
 
 import pydicom.config
-from pydicom.dataset import Dataset
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
 
 from pynetdicom import AE, evt, AllStoragePresentationContexts, ALL_TRANSFER_SYNTAXES
 from pynetdicom import _config, _handlers
@@ -49,7 +51,7 @@ _handlers._send_c_store_rq = _dont_log
 _handlers._recv_c_store_rsp = _dont_log
 
 
-__version__ = "1.0.0"
+__version__ = "1.0.1"
 
 
 def _log_config(config, logger):
@@ -213,7 +215,7 @@ def _setup_argparser():
     return parser.parse_args()
 
 
-def clean(db_path, logger):
+def clean(db_path, instance_path, logger):
     """Remove all entries from the database and delete the corresponding
     stored instances.
 
@@ -221,6 +223,8 @@ def clean(db_path, logger):
     ----------
     db_path : str
         The database path to use with create_engine().
+    instance_path : str
+        The instance storage path.
     logger : logging.Logger
         The application logger.
 
@@ -234,21 +238,24 @@ def clean(db_path, logger):
     with engine.connect() as conn:
         Session = sessionmaker(bind=engine)
         session = Session()
-
+        query_success = True
         try:
-            fpaths = [ii.filename for ii in session.query(Instance).all()]
+            fpaths = [ii.filename for ii in session.query(db.Instance).all()]
         except Exception as exc:
             logger.error("Exception raised while querying the database")
             logger.exception(exc)
             session.rollback()
+            query_success = False
         finally:
             session.close()
+
+        if not query_success:
             return False
 
         storage_cleaned = True
         for fpath in fpaths:
             try:
-                os.remove(os.path.join(config.INSTANCE_LOCATION, fpath))
+                os.remove(os.path.join(instance_path, fpath))
             except Exception as exc:
                 logger.error(f"Unable to delete the instance at '{fpath}'")
                 logger.exception(exc)
@@ -261,7 +268,7 @@ def clean(db_path, logger):
 
         database_cleaned = False
         try:
-            clear(session)
+            db.clear(session)
             database_cleaned = True
             logger.info("Database cleaned successfully")
         except Exception as exc:
@@ -343,7 +350,7 @@ def main(args=None):
         if response != "yes":
             sys.exit()
 
-        if clean(db_path, APP_LOGGER):
+        if clean(db_path, instance_dir, APP_LOGGER):
             sys.exit()
         else:
             sys.exit(1)
diff --git a/pynetdicom/apps/storescp/storescp.py b/pynetdicom/apps/storescp/storescp.py
index c0d5998ff..75e626ca3 100755
--- a/pynetdicom/apps/storescp/storescp.py
+++ b/pynetdicom/apps/storescp/storescp.py
@@ -5,10 +5,8 @@ Used for receiving DICOM SOP Instances transferred from an SCU.
 """
 
 import argparse
-import os
 import sys
 
-from pydicom.dataset import Dataset
 from pydicom.uid import (
     ExplicitVRLittleEndian,
     ImplicitVRLittleEndian,
diff --git a/pynetdicom/association.py b/pynetdicom/association.py
index 42a8ab539..c6238f8c9 100644
--- a/pynetdicom/association.py
+++ b/pynetdicom/association.py
@@ -780,8 +780,8 @@ class Association(threading.Thread):
     def _c_store_scp(self, req: C_STORE) -> None:
         """A C-STORE SCP implementation.
 
-        Handles C-STORE requests from the peer over the same assocation as the
-        local AE sent a C-MOVE or C-GET request.
+        Handles C-STORE requests from the peer over the same association as
+        the local AE sent a C-MOVE or C-GET request.
 
         Must always send a C-STORE response back to the peer.
 
@@ -1422,7 +1422,7 @@ class Association(threading.Thread):
             req.Identifier = BytesIO(bytestream)
         else:
             LOGGER.error("Failed to encode the supplied Identifier dataset")
-            raise ValueError("Failed to encode the supplied Identifer dataset")
+            raise ValueError("Failed to encode the supplied Identifier dataset")
 
         LOGGER.info(f"Sending Get Request: MsgID {msg_id}")
         LOGGER.info("")
@@ -1526,7 +1526,7 @@ class Association(threading.Thread):
 
             *Query/Retrieve Service, Hanging Protocol Query/Retrieve Service,
             Defined Procedure Protocol Query/Retrieve Service, Color Palette
-            Query/Retrieve Service* , *Implant Template Query/Retreive
+            Query/Retrieve Service* , *Implant Template Query/Retrieve
             Service* and *Protocol Approval Query/Retrieve Service*
             specific (DICOM Standard, Part 4, Annexes C, U, Y, X, BB and HH):
 
@@ -1993,7 +1993,7 @@ class Association(threading.Thread):
                 yield status, identifier
                 continue
 
-            # Only reach this point if status is Sucess, Warning, Failure
+            # Only reach this point if status is Success, Warning, Failure
             #   or Cancel
             self._reactor_checkpoint.set()
             yield status, identifier
@@ -2133,7 +2133,7 @@ class Association(threading.Thread):
                         LOGGER.exception(exc)
                         identifier = None
 
-            # Only reach this point if status is Sucess, Warning, Failure
+            # Only reach this point if status is Success, Warning, Failure
             #   or Cancel
             self._reactor_checkpoint.set()
             yield status, identifier
diff --git a/pynetdicom/dimse_messages.py b/pynetdicom/dimse_messages.py
index 19fb6476a..a307cfcd4 100644
--- a/pynetdicom/dimse_messages.py
+++ b/pynetdicom/dimse_messages.py
@@ -5,11 +5,11 @@ import logging
 from math import ceil
 from pathlib import Path
 from tempfile import NamedTemporaryFile
-from typing import Iterator, Optional, TYPE_CHECKING, cast, Union, Tuple, Type, List
+from typing import Iterator, Optional, TYPE_CHECKING, cast, Union, Tuple
 
 from pydicom.dataset import Dataset
 from pydicom.filewriter import write_file_meta_info
-from pydicom.tag import Tag, BaseTag
+from pydicom.tag import Tag
 from pydicom.uid import UID
 
 from pynetdicom import _config
@@ -772,7 +772,7 @@ class DIMSEMessage:
                 else:
                     del self.command_set[elem.tag]
 
-        # Theres a one-to-one relationship in the _MESSAGE_TYPES dict, so
+        # There's a one-to-one relationship in the _MESSAGE_TYPES dict, so
         #   invert it for convenience
         rev_type = {vv[0]: kk for kk, vv in _MESSAGE_TYPES.items()}
         self.command_set.CommandField = rev_type[cls_type_name]
diff --git a/pynetdicom/dimse_primitives.py b/pynetdicom/dimse_primitives.py
index 8bc17ecb6..58a0b50c7 100644
--- a/pynetdicom/dimse_primitives.py
+++ b/pynetdicom/dimse_primitives.py
@@ -6,7 +6,6 @@ Notes:
     in order for the DIMSE messages/primitives to be created correctly.
 """
 
-import codecs
 from collections.abc import MutableSequence
 from io import BytesIO
 import logging
@@ -17,7 +16,6 @@ import warnings
 from pydicom.tag import Tag, BaseTag
 from pydicom.uid import UID
 
-from pynetdicom import _config
 from pynetdicom._globals import OptionalUIDType
 from pynetdicom.utils import set_ae, decode_bytes, set_uid
 
diff --git a/pynetdicom/dul.py b/pynetdicom/dul.py
index 803837994..cf789ec94 100644
--- a/pynetdicom/dul.py
+++ b/pynetdicom/dul.py
@@ -184,7 +184,7 @@ class DULServiceProvider(Thread):
             return True
 
         # By this point the connection should be established
-        #   If theres incoming data on the connection then check the PDU
+        #   If there's incoming data on the connection then check the PDU
         #   type
         # Fix for #28 - caused by peer disconnecting before run loop is
         #   stopped by assoc.release()
diff --git a/pynetdicom/events.py b/pynetdicom/events.py
index a387dbfe2..c1cd5f47f 100644
--- a/pynetdicom/events.py
+++ b/pynetdicom/events.py
@@ -997,7 +997,7 @@ def _sop_extended_handler(event: Event) -> Dict[UID, bytes]:
 
 
 def _user_identity_handler(event: Event) -> Tuple[bool, Optional[bytes]]:
-    """Default hander for when a user identity negotiation item is included
+    """Default handler for when a user identity negotiation item is included
     with the association request.
 
     See _handlers.doc_handler_userid for detailed documentation.
diff --git a/pynetdicom/fsm.py b/pynetdicom/fsm.py
index 6ab7687b6..d1670ae49 100644
--- a/pynetdicom/fsm.py
+++ b/pynetdicom/fsm.py
@@ -1005,9 +1005,10 @@ def AA_8(dul: "DULServiceProvider") -> str:
 
 
 # Finite State Machine
-# Machine State Defintions, PS3.8 Tables 9-1, 9-2, 9-3, 9-4, 9-5
+# Machine State Definitions, PS3.8 Tables 9-1, 9-2, 9-3, 9-4, 9-5
 # pylint: disable=line-too-long
 STATES = {
+    # No association
     "Sta1": "Idle",
     # Association establishment
     "Sta2": "Transport connection open (Awaiting A-ASSOCIATE-RQ PDU)",
@@ -1023,11 +1024,13 @@ STATES = {
     "Sta10": "Release collision acceptor side; awaiting A-RELEASE-RP PDU",
     "Sta11": "Release collision requestor side; awaiting A-RELEASE-RP PDU",
     "Sta12": "Release collision acceptor side; awaiting A-RELEASE response primitive (from local user)",
+    # Waiting for transport connection close
     "Sta13": "Awaiting Transport Connection Close Indication (Association no longer exists)",
 }
 
 # State Machine Action Definitions, PS3.8 Tables 9-6, 9-7, 9-8, 9-9
 ACTIONS = {
+    # Association establishment related actions
     "AE-1": (
         "Issue TRANSPORT CONNECT request primitive to local transport service",
         AE_1,
@@ -1058,7 +1061,7 @@ ACTIONS = {
     # Data transfer related actions
     "DT-1": ("Send P-DATA-TF PDU", DT_1, "Sta6"),
     "DT-2": ("Send P-DATA indication primitive", DT_2, "Sta6"),
-    # Assocation Release related actions
+    # Association Release related actions
     "AR-1": ("Send A-RELEASE-RQ PDU", AR_1, "Sta7"),
     "AR-2": ("Issue A-RELEASE indication primitive", AR_2, "Sta8"),
     "AR-3": (
@@ -1114,7 +1117,7 @@ EVENTS = {
     "Evt3": "A-ASSOCIATE-AC PDU (received on transport connection)",
     "Evt4": "A-ASSOCIATE-RJ PDU (received on transport connection)",
     "Evt5": "Transport connection indication (local transport service)",
-    "Evt6": "A-ASSOCIATE-RQ PDU (on tranport connection)",
+    "Evt6": "A-ASSOCIATE-RQ PDU (on transport connection)",
     "Evt7": "A-ASSOCIATE response primitive (accept)",
     "Evt8": "A-ASSOCIATE response primitive (reject)",
     "Evt9": "P-DATA request primitive",
diff --git a/pynetdicom/pdu.py b/pynetdicom/pdu.py
index 5421e20b8..978b5c0ad 100644
--- a/pynetdicom/pdu.py
+++ b/pynetdicom/pdu.py
@@ -19,7 +19,6 @@ There are seven different PDUs:
                     to_primitive               decode
 """
 
-import codecs
 import logging
 from struct import Struct
 from typing import (
diff --git a/pynetdicom/pdu_items.py b/pynetdicom/pdu_items.py
index 8e0408c2f..cabcbd205 100644
--- a/pynetdicom/pdu_items.py
+++ b/pynetdicom/pdu_items.py
@@ -40,7 +40,6 @@
 - PresentationDataValueItem
 """
 
-import codecs
 import logging
 from struct import Struct
 from typing import (
@@ -2365,7 +2364,7 @@ class SCP_SCU_RoleSelectionSubItem(PDUItem):
 class SOPClassExtendedNegotiationSubItem(PDUItem):
     """A SOP Class Extended Negotiation Sub-item.
 
-    A SOP Class Extended Negotation Sub-item allows peer Application Entities
+    A SOP Class Extended Negotiation Sub-item allows peer Application Entities
     to exchange application information defined by specific Service Class
     specifications.
 
@@ -2566,7 +2565,7 @@ class SOPClassExtendedNegotiationSubItem(PDUItem):
         return self.sop_class_uid
 
 
-# Overriden _generate_items, _wrap_generate_items
+# Overridden _generate_items, _wrap_generate_items
 class SOPClassCommonExtendedNegotiationSubItem(PDUItem):
     """A SOP Class Common Extended Negotiation Sub-item.
 
@@ -3357,7 +3356,7 @@ class UserIdentitySubItemAC(PDUItem):
 
 
 # P-DATA-TF Item
-# Overriden item_type
+# Overridden item_type
 class PresentationDataValueItem(PDUItem):
     """A Presentation Data Value Item.
 
diff --git a/pynetdicom/pdu_primitives.py b/pynetdicom/pdu_primitives.py
index 05f27c9b0..cf80a9e0a 100644
--- a/pynetdicom/pdu_primitives.py
+++ b/pynetdicom/pdu_primitives.py
@@ -1,7 +1,6 @@
 """
-Implementaion of the service parameter primitives.
+Implementation of the service parameter primitives.
 """
-import codecs
 import logging
 from typing import Optional, List, Any, Union, Tuple, cast, Type
 
diff --git a/pynetdicom/presentation.py b/pynetdicom/presentation.py
index e31c94cf8..b5c0234ad 100644
--- a/pynetdicom/presentation.py
+++ b/pynetdicom/presentation.py
@@ -459,10 +459,10 @@ class PresentationContext:
             s.append(f"Abstract Syntax: {self.abstract_syntax.name}")
 
         s.append("Transfer Syntax(es):")
-        for syntax in self.transfer_syntax:
-            s.append(f"    ={syntax.name}")
-        else:
+        if not self.transfer_syntax:
             s.append("    (none)")
+        else:
+            s.extend(f"    ={ts.name}" for ts in self.transfer_syntax)
 
         if self.result is not None:
             s.append(f"Result: {self.status}")
diff --git a/pynetdicom/service_class.py b/pynetdicom/service_class.py
index 9d8b4c9ca..70af71073 100644
--- a/pynetdicom/service_class.py
+++ b/pynetdicom/service_class.py
@@ -296,7 +296,7 @@ class ServiceClass:
             else:
                 (rsp_status, dataset) = cast(UserReturnType, result)
 
-            # Event hander has aborted or released
+            # Event handler has aborted or released
             if not self.assoc.is_established:
                 return
 
@@ -362,7 +362,7 @@ class ServiceClass:
 
                 self.dimse.send_msg(rsp, cx_id)
 
-        # Event hander has aborted or released
+        # Event handler has aborted or released
         if not self.assoc.is_established:
             return
 
@@ -1422,7 +1422,7 @@ class VerificationServiceClass(ServiceClass):
                 evt.EVT_C_ECHO,
                 {"request": req, "context": context.as_tuple},
             )
-            # Event hander has aborted or released
+            # Event handler has aborted or released
             if not self.assoc.is_established:
                 return
 
@@ -1714,7 +1714,7 @@ class QueryRetrieveServiceClass(ServiceClass):
             else:
                 (rsp_status, dataset) = cast(UserReturnType, result)
 
-            # Event hander has aborted or released - after any yields
+            # Event handler has aborted or released - after any yields
             if not self.assoc.is_established:
                 return
 
@@ -1927,7 +1927,7 @@ class QueryRetrieveServiceClass(ServiceClass):
                 rsp.NumberOfCompletedSuboperations = store_results[3]
                 self.dimse.send_msg(rsp, cx_id)
 
-        # Event hander has aborted or released - prevent final message
+        # Event handler has aborted or released - prevent final message
         if not self.assoc.is_established:
             return
 
@@ -2138,7 +2138,7 @@ class QueryRetrieveServiceClass(ServiceClass):
             else:
                 (rsp_status, dataset) = cast(UserReturnType, result)
 
-            # Event hander has aborted or released - during any status yields
+            # Event handler has aborted or released - during any status yields
             if not self.assoc.is_established:
                 store_assoc.release()
                 return
@@ -2335,7 +2335,7 @@ class QueryRetrieveServiceClass(ServiceClass):
 
         store_assoc.release()
 
-        # Event hander has aborted or released - after any yields
+        # Event handler has aborted or released - after any yields
         if not self.assoc.is_established:
             return
 
@@ -2495,7 +2495,7 @@ class RelevantPatientInformationQueryServiceClass(ServiceClass):
             responses = cast(Iterator[UserReturnType], responses)
             (rsp_status, rsp_identifier) = next(responses)
         except (StopIteration, TypeError):
-            # Event hander has aborted or released - before any yields
+            # Event handler has aborted or released - before any yields
             if not self.assoc.is_established:
                 return
 
@@ -2512,7 +2512,7 @@ class RelevantPatientInformationQueryServiceClass(ServiceClass):
             self.dimse.send_msg(rsp, cx_id)
             return
 
-        # Event hander has aborted or released
+        # Event handler has aborted or released
         if not self.assoc.is_established:
             return
 
diff --git a/pynetdicom/transport.py b/pynetdicom/transport.py
index e01b08a1d..3404480bd 100644
--- a/pynetdicom/transport.py
+++ b/pynetdicom/transport.py
@@ -268,15 +268,13 @@ class AssociationSocket:
             address.
         """
         # Solution from https://stackoverflow.com/a/28950776
-        temp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-        try:
-            # We use `host` to allow unit testing
-            temp.connect(host)
-            addr: str = temp.getsockname()[0]
-        except:
-            addr = "127.0.0.1"
-        finally:
-            temp.close()
+        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as temp:
+            try:
+                # We use `host` to allow unit testing
+                temp.connect(host)
+                addr: str = temp.getsockname()[0]
+            except:
+                addr = "127.0.0.1"
 
         return addr
 
diff --git a/pynetdicom/utils.py b/pynetdicom/utils.py
index 6a4460247..dd250f7af 100644
--- a/pynetdicom/utils.py
+++ b/pynetdicom/utils.py
@@ -13,11 +13,8 @@ from typing import (
     Union,
     cast,
     Callable,
-    Tuple,
-    Type,
     Sequence,
 )
-import unicodedata
 
 try:
     import ctypes
@@ -147,15 +144,12 @@ def pretty_bytes(
         byte_count += len(chunk)
         gen = (format(x, "02x") for x in chunk)
 
-        if max_size is not None and byte_count <= max_size:
+        if max_size is None or byte_count <= max_size:
             line = prefix + delimiter.join(gen)
             lines.append(line + suffix)
-        elif max_size is not None and byte_count > max_size:
+        else:
             cutoff_output = True
             break
-        else:
-            line = prefix + delimiter.join(gen)
-            lines.append(line + suffix)
 
     if cutoff_output:
         lines.insert(0, prefix + f"Only dumping {max_size} bytes.")
diff --git a/setup.cfg b/setup.cfg
index d0a9ca845..7f79b59e7 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -4,3 +4,4 @@ universal = 1
 
 [flake8]
 exclude = pynetdicom/tests, pynetdicom/benchmarks, pynetdicom/apps
+max-line-length = 88
diff --git a/setup.py b/setup.py
index 036be8902..349c066df 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,5 @@
 from setuptools import setup, find_packages
 from pathlib import Path
-import sys
 
 
 BASE_DIR = Path(__file__).parent


Test patch:
diff --git a/pynetdicom/apps/tests/test_storescp.py b/pynetdicom/apps/tests/test_storescp.py
index b4db5dbb0..03a0b3b18 100644
--- a/pynetdicom/apps/tests/test_storescp.py
+++ b/pynetdicom/apps/tests/test_storescp.py
@@ -2,6 +2,7 @@
 
 import logging
 import os
+from pathlib import Path
 import shutil
 import subprocess
 import sys
@@ -18,16 +19,22 @@ from pydicom.uid import (
 )
 
 from pynetdicom import AE, evt, debug_logger, DEFAULT_TRANSFER_SYNTAXES
-from pynetdicom.sop_class import Verification, CTImageStorage
+from pynetdicom.sop_class import (
+    Verification,
+    CTImageStorage,
+    SecondaryCaptureImageStorage,
+)
 
 
 # debug_logger()
 
 
-APP_DIR = os.path.join(os.path.dirname(__file__), "../")
-APP_FILE = os.path.join(APP_DIR, "storescp", "storescp.py")
-DATA_DIR = os.path.join(APP_DIR, "../", "tests", "dicom_files")
-DATASET_FILE = os.path.join(DATA_DIR, "CTImageStorage.dcm")
+APP_DIR = Path(__file__).parent.parent
+APP_FILE = APP_DIR / "storescp" / "storescp.py"
+DATA_DIR = APP_DIR.parent / "tests" / "dicom_files"
+DATASET_FILE = DATA_DIR / "CTImageStorage.dcm"
+DEFLATED_FILE = DATA_DIR / "SCImageStorage_Deflated.dcm"
+TEST_DIR = Path(__file__).parent / "test_dir"
 
 
 def start_storescp(args):
@@ -53,6 +60,9 @@ class StoreSCPBase:
 
     def teardown(self):
         """Clear any active threads"""
+        if TEST_DIR.exists():
+            shutil.rmtree(os.fspath(TEST_DIR))
+
         if self.ae:
             self.ae.shutdown()
 
@@ -310,9 +320,9 @@ class StoreSCPBase:
         ae.add_requested_context(Verification)
         ae.add_requested_context(CTImageStorage)
 
-        assert "test_dir" not in os.listdir()
+        assert not TEST_DIR.exists()
 
-        self.p = p = self.func(["-od", "test_dir"])
+        self.p = p = self.func(["-od", os.fspath(TEST_DIR)])
         time.sleep(0.5)
 
         ds = dcmread(DATASET_FILE)
@@ -323,9 +333,9 @@ class StoreSCPBase:
         assert status.Status == 0x0000
         assoc.release()
 
-        assert "CT.{}".format(ds.SOPInstanceUID) in os.listdir("test_dir")
-        shutil.rmtree("test_dir")
-        assert "test_dir" not in os.listdir()
+        assert (TEST_DIR / f"CT.{ds.SOPInstanceUID}").exists()
+        shutil.rmtree(os.fspath(TEST_DIR))
+        assert not TEST_DIR.exists()
 
     def test_flag_ignore(self):
         """Test the --ignore flag."""
@@ -347,7 +357,38 @@ class StoreSCPBase:
         assert status.Status == 0x0000
         assoc.release()
 
-        assert "CT.{}".format(ds.SOPInstanceUID) not in os.listdir()
+        assert not (TEST_DIR / f"CT.{ds.SOPInstanceUID}").exists()
+
+    def test_store_deflated(self):
+        """Test storing deflated dataset"""
+        self.ae = ae = AE()
+        ae.acse_timeout = 5
+        ae.dimse_timeout = 5
+        ae.network_timeout = 5
+        ae.add_requested_context(
+            SecondaryCaptureImageStorage,
+            DeflatedExplicitVRLittleEndian,
+        )
+
+        assert not TEST_DIR.exists()
+
+        self.p = p = self.func(["-od", os.fspath(TEST_DIR)])
+        time.sleep(0.5)
+
+        ds = dcmread(DEFLATED_FILE)
+
+        assoc = ae.associate("localhost", 11112)
+        assert assoc.is_established
+        status = assoc.send_c_store(ds)
+        assert status.Status == 0x0000
+        assoc.release()
+
+        p = TEST_DIR / f"SC.{ds.SOPInstanceUID}"
+        assert p.exists()
+        ds = dcmread(p)
+        assert ds.file_meta.TransferSyntaxUID == DeflatedExplicitVRLittleEndian
+        shutil.rmtree(os.fspath(TEST_DIR))
+        assert not TEST_DIR.exists()
 
 
 class TestStoreSCP(StoreSCPBase):
diff --git a/pynetdicom/tests/benchmark_script.py b/pynetdicom/tests/benchmark_script.py
index 7a427cd9e..d8a2a6e88 100755
--- a/pynetdicom/tests/benchmark_script.py
+++ b/pynetdicom/tests/benchmark_script.py
@@ -6,7 +6,7 @@ Overall transfer speed (no datasets written to file unless noted)
   * 1000 datasets over 1 association
   * 1000 datasets over 1 association (datasets written to temp file)
   * 1 dataset per association over 1000 sequential associations
-  * 1000 datasets per association over 10 simulataneous associations
+  * 1000 datasets per association over 10 simultaneous associations
 * pynetdicom as SCU, DCMTK's storescp as SCP
   * 1000 datasets over 1 association
   * 1 dataset per association for 1000 sequential associations
@@ -14,7 +14,6 @@ Overall transfer speed (no datasets written to file unless noted)
 """
 
 from datetime import datetime
-import multiprocessing
 import os
 import subprocess
 import tempfile
@@ -24,8 +23,7 @@ from pydicom import dcmread
 from pydicom.filewriter import write_file_meta_info
 from pydicom.uid import ImplicitVRLittleEndian
 
-from pynetdicom import AE, evt, build_context, debug_logger
-from pynetdicom.dsutils import encode
+from pynetdicom import AE, evt, debug_logger
 
 
 # debug_logger()
@@ -167,10 +165,7 @@ def receive_store(nr_assoc, ds_per_assoc, write_ds=0, use_yappi=False):
     )
 
     time.sleep(0.5)
-
     start_time = time.time()
-    run_times = []
-
     is_successful = True
 
     for ii in range(nr_assoc):
@@ -243,10 +238,7 @@ def receive_store_internal(nr_assoc, ds_per_assoc, write_ds=0, use_yappi=False):
     )
 
     time.sleep(0.5)
-
     start_time = time.time()
-    run_times = []
-
     is_successful = True
 
     for ii in range(nr_assoc):
@@ -343,10 +335,7 @@ def receive_store_simultaneous(nr_assoc, ds_per_assoc, use_yappi=False):
     )
 
     time.sleep(0.5)
-
     start_time = time.time()
-    run_times = []
-
     is_successful = True
 
     processes = []
diff --git a/pynetdicom/tests/encoded_pdu_items.py b/pynetdicom/tests/encoded_pdu_items.py
index 080b15d10..48d90302f 100644
--- a/pynetdicom/tests/encoded_pdu_items.py
+++ b/pynetdicom/tests/encoded_pdu_items.py
@@ -585,7 +585,7 @@ presentation_data_value = b"\x00\x00\x00\x50\x01" + presentation_data
 # Max Length Received: 16382
 maximum_length_received = b"\x51\x00\x00\x04\x00\x00\x3f\xfe"
 
-######################## Implementaion Class UID Sub Item ####################
+######################## Implementation Class UID Sub Item ###################
 # Implementation Class UID: 1.2.826.0.1.3680043.9.3811.0.9.0
 implementation_class_uid = (
     b"\x52\x00\x00\x20\x31\x2e\x32\x2e\x38\x32\x36\x2e\x30\x2e\x31\x2e"
diff --git a/pynetdicom/tests/test_assoc.py b/pynetdicom/tests/test_assoc.py
index 47102aa6c..cc11abe53 100644
--- a/pynetdicom/tests/test_assoc.py
+++ b/pynetdicom/tests/test_assoc.py
@@ -13,17 +13,14 @@ import logging
 import os
 from pathlib import Path
 import queue
-import socket
 import sys
 import time
-import threading
 
 import pytest
 
 from pydicom import dcmread
 from pydicom.dataset import Dataset, FileMetaDataset
 from pydicom.uid import (
-    UID,
     ImplicitVRLittleEndian,
     ExplicitVRLittleEndian,
     JPEGBaseline8Bit,
@@ -36,7 +33,6 @@ from pydicom.uid import (
 import pynetdicom
 from pynetdicom import (
     AE,
-    VerificationPresentationContexts,
     build_context,
     evt,
     _config,
@@ -47,13 +43,12 @@ from pynetdicom.association import Association
 from pynetdicom.dimse_primitives import C_STORE, C_FIND, C_GET, C_MOVE
 from pynetdicom.dsutils import encode, decode
 from pynetdicom.events import Event
-from pynetdicom._globals import MODE_REQUESTOR, MODE_ACCEPTOR
+from pynetdicom._globals import MODE_REQUESTOR
 from pynetdicom.pdu_primitives import (
     UserIdentityNegotiation,
     SOPClassExtendedNegotiation,
     SOPClassCommonExtendedNegotiation,
     SCP_SCU_RoleSelectionNegotiation,
-    AsynchronousOperationsWindowNegotiation,
     A_ASSOCIATE,
 )
 from pynetdicom.sop_class import (
@@ -69,7 +64,6 @@ from pynetdicom.sop_class import (
     SecondaryCaptureImageStorage,
     UnifiedProcedureStepPull,
     UnifiedProcedureStepPush,
-    UnifiedProcedureStepWatch,
 )
 
 from .hide_modules import hide_modules
@@ -488,7 +482,7 @@ class TestAssociation:
             "'acceptor'"
         )
         with pytest.raises(ValueError, match=msg):
-            assoc = Association(None, "nope")
+            Association(None, "nope")
 
     def test_setting_socket_override_raises(self):
         """Test that set_socket raises exception if socket set."""
@@ -522,7 +516,7 @@ class TestAssociation:
             ds.SOPInstanceUID = "1.2.3.4"
             ds.file_meta = FileMetaDataset()
             ds.file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
-            result = assoc.send_c_store(ds)
+            assoc.send_c_store(ds)
             time.sleep(0.1)
             assert assoc.is_aborted
             assert (
@@ -871,7 +865,7 @@ class TestCStoreSCP:
 
 
 class TestAssociationSendCEcho:
-    """Run tests on Assocation evt.EVT_C_ECHO handler."""
+    """Run tests on Association evt.EVT_C_ECHO handler."""
 
     def setup(self):
         """Run prior to each test"""
@@ -1235,7 +1229,7 @@ class TestAssociationSendCEcho:
 
 
 class TestAssociationSendCStore:
-    """Run tests on Assocation send_c_store."""
+    """Run tests on Association send_c_store."""
 
     def setup(self):
         """Run prior to each test"""
@@ -1590,8 +1584,8 @@ class TestAssociationSendCStore:
         assert assoc.is_established
         assert "SOPClassUID" not in ds
         msg = (
-            f"Unable to send the dataset as one or more required "
-            f"element are missing: SOPClassUID"
+            "Unable to send the dataset as one or more required "
+            "element are missing: SOPClassUID"
         )
         with pytest.raises(AttributeError, match=msg):
             assoc.send_c_store(ds)
@@ -1892,7 +1886,7 @@ class TestAssociationSendCStore:
 
         assert assoc.is_established
 
-        status = assoc.send_c_store(DEFL_DATASET)
+        assoc.send_c_store(DEFL_DATASET)
 
         assoc.release()
         assert assoc.is_released
@@ -1903,7 +1897,7 @@ class TestAssociationSendCStore:
 
 
 class TestAssociationSendCFind:
-    """Run tests on Assocation send_c_find."""
+    """Run tests on Association send_c_find."""
 
     def setup(self):
         """Run prior to each test"""
@@ -2465,7 +2459,7 @@ class TestAssociationSendCFind:
             assoc = ae.associate("localhost", 11112)
             assert assoc.is_established
 
-            responses = assoc.send_c_find(self.ds, "1.2.3.4")
+            assoc.send_c_find(self.ds, "1.2.3.4")
 
             scp.shutdown()
 
@@ -2477,7 +2471,7 @@ class TestAssociationSendCFind:
 
 
 class TestAssociationSendCCancel:
-    """Run tests on Assocation send_c_cancel."""
+    """Run tests on Association send_c_cancel."""
 
     def setup(self):
         """Run prior to each test"""
@@ -2580,7 +2574,7 @@ class TestAssociationSendCCancel:
 
 
 class TestAssociationSendCGet:
-    """Run tests on Assocation send_c_get."""
+    """Run tests on Association send_c_get."""
 
     def setup(self):
         """Run prior to each test"""
@@ -3367,7 +3361,7 @@ class TestAssociationSendCGet:
             assoc = ae.associate("localhost", 11112)
             assert assoc.is_established
 
-            responses = assoc.send_c_get(self.ds, "1.2.3.4")
+            assoc.send_c_get(self.ds, "1.2.3.4")
 
             scp.shutdown()
 
@@ -3517,7 +3511,7 @@ class TestAssociationSendCGet:
 
 
 class TestAssociationSendCMove:
-    """Run tests on Assocation send_c_move."""
+    """Run tests on Association send_c_move."""
 
     def setup(self):
         """Run prior to each test"""
@@ -4348,7 +4342,7 @@ class TestAssociationSendCMove:
             assoc = ae.associate("localhost", 11113)
             assert assoc.is_established
 
-            result = assoc.send_c_move(self.ds, "TESTMOVE", "1.2.3.4")
+            assoc.send_c_move(self.ds, "TESTMOVE", "1.2.3.4")
 
             store_scp.shutdown()
             move_scp.shutdown()
@@ -5047,7 +5041,7 @@ class TestGetValidContext:
         ds = Dataset()
         ds.TransactionUID = "1.2.3.4"
         with caplog.at_level(logging.DEBUG, logger="pynetdicom"):
-            responses = assoc.send_c_find(ds, UnifiedProcedureStepPush)
+            assoc.send_c_find(ds, UnifiedProcedureStepPush)
             assert msg in caplog.text
 
         assoc.release()
@@ -5287,7 +5281,6 @@ class TestEventHandlingAcceptor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_ABORTED, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_ABORTED) == []
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
@@ -5566,7 +5559,6 @@ class TestEventHandlingAcceptor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_ACCEPTED, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
 
@@ -5939,7 +5931,6 @@ class TestEventHandlingAcceptor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_ESTABLISHED, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
 
@@ -6099,7 +6090,6 @@ class TestEventHandlingAcceptor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_REQUESTED, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
 
@@ -6247,7 +6237,6 @@ class TestEventHandlingAcceptor:
         ae.require_called_aet = True
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_REJECTED, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_REJECTED) == []
 
@@ -6472,7 +6461,7 @@ class TestEventHandlingRequestor:
         scp.shutdown()
 
     def test_unbind_notification_none(self):
-        """Test unbinding a handler thats not bound."""
+        """Test unbinding a handler that's not bound."""
 
         def dummy(event):
             pass
@@ -6573,7 +6562,6 @@ class TestEventHandlingRequestor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_ABORTED, handle)]
         scp = ae.start_server(("", 11112), block=False)
 
         assoc = ae.associate("localhost", 11112)
@@ -6826,7 +6814,6 @@ class TestEventHandlingRequestor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_RELEASED, handle)]
         scp = ae.start_server(("", 11112), block=False)
 
         assoc = ae.associate("localhost", 11112)
diff --git a/pynetdicom/tests/test_assoc_n.py b/pynetdicom/tests/test_assoc_n.py
index cfc51c6d2..9d4339d2a 100644
--- a/pynetdicom/tests/test_assoc_n.py
+++ b/pynetdicom/tests/test_assoc_n.py
@@ -1,6 +1,5 @@
 """Association testing for DIMSE-N services"""
 
-from io import BytesIO
 import queue
 import time
 
@@ -8,18 +7,9 @@ import pytest
 
 from pydicom.dataset import Dataset
 from pydicom.tag import Tag
-from pydicom.uid import UID, ImplicitVRLittleEndian, ExplicitVRLittleEndian
+from pydicom.uid import ExplicitVRLittleEndian
 
 from pynetdicom import AE, debug_logger, evt
-from pynetdicom.dimse_primitives import (
-    N_EVENT_REPORT,
-    N_GET,
-    N_SET,
-    N_ACTION,
-    N_CREATE,
-    N_DELETE,
-)
-from pynetdicom.dsutils import encode, decode
 from pynetdicom.sop_class import (
     DisplaySystem,
     Verification,
@@ -33,7 +23,6 @@ from pynetdicom.sop_class import (
     BasicColorPrintManagementMeta,
     Printer,
 )
-from pynetdicom.service_class import ServiceClass
 
 
 # debug_logger()
@@ -52,7 +41,7 @@ class DummyDIMSE:
 
 
 class TestAssociationSendNEventReport:
-    """Run tests on Assocation send_n_event_report."""
+    """Run tests on Association send_n_event_report."""
 
     def setup(self):
         self.ae = None
@@ -653,7 +642,7 @@ class TestAssociationSendNEventReport:
 
 
 class TestAssociationSendNGet:
-    """Run tests on Assocation send_n_get."""
+    """Run tests on Association send_n_get."""
 
     def setup(self):
         """Run prior to each test"""
@@ -1208,7 +1197,7 @@ class TestAssociationSendNGet:
 
 
 class TestAssociationSendNSet:
-    """Run tests on Assocation send_n_set."""
+    """Run tests on Association send_n_set."""
 
     def setup(self):
         self.ae = None
@@ -1458,6 +1447,8 @@ class TestAssociationSendNSet:
         assoc.release()
         assert assoc.is_released
 
+        scp.shutdown()
+
     def test_rsp_success(self):
         """Test receiving a success response from the peer"""
 
@@ -1487,6 +1478,8 @@ class TestAssociationSendNSet:
         assoc.release()
         assert assoc.is_released
 
+        scp.shutdown()
+
     def test_rsp_unknown_status(self):
         """Test unknown status value returned by peer"""
 
@@ -1516,6 +1509,8 @@ class TestAssociationSendNSet:
         assoc.release()
         assert assoc.is_released
 
+        scp.shutdown()
+
     def test_rsp_bad_dataset(self):
         """Test handler returns bad dataset"""
 
@@ -1781,7 +1776,7 @@ class TestAssociationSendNSet:
 
 
 class TestAssociationSendNAction:
-    """Run tests on Assocation send_n_action."""
+    """Run tests on Association send_n_action."""
 
     def setup(self):
         self.ae = None
@@ -2315,7 +2310,7 @@ class TestAssociationSendNAction:
 
 
 class TestAssociationSendNCreate:
-    """Run tests on Assocation send_n_create."""
+    """Run tests on Association send_n_create."""
 
     def setup(self):
         self.ae = None
@@ -2875,7 +2870,7 @@ class TestAssociationSendNCreate:
 
 
 class TestAssociationSendNDelete:
-    """Run tests on Assocation send_n_delete."""
+    """Run tests on Association send_n_delete."""
 
     def setup(self):
         self.ae = None
@@ -3143,7 +3138,7 @@ class TestAssociationSendNDelete:
         ds = Dataset()
         ds.PatientName = "Test^test"
         # Receives None, None from DummyDIMSE, aborts
-        status = assoc.send_n_delete(
+        assoc.send_n_delete(
             Printer,
             "1.2.840.10008.5.1.1.40.1",
             meta_uid=BasicGrayscalePrintManagementMeta,
diff --git a/pynetdicom/tests/test_assoc_user.py b/pynetdicom/tests/test_assoc_user.py
index bc23e3f39..23cefbc94 100644
--- a/pynetdicom/tests/test_assoc_user.py
+++ b/pynetdicom/tests/test_assoc_user.py
@@ -1,16 +1,10 @@
 """Tests for association.AcceptorRequestor."""
 
-import logging
-import time
-import threading
-
 import pytest
 
 from pynetdicom import (
     AE,
-    VerificationPresentationContexts,
     PYNETDICOM_IMPLEMENTATION_UID,
-    PYNETDICOM_IMPLEMENTATION_VERSION,
     build_context,
     debug_logger,
 )
@@ -118,7 +112,7 @@ class TestServiceUserAcceptor:
         assert user.implementation_class_uid is None
 
     def test_no_maximum_len(self):
-        """Test correct reutrn if no maximum length."""
+        """Test correct return if no maximum length."""
         user = ServiceUser(self.assoc, mode="acceptor")
         user._user_info = []
         assert user.maximum_length is None
@@ -176,7 +170,7 @@ class TestServiceUserAcceptor:
         assert user.mode == "acceptor"
 
     def test_minimal_ac(self):
-        """Test access with a miminal allowed A-ASSOCIATE (ac) primitive."""
+        """Test access with a minimal allowed A-ASSOCIATE (ac) primitive."""
         user = ServiceUser(self.assoc, mode="acceptor")
         user.primitive = self.primitive_ac
 
@@ -193,7 +187,7 @@ class TestServiceUserAcceptor:
         assert user.user_identity is None
 
     def test_minimal_rj(self):
-        """Test access with a miminal allowed A-ASSOCIATE (rj) primitive."""
+        """Test access with a minimal allowed A-ASSOCIATE (rj) primitive."""
         user = ServiceUser(self.assoc, mode="acceptor")
         user.primitive = self.primitive_rj
 
@@ -1491,7 +1485,7 @@ class TestServiceUserRequestor:
         assert user.mode == "requestor"
 
     def test_minimal(self):
-        """Test access with a miminal allowed A-ASSOCIATE primitive."""
+        """Test access with a minimal allowed A-ASSOCIATE primitive."""
         user = ServiceUser(self.assoc, mode="requestor")
         user.primitive = self.primitive
 
diff --git a/pynetdicom/tests/test_fsm.py b/pynetdicom/tests/test_fsm.py
index 15e1cb07c..b8bcc1b75 100644
--- a/pynetdicom/tests/test_fsm.py
+++ b/pynetdicom/tests/test_fsm.py
@@ -2,10 +2,8 @@
 
 import datetime
 import logging
-import select
 import socket
 from struct import pack
-import sys
 import threading
 import time
 
@@ -25,7 +23,6 @@ from pynetdicom.pdu_primitives import (
     MaximumLengthNotification,
     ImplementationClassUIDNotification,
 )
-from pynetdicom.pdu import A_RELEASE_RQ
 from pynetdicom.sop_class import Verification
 from pynetdicom.transport import AssociationSocket
 from .encoded_pdu_items import (
@@ -1325,7 +1322,7 @@ class TestState03(TestStateBase):
 
         assoc, fsm = self.get_acceptor_assoc()
 
-        orig = assoc.acse._negotiate_as_acceptor
+        assoc.acse._negotiate_as_acceptor
 
         def _neg_as_acc():
             """Override ACSE._negotiate_as_acceptor so no A-ASSOCIATE (rsp)."""
@@ -1354,7 +1351,7 @@ class TestState03(TestStateBase):
 
         assoc, fsm = self.get_acceptor_assoc()
 
-        orig = assoc.acse._negotiate_as_acceptor
+        assoc.acse._negotiate_as_acceptor
 
         def _neg_as_acc():
             """Override ACSE._negotiate_as_acceptor so no A-ASSOCIATE (rsp)."""
@@ -1415,7 +1412,7 @@ class TestState03(TestStateBase):
 
         assoc, fsm = self.get_acceptor_assoc()
 
-        orig = assoc.acse._negotiate_as_acceptor
+        assoc.acse._negotiate_as_acceptor
 
         def _neg_as_acc():
             """Override ACSE._negotiate_as_acceptor so no A-ASSOCIATE (rsp)."""
@@ -1509,7 +1506,7 @@ class TestState03(TestStateBase):
 
         assoc, fsm = self.get_acceptor_assoc()
 
-        orig = assoc.acse._negotiate_as_acceptor
+        assoc.acse._negotiate_as_acceptor
 
         def _neg_as_acc():
             """Override ACSE._negotiate_as_acceptor so no A-ASSOCIATE (rsp)."""
@@ -1538,7 +1535,7 @@ class TestState03(TestStateBase):
 
         assoc, fsm = self.get_acceptor_assoc()
 
-        orig = assoc.acse._negotiate_as_acceptor
+        assoc.acse._negotiate_as_acceptor
 
         def _neg_as_acc():
             """Override ACSE._negotiate_as_acceptor so no A-ASSOCIATE (rsp)."""
@@ -2389,7 +2386,7 @@ class TestState05(TestStateBase):
         # Sta5 + Evt16 -> AA-3 -> Sta1
         # Evt16: Receive A-ABORT PDU from <remote>
         # AA-3: If service user initiated:
-        #           Issue A-ABORT primitve and close transport
+        #           Issue A-ABORT primitive and close transport
         #       Otherwise
         #           Issue A-P-ABORT primitive and close transport
         commands = [("recv", None), ("send", a_abort), ("exit", None)]
diff --git a/pynetdicom/tests/test_presentation.py b/pynetdicom/tests/test_presentation.py
index f0e143745..bc9fa5cc1 100644
--- a/pynetdicom/tests/test_presentation.py
+++ b/pynetdicom/tests/test_presentation.py
@@ -217,23 +217,36 @@ class TestPresentationContext:
         pc._scp_role = True
         pc._scu_role = False
         pc.result = 0x02
-        assert "1.1.1" in pc.__str__()
-        assert "Implicit" in pc.__str__()
-        assert "Provider Rejected" in pc.__str__()
+        out = [
+            "ID: 1",
+            "Abstract Syntax: 1.1.1",
+            "Transfer Syntax(es):",
+            "    =Implicit VR Little Endian",
+            "    =1.2.3",
+            "Result: Provider Rejected",
+        ]
+        assert "\n".join(out) == str(pc)
 
         pc._as_scu = True
         pc._as_scp = False
-        assert "Role: SCU only" in pc.__str__()
+        assert "Role: SCU only" in str(pc)
         pc._as_scp = True
-        assert "Role: SCU and SCP" in pc.__str__()
+        assert "Role: SCU and SCP" in str(pc)
         pc._as_scu = False
-        assert "Role: SCP only" in pc.__str__()
+        assert "Role: SCP only" in str(pc)
         pc._as_scp = False
-        assert "Role: (none)" in pc.__str__()
+        assert "Role: (none)" in str(pc)
 
         pc._transfer_syntax = []
-        print(pc)
-        assert "    (none)" in pc.__str__()
+        out = [
+            "ID: 1",
+            "Abstract Syntax: 1.1.1",
+            "Transfer Syntax(es):",
+            "    (none)",
+            "Result: Provider Rejected",
+            "Role: (none)",
+        ]
+        assert "\n".join(out) == str(pc)
 
     def test_context_id(self):
         """Test setting context_id."""
diff --git a/pynetdicom/tests/test_service_n.py b/pynetdicom/tests/test_service_n.py
index 7439acd6b..e4de41436 100644
--- a/pynetdicom/tests/test_service_n.py
+++ b/pynetdicom/tests/test_service_n.py
@@ -19,7 +19,7 @@ from pynetdicom.dimse_primitives import (
     C_FIND,
 )
 from pynetdicom.sop_class import (
-    DisplaySystem,  # Display Sysyem Management - N-GET
+    DisplaySystem,  # Display System Management - N-GET
     # Modality Performed Procedure - N-CREATE, N-SET
     ModalityPerformedProcedureStep,
     ModalityPerformedProcedureStepRetrieve,  # N-GET
@@ -1144,7 +1144,7 @@ class TestNServiceClass:
         if msg_type != "N-DELETE":
             status, ds = rsp
             assert status == Dataset()
-            assert ds == None
+            assert ds is None
         else:
             assert rsp == Dataset()
 
@@ -1196,7 +1196,7 @@ class TestNServiceClass:
         if msg_type != "N-DELETE":
             status, ds = rsp
             assert status == Dataset()
-            assert ds == None
+            assert ds is None
         else:
             assert rsp == Dataset()
 
@@ -2028,7 +2028,7 @@ class TestUPSFindServiceClass:
         result = assoc.send_c_find(self.query, UnifiedProcedureStepPull)
         status, identifier = next(result)
         assert status == Dataset()
-        assert identifier == None
+        assert identifier is None
         with pytest.raises(StopIteration):
             next(result)
 
@@ -2056,7 +2056,7 @@ class TestUPSFindServiceClass:
         result = assoc.send_c_find(self.query, UnifiedProcedureStepPull)
         status, identifier = next(result)
         assert status == Dataset()
-        assert identifier == None
+        assert identifier is None
         with pytest.raises(StopIteration):
             next(result)
 
@@ -2233,3 +2233,5 @@ class TestNEventReport:
         assert e.event == evt.EVT_N_EVENT_REPORT
         assert e.event_type == 1
         assert e.event_information.PatientName == "Test2"
+
+        ner_scp.shutdown()
diff --git a/pynetdicom/tests/test_service_non_patient.py b/pynetdicom/tests/test_service_non_patient.py
index 5222c2301..bdc9adb8b 100644
--- a/pynetdicom/tests/test_service_non_patient.py
+++ b/pynetdicom/tests/test_service_non_patient.py
@@ -1,10 +1,7 @@
 """Tests for the NonPatientObjectStorageServiceClass."""
 
 from io import BytesIO
-import logging
 import os
-import threading
-import time
 
 import pytest
 
@@ -15,7 +12,6 @@ from pydicom.uid import ExplicitVRLittleEndian
 from pynetdicom import AE, evt, debug_logger
 from pynetdicom.dimse_primitives import C_STORE
 from pynetdicom.sop_class import (
-    NonPatientObjectStorageServiceClass,
     HangingProtocolStorage,
 )
 
@@ -72,7 +68,7 @@ class TestNonPatientObjectStorageServiceClass:
         req.MessageID = 1
         req.AffectedSOPClassUID = DATASET.SOPClassUID
         req.AffectedSOPInstanceUID = DATASET.SOPInstanceUID
-        req.Priorty = 0x0002
+        req.Priority = 0x0002
         # Bad VR? AA
         req.DataSet = BytesIO(
             b"\x08\x00\x01\x00\x40\x40\x00\x00\x00\x00\x00\x08\x00\x49"
@@ -162,7 +158,7 @@ class TestNonPatientObjectStorageServiceClass:
         assert assoc.is_established
         rsp = assoc.send_c_store(DATASET)
         assert rsp.Status == 0x0000
-        assert not "ErrorComment" in rsp
+        assert "ErrorComment" not in rsp
         assoc.release()
         assert assoc.is_released
 
diff --git a/pynetdicom/tests/test_service_qr.py b/pynetdicom/tests/test_service_qr.py
index 5cb27633d..6004028aa 100644
--- a/pynetdicom/tests/test_service_qr.py
+++ b/pynetdicom/tests/test_service_qr.py
@@ -29,7 +29,6 @@ from pynetdicom import (
 )
 from pynetdicom.dimse_primitives import C_FIND, C_GET, C_MOVE, C_STORE
 from pynetdicom.presentation import PresentationContext
-from pynetdicom.pdu_primitives import SCP_SCU_RoleSelectionNegotiation
 from pynetdicom.service_class import (
     QueryRetrieveServiceClass,
     BasicWorklistManagementServiceClass,
@@ -828,7 +827,6 @@ class TestQRFindServiceClass:
             attrs["request"] = event.request
             attrs["identifier"] = event.identifier
 
-            ds = event.identifier
             yield 0xFF00, self.query
 
         handlers = [(evt.EVT_C_FIND, handle)]
@@ -935,7 +933,7 @@ class TestQRFindServiceClass:
         )
         status, identifier = next(result)
         assert status == Dataset()
-        assert identifier == None
+        assert identifier is None
         with pytest.raises(StopIteration):
             next(result)
 
@@ -967,7 +965,7 @@ class TestQRFindServiceClass:
         )
         status, identifier = next(result)
         assert status == Dataset()
-        assert identifier == None
+        assert identifier is None
         with pytest.raises(StopIteration):
             next(result)
 
@@ -1072,7 +1070,7 @@ class TestQRFindServiceClass:
         )
         status, identifier = next(result)
         assert status.Status == 0xC311
-        assert identifier == None
+        assert identifier is None
         pytest.raises(StopIteration, next, result)
 
         assoc.release()
@@ -2905,7 +2903,6 @@ class TestQRGetServiceClass:
 
     def test_store_handler_bad(self):
         """Test C-STORE handler event's assoc attribute"""
-        attrs = {}
 
         def handle(event):
             yield 1
@@ -3657,8 +3654,6 @@ class TestQRMoveServiceClass:
         ae.add_requested_context(CTImageStorage)
         scp = ae.start_server(("", 11112), block=False, evt_handlers=handlers)
 
-        role = build_role(CTImageStorage, scp_role=True)
-
         ae.acse_timeout = 5
         ae.dimse_timeout = 5
 
@@ -4912,7 +4907,7 @@ class TestQRMoveServiceClass:
         scp.shutdown()
 
     def test_scp_handler_context(self):
-        """Test hander event's context attribute"""
+        """Test handler event's context attribute"""
         attrs = {}
 
         def handle(event):
@@ -4961,7 +4956,7 @@ class TestQRMoveServiceClass:
         scp.shutdown()
 
     def test_scp_handler_assoc(self):
-        """Test hander event's context attribute"""
+        """Test handler event's context attribute"""
         attrs = {}
 
         def handle(event):
@@ -5010,7 +5005,7 @@ class TestQRMoveServiceClass:
         scp.shutdown()
 
     def test_scp_handler_request(self):
-        """Test hander event's context attribute"""
+        """Test handler event's context attribute"""
         attrs = {}
 
         def handle(event):
@@ -5067,7 +5062,7 @@ class TestQRMoveServiceClass:
         scp.shutdown()
 
     def test_scp_handler_identifier(self):
-        """Test hander event's context attribute"""
+        """Test handler event's context attribute"""
         attrs = {}
 
         def handle(event):
@@ -5115,7 +5110,7 @@ class TestQRMoveServiceClass:
         scp.shutdown()
 
     def test_scp_handler_move_dest(self):
-        """Test hander event's context attribute"""
+        """Test handler event's context attribute"""
         attrs = {}
 
         def handle(event):
@@ -5166,8 +5161,6 @@ class TestQRMoveServiceClass:
         """Test is_cancelled works as expected."""
         cancel_results = []
 
-        attrs = {}
-
         def handle(event):
             ds = Dataset()
             ds.SOPClassUID = CTImageStorage
@@ -5740,6 +5733,7 @@ class TestQRMoveServiceClass:
 
         assoc.release()
         scp.shutdown()
+        store_scp.shutdown()
 
         assert len(events) == 0
 
diff --git a/pynetdicom/tests/test_service_storage.py b/pynetdicom/tests/test_service_storage.py
index ad37c70d1..fb09c48e4 100644
--- a/pynetdicom/tests/test_service_storage.py
+++ b/pynetdicom/tests/test_service_storage.py
@@ -11,14 +11,12 @@ from pydicom import dcmread
 from pydicom.dataset import Dataset, FileMetaDataset
 from pydicom.uid import ExplicitVRLittleEndian, ImplicitVRLittleEndian
 
-from pynetdicom import AE, _config, evt, build_role, debug_logger
+from pynetdicom import AE, _config, evt, debug_logger
 from pynetdicom.dimse_primitives import C_STORE
 from pynetdicom.pdu_primitives import SOPClassExtendedNegotiation
-from pynetdicom.service_class import StorageServiceClass
 from pynetdicom.sop_class import (
     Verification,
     CTImageStorage,
-    RTImageStorage,
 )
 
 try:
@@ -97,7 +95,7 @@ class TestStorageServiceClass:
         req.MessageID = 1
         req.AffectedSOPClassUID = DATASET.SOPClassUID
         req.AffectedSOPInstanceUID = DATASET.SOPInstanceUID
-        req.Priorty = 0x0002
+        req.Priority = 0x0002
         req.DataSet = BytesIO(
             b"\x08\x00\x01\x00\x40\x40\x00\x00\x00\x00\x00\x08\x00\x49"
         )
@@ -147,7 +145,7 @@ class TestStorageServiceClass:
         req.MessageID = 1
         req.AffectedSOPClassUID = DATASET.SOPClassUID
         req.AffectedSOPInstanceUID = DATASET.SOPInstanceUID
-        req.Priorty = 0x0002
+        req.Priority = 0x0002
         req.DataSet = BytesIO(
             b"\x08\x00\x01\x00\x40\x40\x00\x00\x00\x00\x00\x08\x00\x49"
         )
@@ -235,7 +233,7 @@ class TestStorageServiceClass:
         assert assoc.is_established
         rsp = assoc.send_c_store(DATASET)
         assert rsp.Status == 0x0000
-        assert not "ErrorComment" in rsp
+        assert "ErrorComment" not in rsp
         assoc.release()
         assert assoc.is_released
 
diff --git a/pynetdicom/tests/test_transport.py b/pynetdicom/tests/test_transport.py
index 2049ef581..8610afde3 100644
--- a/pynetdicom/tests/test_transport.py
+++ b/pynetdicom/tests/test_transport.py
@@ -5,7 +5,6 @@ import logging
 import queue
 import os
 import platform
-import select
 import socket
 import ssl
 from struct import pack
@@ -21,11 +20,10 @@ import pynetdicom
 from pynetdicom import AE, evt, _config, debug_logger
 from pynetdicom.association import Association
 from pynetdicom.events import Event
-from pynetdicom._globals import MODE_REQUESTOR, MODE_ACCEPTOR
+from pynetdicom._globals import MODE_REQUESTOR
 from pynetdicom import transport
 from pynetdicom.transport import (
     AssociationSocket,
-    AssociationServer,
     ThreadedAssociationServer,
 )
 from pynetdicom.sop_class import Verification, RTImageStorage
@@ -117,9 +115,7 @@ class TestAssociationSocket:
             r"and bind 'address'. The original socket will not be rebound"
         )
         with caplog.at_level(logging.WARNING, logger="pynetdicom"):
-            sock = AssociationSocket(
-                self.assoc, client_socket="abc", address=("", 11112)
-            )
+            AssociationSocket(self.assoc, client_socket="abc", address=("", 11112))
 
             assert msg in caplog.text
 
@@ -700,7 +696,7 @@ class TestAssociationServer:
         scp.shutdown()
 
     def test_shutdown(self):
-        """test tring to shutdown a socket that's already closed."""
+        """test trying to shutdown a socket that's already closed."""
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         server = ae.start_server(("", 11112), block=False)
@@ -723,7 +719,7 @@ class TestAssociationServer:
 
         ae = AE()
         ae.add_requested_context("1.2.840.10008.1.1")
-        assoc = ae.associate("localhost", 11112)
+        ae.associate("localhost", 11112)
 
         assert server.socket.fileno() != -1
 
@@ -1249,7 +1245,6 @@ class TestEventHandlingAcceptor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_DATA_SENT, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_DATA_SENT) == []
 
@@ -1779,7 +1774,6 @@ class TestEventHandlingRequestor:
         self.ae = ae = AE()
         ae.add_supported_context(Verification)
         ae.add_requested_context(Verification)
-        handlers = [(evt.EVT_DATA_SENT, handle)]
         scp = ae.start_server(("", 11112), block=False)
         assert scp.get_handlers(evt.EVT_DATA_SENT) == []
 
diff --git a/pynetdicom/tests/test_utils.py b/pynetdicom/tests/test_utils.py
index fee3b940d..e0779894d 100644
--- a/pynetdicom/tests/test_utils.py
+++ b/pynetdicom/tests/test_utils.py
@@ -146,7 +146,12 @@ class TestPrettyBytes:
             bytestream, prefix="", delimiter="", items_per_line=10, max_size=100
         )
         assert len(result) == 11  # 10 plus the cutoff line
+        assert "Only dumping 100 bytes." == result[0]
+        assert "382e332e312e312e3120" == result[-1]
+
         result = pretty_bytes(bytestream, max_size=None)
+        assert "Only dumping 100 bytes." != result[0]
+        assert "  43  4f  4d  5f  30  39  30" == result[-1]
 
         # suffix
         result = pretty_bytes(bytestream, suffix="xxx")