scanoss 1.19.6__py3-none-any.whl → 1.20.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. protoc_gen_swagger/__init__.py +13 -13
  2. protoc_gen_swagger/options/__init__.py +13 -13
  3. protoc_gen_swagger/options/annotations_pb2.py +12 -9
  4. protoc_gen_swagger/options/annotations_pb2_grpc.py +1 -1
  5. protoc_gen_swagger/options/openapiv2_pb2.py +98 -96
  6. protoc_gen_swagger/options/openapiv2_pb2_grpc.py +1 -1
  7. scanoss/__init__.py +18 -18
  8. scanoss/api/__init__.py +17 -17
  9. scanoss/api/common/__init__.py +17 -17
  10. scanoss/api/common/v2/__init__.py +17 -17
  11. scanoss/api/common/v2/scanoss_common_pb2.py +18 -18
  12. scanoss/api/common/v2/scanoss_common_pb2_grpc.py +1 -1
  13. scanoss/api/components/__init__.py +17 -17
  14. scanoss/api/components/v2/__init__.py +17 -17
  15. scanoss/api/components/v2/scanoss_components_pb2.py +48 -38
  16. scanoss/api/components/v2/scanoss_components_pb2_grpc.py +142 -96
  17. scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +22 -16
  18. scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +75 -49
  19. scanoss/api/dependencies/__init__.py +17 -17
  20. scanoss/api/dependencies/v2/__init__.py +17 -17
  21. scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +30 -24
  22. scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +75 -49
  23. scanoss/api/provenance/__init__.py +23 -0
  24. scanoss/api/provenance/v2/__init__.py +23 -0
  25. scanoss/api/provenance/v2/scanoss_provenance_pb2.py +42 -0
  26. scanoss/api/provenance/v2/scanoss_provenance_pb2_grpc.py +108 -0
  27. scanoss/api/scanning/__init__.py +17 -17
  28. scanoss/api/scanning/v2/__init__.py +17 -17
  29. scanoss/api/scanning/v2/scanoss_scanning_pb2.py +10 -8
  30. scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +40 -32
  31. scanoss/api/semgrep/__init__.py +17 -17
  32. scanoss/api/semgrep/v2/__init__.py +17 -17
  33. scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +22 -18
  34. scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +71 -49
  35. scanoss/api/vulnerabilities/__init__.py +17 -17
  36. scanoss/api/vulnerabilities/v2/__init__.py +17 -17
  37. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +37 -27
  38. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +109 -72
  39. scanoss/cli.py +578 -264
  40. scanoss/components.py +99 -48
  41. scanoss/csvoutput.py +83 -56
  42. scanoss/cyclonedx.py +48 -46
  43. scanoss/data/build_date.txt +1 -1
  44. scanoss/file_filters.py +13 -15
  45. scanoss/filecount.py +43 -36
  46. scanoss/inspection/__init__.py +17 -17
  47. scanoss/inspection/copyleft.py +71 -58
  48. scanoss/inspection/policy_check.py +76 -53
  49. scanoss/inspection/undeclared_component.py +98 -75
  50. scanoss/inspection/utils/license_utils.py +66 -44
  51. scanoss/results.py +51 -60
  52. scanoss/scancodedeps.py +61 -38
  53. scanoss/scanner.py +203 -135
  54. scanoss/scanoss_settings.py +5 -3
  55. scanoss/scanossapi.py +98 -69
  56. scanoss/scanossbase.py +19 -19
  57. scanoss/scanossgrpc.py +107 -51
  58. scanoss/scanpostprocessor.py +9 -6
  59. scanoss/scantype.py +22 -21
  60. scanoss/spdxlite.py +265 -171
  61. scanoss/threadeddependencies.py +91 -61
  62. scanoss/threadedscanning.py +37 -31
  63. scanoss/utils/file.py +4 -4
  64. scanoss/winnowing.py +111 -47
  65. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/METADATA +1 -1
  66. scanoss-1.20.1.dist-info/RECORD +74 -0
  67. scanoss-1.19.6.dist-info/RECORD +0 -70
  68. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/LICENSE +0 -0
  69. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/WHEEL +0 -0
  70. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/entry_points.txt +0 -0
  71. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/top_level.txt +0 -0
