prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  path_spec.parent is None exception
  ```
  FsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']
  Traceback (most recent call last):
    File "/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/workers/__init__.py", line 881, in run_wrapper
      self.evidence_setup(evidence)
    File "/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/workers/__init__.py", line 499, in evidence_setup
      evidence.preprocess(self.tmp_dir, required_states=self.REQUIRED_STATES)
    File "/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/evidence.py", line 341, in preprocess
      self._preprocess(tmp_dir, required_states)
    File "/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/evidence.py", line 575, in _preprocess
      encryption_type = partitions.GetPartitionEncryptionType(path_spec)
    File "/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/processors/partitions.py", line 66, in GetPartitionEncryptionType
      if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:
  AttributeError: 'NoneType' object has no attribute 'type_indicator'
  
  No state_manager initialized, not updating Task info
  Trying last ditch attempt to close result
  Task Result was auto-closed from task executor on turbinia-worker-6eaf93e7aee7c9cf-0 likely due to previous failures.  Previous status: [FsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']]
  Task Result was auto-closed from task executor on turbinia-worker-6eaf93e7aee7c9cf-0 likely due to previous failures.  Previous status: [FsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']]
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `turbinia/processors/partitions.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # Copyright 2021 Google LLC
  3 #
  4 # Licensed under the Apache License, Version 2.0 (the "License");
  5 # you may not use this file except in compliance with the License.
  6 # You may obtain a copy of the License at
  7 #
  8 # https://www.apache.org/licenses/LICENSE-2.0
  9 #
  10 # Unless required by applicable law or agreed to in writing, software
  11 # distributed under the License is distributed on an "AS IS" BASIS,
  12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 # See the License for the specific language governing permissions and
  14 # limitations under the License.
  15 """Evidence processor to enumerate partitions."""
  16 
  17 import logging
  18 
  19 from dfvfs.helpers import volume_scanner
  20 from dfvfs.lib import definitions as dfvfs_definitions
  21 from dfvfs.lib import errors as dfvfs_errors
  22 
  23 from turbinia.lib.dfvfs_classes import UnattendedVolumeScannerMediator
  24 from turbinia import TurbiniaException
  25 
  26 log = logging.getLogger('turbinia')
  27 
  28 
  29 def Enumerate(evidence):
  30   """Uses dfVFS to enumerate partitions in a disk / image.
  31 
  32   Args:
  33     evidence: Evidence object to be scanned.
  34 
  35   Raises:
  36     TurbiniaException if source evidence can't be scanned.
  37 
  38   Returns:
  39     list[dfVFS.path_spec]: path specs for identified partitions
  40   """
  41   dfvfs_definitions.PREFERRED_GPT_BACK_END = (
  42       dfvfs_definitions.TYPE_INDICATOR_GPT)
  43   mediator = UnattendedVolumeScannerMediator()
  44   mediator.credentials = evidence.credentials
  45   path_specs = []
  46   try:
  47     scanner = volume_scanner.VolumeScanner(mediator=mediator)
  48     path_specs = scanner.GetBasePathSpecs(evidence.local_path)
  49   except dfvfs_errors.ScannerError as e:
  50     raise TurbiniaException(
  51         'Could not enumerate partitions [{0!s}]: {1!s}'.format(
  52             evidence.local_path, e))
  53 
  54   return path_specs
  55 
  56 
  57 def GetPartitionEncryptionType(path_spec):
  58   """Checks a partition for encryption.
  59 
  60   Args:
  61     path_spec (dfVFS.path_spec): Partition path_spec.
  62 
  63   Returns:
  64     String representing the type of encryption, or None.
  65   """
  66   encryption_type = None
  67   if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:
  68     encryption_type = 'BDE'
  69   return encryption_type
  70 
  71 
  72 def GetPathSpecByLocation(path_specs, location):
  73   """Finds a path_spec from a list of path_specs for a given location.
  74 
  75   Args:
  76     path_specs (list[dfVFS.path_spec]): List of path_specs from volume scanner.
  77     location (str): dfVFS location to search for.
  78 
  79   Returns:
  80     dfVFS.path_spec for the given location or None if not found.
  81   """
  82   for path_spec in path_specs:
  83     child_path_spec = path_spec
  84     fs_location = getattr(path_spec, 'location', None)
  85     while path_spec.HasParent():
  86       type_indicator = path_spec.type_indicator
  87       if type_indicator in (dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION,
  88                             dfvfs_definitions.TYPE_INDICATOR_GPT):
  89         if fs_location in ('\\', '/'):
  90           fs_location = getattr(path_spec, 'location', None)
  91         break
  92       path_spec = path_spec.parent
  93     if fs_location == location:
  94       return child_path_spec
  95   return None
  96
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/turbinia/processors/partitions.py b/turbinia/processors/partitions.py
  --- a/turbinia/processors/partitions.py
  +++ b/turbinia/processors/partitions.py
  @@ -64,6 +64,10 @@
       String representing the type of encryption, or None.
     """
     encryption_type = None
  +
  +  if not path_spec.HasParent():
  +    return None
  +
     if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:
       encryption_type = 'BDE'
     return encryption_type
  
verification_info: {"golden_diff": "diff --git a/turbinia/processors/partitions.py b/turbinia/processors/partitions.py\n--- a/turbinia/processors/partitions.py\n+++ b/turbinia/processors/partitions.py\n@@ -64,6 +64,10 @@\n     String representing the type of encryption, or None.\n   \"\"\"\n   encryption_type = None\n+\n+  if not path_spec.HasParent():\n+    return None\n+\n   if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:\n     encryption_type = 'BDE'\n   return encryption_type\n", "issue": "path_spec.parent is None exception\n```\r\nFsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/workers/__init__.py\", line 881, in run_wrapper\r\n    self.evidence_setup(evidence)\r\n  File \"/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/workers/__init__.py\", line 499, in evidence_setup\r\n    evidence.preprocess(self.tmp_dir, required_states=self.REQUIRED_STATES)\r\n  File \"/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/evidence.py\", line 341, in preprocess\r\n    self._preprocess(tmp_dir, required_states)\r\n  File \"/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/evidence.py\", line 575, in _preprocess\r\n    encryption_type = partitions.GetPartitionEncryptionType(path_spec)\r\n  File \"/usr/local/lib/python3.6/dist-packages/turbinia-20210208.4.dev19+g7c02e5e-py3.6.egg/turbinia/processors/partitions.py\", line 66, in GetPartitionEncryptionType\r\n    if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:\r\nAttributeError: 'NoneType' object has no attribute 'type_indicator'\r\n\r\nNo state_manager initialized, not updating Task info\r\nTrying last ditch attempt to close result\r\nTask Result was auto-closed from task executor on turbinia-worker-6eaf93e7aee7c9cf-0 likely due to previous failures.  Previous status: [FsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']]\r\nTask Result was auto-closed from task executor on turbinia-worker-6eaf93e7aee7c9cf-0 likely due to previous failures.  Previous status: [FsstatTask Task failed with exception: ['NoneType' object has no attribute 'type_indicator']]\r\n```\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Evidence processor to enumerate partitions.\"\"\"\n\nimport logging\n\nfrom dfvfs.helpers import volume_scanner\nfrom dfvfs.lib import definitions as dfvfs_definitions\nfrom dfvfs.lib import errors as dfvfs_errors\n\nfrom turbinia.lib.dfvfs_classes import UnattendedVolumeScannerMediator\nfrom turbinia import TurbiniaException\n\nlog = logging.getLogger('turbinia')\n\n\ndef Enumerate(evidence):\n  \"\"\"Uses dfVFS to enumerate partitions in a disk / image.\n\n  Args:\n    evidence: Evidence object to be scanned.\n\n  Raises:\n    TurbiniaException if source evidence can't be scanned.\n\n  Returns:\n    list[dfVFS.path_spec]: path specs for identified partitions\n  \"\"\"\n  dfvfs_definitions.PREFERRED_GPT_BACK_END = (\n      dfvfs_definitions.TYPE_INDICATOR_GPT)\n  mediator = UnattendedVolumeScannerMediator()\n  mediator.credentials = evidence.credentials\n  path_specs = []\n  try:\n    scanner = volume_scanner.VolumeScanner(mediator=mediator)\n    path_specs = scanner.GetBasePathSpecs(evidence.local_path)\n  except dfvfs_errors.ScannerError as e:\n    raise TurbiniaException(\n        'Could not enumerate partitions [{0!s}]: {1!s}'.format(\n            evidence.local_path, e))\n\n  return path_specs\n\n\ndef GetPartitionEncryptionType(path_spec):\n  \"\"\"Checks a partition for encryption.\n\n  Args:\n    path_spec (dfVFS.path_spec): Partition path_spec.\n\n  Returns:\n    String representing the type of encryption, or None.\n  \"\"\"\n  encryption_type = None\n  if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:\n    encryption_type = 'BDE'\n  return encryption_type\n\n\ndef GetPathSpecByLocation(path_specs, location):\n  \"\"\"Finds a path_spec from a list of path_specs for a given location.\n\n  Args:\n    path_specs (list[dfVFS.path_spec]): List of path_specs from volume scanner.\n    location (str): dfVFS location to search for.\n\n  Returns:\n    dfVFS.path_spec for the given location or None if not found.\n  \"\"\"\n  for path_spec in path_specs:\n    child_path_spec = path_spec\n    fs_location = getattr(path_spec, 'location', None)\n    while path_spec.HasParent():\n      type_indicator = path_spec.type_indicator\n      if type_indicator in (dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION,\n                            dfvfs_definitions.TYPE_INDICATOR_GPT):\n        if fs_location in ('\\\\', '/'):\n          fs_location = getattr(path_spec, 'location', None)\n        break\n      path_spec = path_spec.parent\n    if fs_location == location:\n      return child_path_spec\n  return None\n", "path": "turbinia/processors/partitions.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Evidence processor to enumerate partitions.\"\"\"\n\nimport logging\n\nfrom dfvfs.helpers import volume_scanner\nfrom dfvfs.lib import definitions as dfvfs_definitions\nfrom dfvfs.lib import errors as dfvfs_errors\n\nfrom turbinia.lib.dfvfs_classes import UnattendedVolumeScannerMediator\nfrom turbinia import TurbiniaException\n\nlog = logging.getLogger('turbinia')\n\n\ndef Enumerate(evidence):\n  \"\"\"Uses dfVFS to enumerate partitions in a disk / image.\n\n  Args:\n    evidence: Evidence object to be scanned.\n\n  Raises:\n    TurbiniaException if source evidence can't be scanned.\n\n  Returns:\n    list[dfVFS.path_spec]: path specs for identified partitions\n  \"\"\"\n  dfvfs_definitions.PREFERRED_GPT_BACK_END = (\n      dfvfs_definitions.TYPE_INDICATOR_GPT)\n  mediator = UnattendedVolumeScannerMediator()\n  mediator.credentials = evidence.credentials\n  path_specs = []\n  try:\n    scanner = volume_scanner.VolumeScanner(mediator=mediator)\n    path_specs = scanner.GetBasePathSpecs(evidence.local_path)\n  except dfvfs_errors.ScannerError as e:\n    raise TurbiniaException(\n        'Could not enumerate partitions [{0!s}]: {1!s}'.format(\n            evidence.local_path, e))\n\n  return path_specs\n\n\ndef GetPartitionEncryptionType(path_spec):\n  \"\"\"Checks a partition for encryption.\n\n  Args:\n    path_spec (dfVFS.path_spec): Partition path_spec.\n\n  Returns:\n    String representing the type of encryption, or None.\n  \"\"\"\n  encryption_type = None\n\n  if not path_spec.HasParent():\n    return None\n\n  if path_spec.parent.type_indicator == dfvfs_definitions.TYPE_INDICATOR_BDE:\n    encryption_type = 'BDE'\n  return encryption_type\n\n\ndef GetPathSpecByLocation(path_specs, location):\n  \"\"\"Finds a path_spec from a list of path_specs for a given location.\n\n  Args:\n    path_specs (list[dfVFS.path_spec]): List of path_specs from volume scanner.\n    location (str): dfVFS location to search for.\n\n  Returns:\n    dfVFS.path_spec for the given location or None if not found.\n  \"\"\"\n  for path_spec in path_specs:\n    child_path_spec = path_spec\n    fs_location = getattr(path_spec, 'location', None)\n    while path_spec.HasParent():\n      type_indicator = path_spec.type_indicator\n      if type_indicator in (dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION,\n                            dfvfs_definitions.TYPE_INDICATOR_GPT):\n        if fs_location in ('\\\\', '/'):\n          fs_location = getattr(path_spec, 'location', None)\n        break\n      path_spec = path_spec.parent\n    if fs_location == location:\n      return child_path_spec\n  return None\n", "path": "turbinia/processors/partitions.py"}]}