PythonExtensionsCollection 0.2.0__py3-none-any.whl → 0.13.0__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.
- PythonExtensionsCollection/Comparison/CComparison.py +341 -0
- PythonExtensionsCollection/Comparison/__init__.py +13 -0
- PythonExtensionsCollection/File/CFile.py +326 -106
- PythonExtensionsCollection/File/__init__.py +1 -1
- PythonExtensionsCollection/Folder/CFolder.py +460 -0
- PythonExtensionsCollection/Folder/__init__.py +13 -0
- PythonExtensionsCollection/PythonExtensionsCollection.pdf +0 -0
- PythonExtensionsCollection/String/CString.py +128 -344
- PythonExtensionsCollection/String/__init__.py +1 -1
- PythonExtensionsCollection/Utils/CUtils.py +77 -74
- PythonExtensionsCollection/Utils/__init__.py +1 -1
- PythonExtensionsCollection/__init__.py +1 -1
- PythonExtensionsCollection/version.py +23 -0
- {PythonExtensionsCollection-0.2.0.dist-info → PythonExtensionsCollection-0.13.0.dist-info}/METADATA +57 -44
- PythonExtensionsCollection-0.13.0.dist-info/RECORD +18 -0
- {PythonExtensionsCollection-0.2.0.dist-info → PythonExtensionsCollection-0.13.0.dist-info}/WHEEL +1 -1
- PythonExtensionsCollection/doc/.buildinfo +0 -4
- PythonExtensionsCollection/doc/File.html +0 -315
- PythonExtensionsCollection/doc/String.html +0 -590
- PythonExtensionsCollection/doc/Utils.html +0 -209
- PythonExtensionsCollection/doc/_modules/PythonExtensionsCollection/File/CFile.html +0 -960
- PythonExtensionsCollection/doc/_modules/PythonExtensionsCollection/String/CString.html +0 -1221
- PythonExtensionsCollection/doc/_modules/PythonExtensionsCollection/Utils/CUtils.html +0 -431
- PythonExtensionsCollection/doc/_modules/index.html +0 -106
- PythonExtensionsCollection/doc/_sources/File.rst.txt +0 -28
- PythonExtensionsCollection/doc/_sources/String.rst.txt +0 -28
- PythonExtensionsCollection/doc/_sources/Utils.rst.txt +0 -28
- PythonExtensionsCollection/doc/_sources/additional_doc/Introduction.rst.txt +0 -365
- PythonExtensionsCollection/doc/_sources/index.rst.txt +0 -27
- PythonExtensionsCollection/doc/_static/_sphinx_javascript_frameworks_compat.js +0 -134
- PythonExtensionsCollection/doc/_static/alabaster.css +0 -701
- PythonExtensionsCollection/doc/_static/basic.css +0 -930
- PythonExtensionsCollection/doc/_static/custom.css +0 -1
- PythonExtensionsCollection/doc/_static/doctools.js +0 -264
- PythonExtensionsCollection/doc/_static/documentation_options.js +0 -14
- PythonExtensionsCollection/doc/_static/file.png +0 -0
- PythonExtensionsCollection/doc/_static/jquery-3.6.0.js +0 -10881
- PythonExtensionsCollection/doc/_static/jquery.js +0 -2
- PythonExtensionsCollection/doc/_static/language_data.js +0 -199
- PythonExtensionsCollection/doc/_static/minus.png +0 -0
- PythonExtensionsCollection/doc/_static/plus.png +0 -0
- PythonExtensionsCollection/doc/_static/pygments.css +0 -82
- PythonExtensionsCollection/doc/_static/searchtools.js +0 -531
- PythonExtensionsCollection/doc/_static/underscore-1.13.1.js +0 -2042
- PythonExtensionsCollection/doc/_static/underscore.js +0 -6
- PythonExtensionsCollection/doc/additional_doc/Introduction.html +0 -365
- PythonExtensionsCollection/doc/genindex.html +0 -292
- PythonExtensionsCollection/doc/index.html +0 -123
- PythonExtensionsCollection/doc/objects.inv +0 -0
- PythonExtensionsCollection/doc/py-modindex.html +0 -138
- PythonExtensionsCollection/doc/search.html +0 -127
- PythonExtensionsCollection/doc/searchindex.js +0 -1
- PythonExtensionsCollection-0.2.0.dist-info/RECORD +0 -48
- {PythonExtensionsCollection-0.2.0.dist-info → PythonExtensionsCollection-0.13.0.dist-info}/LICENSE +0 -0
- {PythonExtensionsCollection-0.2.0.dist-info → PythonExtensionsCollection-0.13.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# **************************************************************************************************************
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020-2022 Robert Bosch GmbH
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
# **************************************************************************************************************
|
|
18
|
+
#
|
|
19
|
+
# CComparison.py
|
|
20
|
+
#
|
|
21
|
+
# XC-CT/ECA3-Queckenstedt
|
|
22
|
+
#
|
|
23
|
+
# 03.04.2023
|
|
24
|
+
#
|
|
25
|
+
# **************************************************************************************************************
|
|
26
|
+
|
|
27
|
+
# -- import standard Python modules
|
|
28
|
+
import os, re
|
|
29
|
+
|
|
30
|
+
# -- import own Python modules
|
|
31
|
+
from PythonExtensionsCollection.File.CFile import CFile
|
|
32
|
+
from PythonExtensionsCollection.String.CString import CString
|
|
33
|
+
|
|
34
|
+
# **************************************************************************************************************
|
|
35
|
+
|
|
36
|
+
class CComparison(object):
|
|
37
|
+
"""The class ``CComparison`` contains mechanisms to compare two files either based on the original version of these files
|
|
38
|
+
or based on an extract (made with regular expressions) to ensure that only relevant parts of the files are compared.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
42
|
+
#TM***
|
|
43
|
+
|
|
44
|
+
def __init__(self):
|
|
45
|
+
self.__bSkipBlankLines = True
|
|
46
|
+
|
|
47
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
48
|
+
#TM***
|
|
49
|
+
|
|
50
|
+
def Compare(self, sFile_1=None, sFile_2=None, sPatternFile=None, sIgnorePatternFile=None, bDebug=False):
|
|
51
|
+
"""
|
|
52
|
+
Compares two files. While reading in all files empty lines are skipped.
|
|
53
|
+
|
|
54
|
+
**Arguments:**
|
|
55
|
+
|
|
56
|
+
* ``sFile_1``
|
|
57
|
+
|
|
58
|
+
/ *Condition*: required / *Type*: str /
|
|
59
|
+
|
|
60
|
+
First file used for comparison.
|
|
61
|
+
|
|
62
|
+
* ``sFile_2``
|
|
63
|
+
|
|
64
|
+
/ *Condition*: required / *Type*: str /
|
|
65
|
+
|
|
66
|
+
Second file used for comparison.
|
|
67
|
+
|
|
68
|
+
* ``sPatternFile``
|
|
69
|
+
|
|
70
|
+
/ *Condition*: optional / *Type*: str / *Default*: None /
|
|
71
|
+
|
|
72
|
+
Pattern file containing a set of regular expressions (line by line). The regular expressions are used to make
|
|
73
|
+
an extract of both input files. In this case the extracts are compared (instead of the original file content).
|
|
74
|
+
|
|
75
|
+
* ``sIgnorePatternFile``
|
|
76
|
+
|
|
77
|
+
/ *Condition*: optional / *Type*: str / *Default*: None /
|
|
78
|
+
|
|
79
|
+
Pattern file containing a set of strings (**not** regular expressuions; line by line). Every line containing one
|
|
80
|
+
of the strings, is skipped.
|
|
81
|
+
|
|
82
|
+
**Returns:**
|
|
83
|
+
|
|
84
|
+
* ``bIdentical``
|
|
85
|
+
|
|
86
|
+
/ *Type*: bool /
|
|
87
|
+
|
|
88
|
+
Indicates if the two input files (or their extracts) have the same content or not.
|
|
89
|
+
|
|
90
|
+
* ``bSuccess``
|
|
91
|
+
|
|
92
|
+
/ *Type*: bool /
|
|
93
|
+
|
|
94
|
+
Indicates if the computation of the method was successful or not.
|
|
95
|
+
|
|
96
|
+
* ``sResult``
|
|
97
|
+
|
|
98
|
+
/ *Type*: str /
|
|
99
|
+
|
|
100
|
+
The result of the computation of the method.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
sMethod = "CComparison.Compare"
|
|
104
|
+
|
|
105
|
+
bIdentical = None
|
|
106
|
+
bSuccess = None
|
|
107
|
+
sResult = "unknown"
|
|
108
|
+
|
|
109
|
+
if sFile_1 is None:
|
|
110
|
+
bSuccess = False
|
|
111
|
+
sResult = "sFile_1 is None"
|
|
112
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
113
|
+
return bIdentical, bSuccess, sResult
|
|
114
|
+
|
|
115
|
+
if sFile_2 is None:
|
|
116
|
+
bSuccess = False
|
|
117
|
+
sResult = "sFile_2 is None"
|
|
118
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
119
|
+
return bIdentical, bSuccess, sResult
|
|
120
|
+
|
|
121
|
+
sFile_1 = CString.NormalizePath(sFile_1)
|
|
122
|
+
sFile_2 = CString.NormalizePath(sFile_2)
|
|
123
|
+
|
|
124
|
+
if sFile_1 == sFile_2:
|
|
125
|
+
bSuccess = False
|
|
126
|
+
sResult = f"Path and name of input files are the same."
|
|
127
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
128
|
+
return bIdentical, bSuccess, sResult
|
|
129
|
+
|
|
130
|
+
if os.path.isfile(sFile_1) is False:
|
|
131
|
+
bSuccess = False
|
|
132
|
+
sResult = f"The file '{sFile_1}' does not exist"
|
|
133
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
134
|
+
return bIdentical, bSuccess, sResult
|
|
135
|
+
|
|
136
|
+
if os.path.isfile(sFile_2) is False:
|
|
137
|
+
bSuccess = False
|
|
138
|
+
sResult = f"The file '{sFile_2}' does not exist"
|
|
139
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
140
|
+
return bIdentical, bSuccess, sResult
|
|
141
|
+
|
|
142
|
+
if sPatternFile is not None:
|
|
143
|
+
# (optional)
|
|
144
|
+
sPatternFile = CString.NormalizePath(sPatternFile)
|
|
145
|
+
if os.path.isfile(sPatternFile) is False:
|
|
146
|
+
bSuccess = False
|
|
147
|
+
sResult = f"The file '{sPatternFile}' does not exist"
|
|
148
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
149
|
+
return bIdentical, bSuccess, sResult
|
|
150
|
+
# eof if sPatternFile is not None:
|
|
151
|
+
|
|
152
|
+
sIgnorePatterns = None
|
|
153
|
+
listIgnorePatterns = None
|
|
154
|
+
|
|
155
|
+
if sIgnorePatternFile is not None:
|
|
156
|
+
# (optional)
|
|
157
|
+
sIgnorePatternFile = CString.NormalizePath(sIgnorePatternFile)
|
|
158
|
+
if os.path.isfile(sIgnorePatternFile) is False:
|
|
159
|
+
bSuccess = False
|
|
160
|
+
sResult = f"The file '{sIgnorePatternFile}' does not exist"
|
|
161
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
162
|
+
return bIdentical, bSuccess, sResult
|
|
163
|
+
oIgnorePatternFile = CFile(sIgnorePatternFile)
|
|
164
|
+
listIgnorePatterns, bSuccess, sResult = oIgnorePatternFile.ReadLines()
|
|
165
|
+
del oIgnorePatternFile
|
|
166
|
+
if bSuccess is not True:
|
|
167
|
+
return bIdentical, bSuccess, CString.FormatResult(sMethod, bSuccess, sResult)
|
|
168
|
+
if listIgnorePatterns is not None:
|
|
169
|
+
sIgnorePatterns = ";".join(listIgnorePatterns)
|
|
170
|
+
# eof if sIgnorePatternFile is not None:
|
|
171
|
+
|
|
172
|
+
if bDebug is True:
|
|
173
|
+
print()
|
|
174
|
+
print("[FILE 1]")
|
|
175
|
+
oFile_1 = CFile(sFile_1)
|
|
176
|
+
listLines_1, bSuccess, sResult = oFile_1.ReadLines(bSkipBlankLines=self.__bSkipBlankLines, sContainsNot=sIgnorePatterns, bLStrip=True, bRStrip=True, bToScreen=bDebug)
|
|
177
|
+
del oFile_1
|
|
178
|
+
if bSuccess is False:
|
|
179
|
+
del listLines_1
|
|
180
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
181
|
+
return bIdentical, bSuccess, sResult
|
|
182
|
+
|
|
183
|
+
if bDebug is True:
|
|
184
|
+
print()
|
|
185
|
+
print("[FILE 2]")
|
|
186
|
+
oFile_2 = CFile(sFile_2)
|
|
187
|
+
listLines_2, bSuccess, sResult = oFile_2.ReadLines(bSkipBlankLines=self.__bSkipBlankLines, sContainsNot=sIgnorePatterns, bLStrip=True, bRStrip=True, bToScreen=bDebug)
|
|
188
|
+
del oFile_2
|
|
189
|
+
if bSuccess is False:
|
|
190
|
+
del listLines_1
|
|
191
|
+
del listLines_2
|
|
192
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
193
|
+
return bIdentical, bSuccess, sResult
|
|
194
|
+
|
|
195
|
+
if sPatternFile is None:
|
|
196
|
+
# no pattern given => compare the original version of the files
|
|
197
|
+
|
|
198
|
+
# -- check number of lines
|
|
199
|
+
nNrOfLines_1 = len(listLines_1)
|
|
200
|
+
nNrOfLines_2 = len(listLines_2)
|
|
201
|
+
if nNrOfLines_1 != nNrOfLines_2:
|
|
202
|
+
del listLines_1
|
|
203
|
+
del listLines_2
|
|
204
|
+
bIdentical = False
|
|
205
|
+
bSuccess = True
|
|
206
|
+
sResult = f"The files contain different number of lines (file 1: {nNrOfLines_1} lines, file 2: {nNrOfLines_2} lines"
|
|
207
|
+
return bIdentical, bSuccess, sResult
|
|
208
|
+
|
|
209
|
+
for nIndex, sLine_1 in enumerate(listLines_1):
|
|
210
|
+
sLine_2 = listLines_2[nIndex]
|
|
211
|
+
if sLine_1 != sLine_2:
|
|
212
|
+
del listLines_1
|
|
213
|
+
del listLines_2
|
|
214
|
+
bIdentical = False
|
|
215
|
+
bSuccess = True
|
|
216
|
+
sResult = f"Found deviating lines\n(1) '{sLine_1}'\n(2) '{sLine_2}'"
|
|
217
|
+
return bIdentical, bSuccess, sResult
|
|
218
|
+
else:
|
|
219
|
+
if bDebug is True:
|
|
220
|
+
print()
|
|
221
|
+
print("[PATTERN]")
|
|
222
|
+
# -- read pattern for comparison of files
|
|
223
|
+
oPatternFile = CFile(sPatternFile)
|
|
224
|
+
listPatterns, bSuccess, sResult = oPatternFile.ReadLines(bSkipBlankLines=True, bLStrip=True, bRStrip=True, bToScreen=bDebug)
|
|
225
|
+
del oPatternFile
|
|
226
|
+
if bSuccess is False:
|
|
227
|
+
del listPatterns
|
|
228
|
+
sResult = CString.FormatResult(sMethod, bSuccess, sResult)
|
|
229
|
+
return bIdentical, bSuccess, sResult
|
|
230
|
+
# -- compile pattern for comparison of files
|
|
231
|
+
listRegEx = []
|
|
232
|
+
for sPattern in listPatterns:
|
|
233
|
+
listRegEx.append(re.compile(sPattern))
|
|
234
|
+
del listPatterns
|
|
235
|
+
# -- apply pattern to content of file 1
|
|
236
|
+
listSubsetLines_1 = []
|
|
237
|
+
for sLine in listLines_1:
|
|
238
|
+
listLineParts_1 = []
|
|
239
|
+
for RegEx in listRegEx:
|
|
240
|
+
listPositions = RegEx.findall(sLine)
|
|
241
|
+
if len(listPositions) > 0:
|
|
242
|
+
for position in listPositions:
|
|
243
|
+
if isinstance(position, (tuple, list)):
|
|
244
|
+
for subposition in position:
|
|
245
|
+
listLineParts_1.append(subposition)
|
|
246
|
+
else:
|
|
247
|
+
listLineParts_1.append(position)
|
|
248
|
+
sLineNew_1 = " || ".join(listLineParts_1)
|
|
249
|
+
listSubsetLines_1.append(sLineNew_1)
|
|
250
|
+
break # for RegEx in listRegEx:
|
|
251
|
+
# eof for sLine in listLines_1:
|
|
252
|
+
del listLines_1
|
|
253
|
+
# -- apply pattern to content of file 2
|
|
254
|
+
listSubsetLines_2 = []
|
|
255
|
+
for sLine in listLines_2:
|
|
256
|
+
listLineParts_2 = []
|
|
257
|
+
for RegEx in listRegEx:
|
|
258
|
+
listPositions = RegEx.findall(sLine)
|
|
259
|
+
if len(listPositions) > 0:
|
|
260
|
+
for position in listPositions:
|
|
261
|
+
if isinstance(position, (tuple, list)):
|
|
262
|
+
for subposition in position:
|
|
263
|
+
listLineParts_2.append(subposition)
|
|
264
|
+
else:
|
|
265
|
+
listLineParts_2.append(position)
|
|
266
|
+
sLineNew_2 = " || ".join(listLineParts_2)
|
|
267
|
+
listSubsetLines_2.append(sLineNew_2)
|
|
268
|
+
break # for RegEx in listRegEx:
|
|
269
|
+
# eof for sLine in listLines_2:
|
|
270
|
+
del listLines_2
|
|
271
|
+
del listRegEx
|
|
272
|
+
|
|
273
|
+
# -- check number of lines
|
|
274
|
+
nNrOfSubsetLines_1 = len(listSubsetLines_1)
|
|
275
|
+
nNrOfSubsetLines_2 = len(listSubsetLines_2)
|
|
276
|
+
if nNrOfSubsetLines_1 != nNrOfSubsetLines_2:
|
|
277
|
+
print()
|
|
278
|
+
print(120*"-")
|
|
279
|
+
print("[SUBSET 1]")
|
|
280
|
+
sSubset1 = "\n".join(listSubsetLines_1)
|
|
281
|
+
print(f"{sSubset1}")
|
|
282
|
+
print(120*"-")
|
|
283
|
+
print("[SUBSET 2]")
|
|
284
|
+
sSubset2 = "\n".join(listSubsetLines_2)
|
|
285
|
+
print(f"{sSubset2}")
|
|
286
|
+
print(120*"-")
|
|
287
|
+
print()
|
|
288
|
+
del listSubsetLines_1
|
|
289
|
+
del listSubsetLines_2
|
|
290
|
+
bIdentical = False
|
|
291
|
+
bSuccess = True
|
|
292
|
+
sResult = f"The subsets of files contain different number of lines (subset 1: {nNrOfSubsetLines_1} lines, subset 2: {nNrOfSubsetLines_2} lines"
|
|
293
|
+
return bIdentical, bSuccess, sResult
|
|
294
|
+
|
|
295
|
+
# -- compare subsets of content
|
|
296
|
+
for nIndex, sLine_1 in enumerate(listSubsetLines_1):
|
|
297
|
+
sLine_2 = listSubsetLines_2[nIndex]
|
|
298
|
+
if sLine_1 != sLine_2:
|
|
299
|
+
del listSubsetLines_1
|
|
300
|
+
del listSubsetLines_2
|
|
301
|
+
if bDebug is True:
|
|
302
|
+
print()
|
|
303
|
+
print(120*"-")
|
|
304
|
+
print("[SUBSET 1]")
|
|
305
|
+
sSubset1 = "\n".join(listSubsetLines_1)
|
|
306
|
+
print(f"{sSubset1}")
|
|
307
|
+
print(120*"-")
|
|
308
|
+
print("[SUBSET 2]")
|
|
309
|
+
sSubset2 = "\n".join(listSubsetLines_2)
|
|
310
|
+
print(f"{sSubset2}")
|
|
311
|
+
print(120*"-")
|
|
312
|
+
print()
|
|
313
|
+
bIdentical = False
|
|
314
|
+
bSuccess = True
|
|
315
|
+
sResult = f"Found deviating lines\n(1) '{sLine_1}'\n(2) '{sLine_2}'"
|
|
316
|
+
return bIdentical, bSuccess, sResult
|
|
317
|
+
# eof for nIndex, sLine_1 in enumerate(listSubsetLines_1):
|
|
318
|
+
del listSubsetLines_1
|
|
319
|
+
del listSubsetLines_2
|
|
320
|
+
|
|
321
|
+
# eof else - if sPatternFile is None:
|
|
322
|
+
|
|
323
|
+
# final result
|
|
324
|
+
bIdentical = True
|
|
325
|
+
bSuccess = True
|
|
326
|
+
sResult = "Both files have same content"
|
|
327
|
+
|
|
328
|
+
return bIdentical, bSuccess, sResult
|
|
329
|
+
|
|
330
|
+
# eof def Compare(self, sFile_1=None, sFile_2=None, sPatternFile=None):
|
|
331
|
+
|
|
332
|
+
# eof class CComparison(object):
|
|
333
|
+
|
|
334
|
+
# --------------------------------------------------------------------------------------------------------------
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright 2020-2022 Robert Bosch GmbH
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|