@@ -119,7 +119,9 @@ class ScanossSettings(ScanossBase):
119
119
  result = validate_json_file(json_file)
120
120
  if not result.is_valid:
121
121
  if result.error_code == JSON_ERROR_FILE_NOT_FOUND or result.error_code == JSON_ERROR_FILE_EMPTY:
122
- self.print_msg(f'WARNING: The supplied settings file "{filepath}" was not found or is empty. Skipping...')
122
+ self.print_msg(
123
+ f'WARNING: The supplied settings file "{filepath}" was not found or is empty. Skipping...'
124
+ )
123
125
  return self
124
126
  else:
125
127
  raise ScanossSettingsError(f'Problem with settings file. {result.error}')
@@ -234,8 +236,8 @@ class ScanossSettings(ScanossBase):
234
236
  replace_bom_entries = self._remove_duplicates(self.normalize_bom_entries(self.get_bom_replace()))
235
237
  self.print_debug(
236
238
  f"Scan type set to 'identify'. Adding {len(include_bom_entries) + len(replace_bom_entries)} components as context to the scan. \n"
237
- f"From Include list: {[entry['purl'] for entry in include_bom_entries]} \n"
238
- f"From Replace list: {[entry['purl'] for entry in replace_bom_entries]} \n"
239
+ f'From Include list: {[entry["purl"] for entry in include_bom_entries]} \n'
240
+ f'From Replace list: {[entry["purl"] for entry in replace_bom_entries]} \n'
239
241
  )
240
242
  return include_bom_entries + replace_bom_entries
241
243
  return self.normalize_bom_entries(self.get_bom_remove())
scanoss/scanossapi.py CHANGED
@@ -1,26 +1,27 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2022, SCANOSS
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2022, SCANOSS
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
23
  """
24
+
24
25
  import logging
25
26
  import os
26
27
  import sys
@@ -39,10 +40,10 @@ from .scanossbase import ScanossBase
39
40
  from . import __version__
40
41
 
41
42
 
42
- DEFAULT_URL = "https://api.osskb.org/scan/direct" # default free service URL
43
- DEFAULT_URL2 = "https://api.scanoss.com/scan/direct" # default premium service URL
44
- SCANOSS_SCAN_URL = os.environ.get("SCANOSS_SCAN_URL") if os.environ.get("SCANOSS_SCAN_URL") else DEFAULT_URL
45
- SCANOSS_API_KEY = os.environ.get("SCANOSS_API_KEY") if os.environ.get("SCANOSS_API_KEY") else ''
43
+ DEFAULT_URL = 'https://api.osskb.org/scan/direct' # default free service URL
44
+ DEFAULT_URL2 = 'https://api.scanoss.com/scan/direct' # default premium service URL
45
+ SCANOSS_SCAN_URL = os.environ.get('SCANOSS_SCAN_URL') if os.environ.get('SCANOSS_SCAN_URL') else DEFAULT_URL
46
+ SCANOSS_API_KEY = os.environ.get('SCANOSS_API_KEY') if os.environ.get('SCANOSS_API_KEY') else ''
46
47
 
47
48
 
48
49
  class ScanossApi(ScanossBase):
@@ -51,10 +52,23 @@ class ScanossApi(ScanossBase):
51
52
  Currently support posting scan requests to the SCANOSS streaming API
52
53
  """
53
54
 
