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()

```

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

{"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"}]}