54
- def __init__(self, scan_format: str = None, flags: str = None,
55
- url: str = None, api_key: str = None, debug: bool = False, trace: bool = False, quiet: bool = False,
56
- timeout: int = 180, ver_details: str = None, ignore_cert_errors: bool = False,
57
- proxy: str = None, ca_cert: str = None, pac: PACFile = None, retry: int = 5):
55
+ def __init__(
56
+ self,
57
+ scan_format: str = None,
58
+ flags: str = None,
59
+ url: str = None,
60
+ api_key: str = None,
61
+ debug: bool = False,
62
+ trace: bool = False,
63
+ quiet: bool = False,
64
+ timeout: int = 180,
65
+ ver_details: str = None,
66
+ ignore_cert_errors: bool = False,
67
+ proxy: str = None,
68
+ ca_cert: str = None,
69
+ pac: PACFile = None,
70
+ retry: int = 5,
71
+ ):
58
72
  """
59
73
  Initialise the SCANOSS API
60
74
  :param scan_format: Scan format (default plain)
@@ -74,7 +88,7 @@ class ScanossApi(ScanossBase):
74
88
  super().__init__(debug, trace, quiet)
75
89
  self.url = url if url else SCANOSS_SCAN_URL
76
90
  self.api_key = api_key if api_key else SCANOSS_API_KEY
77
- if self.api_key and not url and not os.environ.get("SCANOSS_SCAN_URL"):
91
+ if self.api_key and not url and not os.environ.get('SCANOSS_SCAN_URL'):
78
92
  self.url = DEFAULT_URL2 # API key specific and no alternative URL, so use the default premium
79
93
  self.sbom = None
80
94
  self.scan_format = scan_format if scan_format else 'plain'
@@ -108,7 +122,7 @@ class ScanossApi(ScanossBase):
108
122
  self.verify = ca_cert
109
123
  self.session.verify = ca_cert
110
124
  self.proxies = {'https': proxy, 'http': proxy} if proxy else None
111
- if self. proxies:
125
+ if self.proxies:
112
126
  self.session.proxies = self.proxies
113
127
 
114
128
  def scan(self, wfp: str, context: str = None, scan_id: int = None):
@@ -122,16 +136,16 @@ class ScanossApi(ScanossBase):
122
136
  request_id = str(uuid.uuid4())
123
137
  form_data = {}
124
138
  if self.sbom:
125
- form_data['type'] = self.sbom.get("scan_type")
126
- form_data['assets'] = self.sbom.get("assets")
139
+ form_data['type'] = self.sbom.get('scan_type')
140
+ form_data['assets'] = self.sbom.get('assets')
127
141
  if self.scan_format:
128
142
  form_data['format'] = self.scan_format
129
143
  if self.flags:
130
144
  form_data['flags'] = self.flags
131
145
  if context:
132
146
  form_data['context'] = context
133
-
134
- scan_files = {'file': ("%s.wfp" % request_id, wfp)}
147
+
148
+ scan_files = {'file': ('%s.wfp' % request_id, wfp)}
135
149
  headers = self.headers
136
150
  headers['x-request-id'] = request_id # send a unique request id for each post
137
151
  r = None
@@ -140,75 +154,87 @@ class ScanossApi(ScanossBase):
140
154
  retry += 1
141
155
  try:
142
156
  r = None
143
- r = self.session.post(self.url, files=scan_files, data=form_data, headers=self.headers,
144
- timeout=self.timeout
145
- )
157
+ r = self.session.post(
158
+ self.url, files=scan_files, data=form_data, headers=self.headers, timeout=self.timeout
159
+ )
146
160
  except (requests.exceptions.SSLError, requests.exceptions.ProxyError) as e:
147
161
  self.print_stderr(f'ERROR: Exception ({e.__class__.__name__}) POSTing data - {e}.')
148
- raise Exception(f"ERROR: The SCANOSS API request failed for {self.url}") from e
162
+ raise Exception(f'ERROR: The SCANOSS API request failed for {self.url}') from e
149
163
  except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
150
164
  if retry > self.retry_limit: # Timed out retry_limit or more times, fail
151
165
  self.print_stderr(f'ERROR: {e.__class__.__name__} POSTing data ({request_id}) - {e}: {scan_files}')
152
- raise Exception(f"ERROR: The SCANOSS API request timed out ({e.__class__.__name__}) for"
153
- f" {self.url}") from e
166
+ raise Exception(
167
+ f'ERROR: The SCANOSS API request timed out ({e.__class__.__name__}) for {self.url}'
168
+ ) from e
154
169
  else:
155
170
  self.print_stderr(f'Warning: {e.__class__.__name__} communicating with {self.url}. Retrying...')
156
171
  time.sleep(5)
157
172
  except Exception as e:
158
- self.print_stderr(f'ERROR: Exception ({e.__class__.__name__}) POSTing data ({request_id}) - {e}:'
159
- f' {scan_files}')
160
- raise Exception(f"ERROR: The SCANOSS API request failed for {self.url}") from e
173
+ self.print_stderr(
174
+ f'ERROR: Exception ({e.__class__.__name__}) POSTing data ({request_id}) - {e}: {scan_files}'
175
+ )
176
+ raise Exception(f'ERROR: The SCANOSS API request failed for {self.url}') from e
161
177
  else:
162
178
  if r is None:
163
179
  if retry > self.retry_limit: # No response retry_limit or more times, fail
164
180
  self.save_bad_req_wfp(scan_files, request_id, scan_id)
165
- raise Exception(f"ERROR: The SCANOSS API request ({request_id}) response object is empty "
166
- f"for {self.url}")
181
+ raise Exception(
182
+ f'ERROR: The SCANOSS API request ({request_id}) response object is empty for {self.url}'
183
+ )
167
184
  else:
168
185
  self.print_stderr(f'Warning: No response received from {self.url}. Retrying...')
169
186
  time.sleep(5)
170
187
  elif r.status_code == 503: # Service limits have most likely been reached
171
- self.print_stderr(f'ERROR: SCANOSS API rejected the scan request ({request_id}) due to '
172
- f'service limits being exceeded')
188
+ self.print_stderr(
189
+ f'ERROR: SCANOSS API rejected the scan request ({request_id}) due to '
190
+ f'service limits being exceeded'
191
+ )
173
192
  self.print_stderr(f'ERROR: Details: {r.text.strip()}')
174
- raise Exception(f"ERROR: {r.status_code} - The SCANOSS API request ({request_id}) rejected "
175
- f"for {self.url} due to service limits being exceeded.")
193
+ raise Exception(
194
+ f'ERROR: {r.status_code} - The SCANOSS API request ({request_id}) rejected '
195
+ f'for {self.url} due to service limits being exceeded.'
196
+ )
176
197
  elif r.status_code >= 400:
177
198
  if retry > self.retry_limit: # No response retry_limit or more times, fail
178
199
  self.save_bad_req_wfp(scan_files, request_id, scan_id)
179
200
  raise Exception(
180
- f"ERROR: The SCANOSS API returned the following error: HTTP {r.status_code}, "
181
- f"{r.text.strip()}")
201
+ f'ERROR: The SCANOSS API returned the following error: HTTP {r.status_code}, '
202
+ f'{r.text.strip()}'
203
+ )
182
204
  else:
183
205
  self.save_bad_req_wfp(scan_files, request_id, scan_id)
184
- self.print_stderr(f'Warning: Error response code {r.status_code} ({r.text.strip()}) from '
185
- f'{self.url}. Retrying...')
206
+ self.print_stderr(
207
+ f'Warning: Error response code {r.status_code} ({r.text.strip()}) from '
208
+ f'{self.url}. Retrying...'
209
+ )
186
210
  time.sleep(5)
187
211
  else:
188
212
  break # Valid response, break out of the retry loop
189
213
  # End of while loop
190
214
  if r is None:
191
215
  self.save_bad_req_wfp(scan_files, request_id, scan_id)
192
- raise Exception(f"ERROR: The SCANOSS API request response object is empty for {self.url}")
216
+ raise Exception(f'ERROR: The SCANOSS API request response object is empty for {self.url}')
193
217
  try:
194
218
  if 'xml' in self.scan_format: # TODO remove XML parsing option?
195
219
  return r.text
196
220
  json_resp = r.json()
197
221
  return json_resp
198
222
  except (JSONDecodeError, Exception) as e:
199
- self.print_stderr(f'ERROR: The SCANOSS API returned an invalid JSON '
200
- f'({e.__class__.__name__} - {request_id}): {e}')
223
+ self.print_stderr(
224
+ f'ERROR: The SCANOSS API returned an invalid JSON ({e.__class__.__name__} - {request_id}): {e}'
225
+ )
201
226
  bad_json_file = f'bad_json-{scan_id}-{request_id}.txt' if scan_id else f'bad_json-{request_id}.txt'
202
227
  self.print_stderr(f'Ignoring result. Please look in "{bad_json_file}" for more details.')
203
228
  try:
204
229
  with open(bad_json_file, 'w') as f:
205
- f.write(f"---Request ID Begin---\n{request_id}\n---Request ID End---\n")
206
- f.write(f"---WFP Begin---\n{scan_files}\n---WFP End---\n---Bad JSON Begin---\n")
230
+ f.write(f'---Request ID Begin---\n{request_id}\n---Request ID End---\n')
231
+ f.write(f'---WFP Begin---\n{scan_files}\n---WFP End---\n---Bad JSON Begin---\n')
207
232
  f.write(r.text)
208
- f.write("---Bad JSON End---\n")
233
+ f.write('---Bad JSON End---\n')
209
234
  except Exception as ee:
210
- self.print_stderr(f'Warning: Issue writing bad json file - {bad_json_file} ({ee.__class__.__name__}):'
211
- f' {ee}')
235
+ self.print_stderr(
236
+ f'Warning: Issue writing bad json file - {bad_json_file} ({ee.__class__.__name__}): {ee}'
237
+ )
212
238
  return None
213
239
 
214
240
  def save_bad_req_wfp(self, scan_files, request_id, scan_id):
@@ -220,19 +246,22 @@ class ScanossApi(ScanossBase):
220
246
  """
221
247
  bad_req_file = f'bad_request-{scan_id}-{request_id}.txt' if scan_id else f'bad_request-{request_id}.txt'
222
248
  try:
223
- self.print_stderr(f'No response object returned from API. Please look in "{bad_req_file}" for the '
224
- f'offending WFP.')
249
+ self.print_stderr(
250
+ f'No response object returned from API. Please look in "{bad_req_file}" for the offending WFP.'
251
+ )
225
252
  with open(bad_req_file, 'w') as f:
226
- f.write(f"---Request ID Begin---\n{request_id}\n---Request ID End---\n")
227
- f.write(f"---WFP Begin---\n{scan_files}\n---WFP End---\n")
253
+ f.write(f'---Request ID Begin---\n{request_id}\n---Request ID End---\n')
254
+ f.write(f'---WFP Begin---\n{scan_files}\n---WFP End---\n')
228
255
  except Exception as ee:
229
- self.print_stderr(f'Warning: Issue writing bad request file - {bad_req_file} ({ee.__class__.__name__}):'
230
- f' {ee}')
231
-
256
+ self.print_stderr(
257
+ f'Warning: Issue writing bad request file - {bad_req_file} ({ee.__class__.__name__}): {ee}'
258
+ )
259
+
232
260
  def set_sbom(self, sbom):
233
261
  self.sbom = sbom
234
262
  return self
235
263
 
264
+
236
265
  #
237
266
  # End of ScanossApi Class
238
267
  #
scanoss/scanossbase.py CHANGED
@@ -1,25 +1,25 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
2
+ SPDX-License-Identifier: MIT
3
3
 
4
- Copyright (c) 2021, SCANOSS
4
+ Copyright (c) 2021, SCANOSS
5
5
 
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
12
 
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
15
 
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
23
  """
24
24
 
25
25
  import sys
@@ -85,7 +85,7 @@ class ScanossBase:
85
85
  Print message to file if provided or stdout
86
86
  """
87
87
  if file:
88
- with open(file, "w") as f:
88
+ with open(file, 'w') as f:
89
89
  f.write(msg)
90
90
  else:
91
91
  self.print_stdout(msg)
@@ -95,7 +95,7 @@ class ScanossBase:
95
95
  Print message to file if provided or stderr
96
96
  """
97
97
  if file:
98
- with open(file, "w") as f:
98
+ with open(file, 'w') as f:
99
99
  f.write(msg)
100
100
  else:
101
101
  self.print_stderr(msg)