c2cciutils 1.7.0.dev277__py3-none-any.whl → 1.7.0.dev281__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.
- c2cciutils/audit.py +6 -5
- c2cciutils/configuration.py +3 -18
- c2cciutils/schema.json +2 -5
- c2cciutils/scripts/main.py +2 -5
- c2cciutils/scripts/publish.py +2 -2
- {c2cciutils-1.7.0.dev277.dist-info → c2cciutils-1.7.0.dev281.dist-info}/METADATA +2 -1
- {c2cciutils-1.7.0.dev277.dist-info → c2cciutils-1.7.0.dev281.dist-info}/RECORD +10 -11
- {c2cciutils-1.7.0.dev277.dist-info → c2cciutils-1.7.0.dev281.dist-info}/entry_points.txt +0 -1
- c2cciutils/security.py +0 -112
- {c2cciutils-1.7.0.dev277.dist-info → c2cciutils-1.7.0.dev281.dist-info}/LICENSE +0 -0
- {c2cciutils-1.7.0.dev277.dist-info → c2cciutils-1.7.0.dev281.dist-info}/WHEEL +0 -0
c2cciutils/audit.py
CHANGED
|
@@ -9,9 +9,10 @@ import subprocess # nosec
|
|
|
9
9
|
import sys
|
|
10
10
|
from argparse import Namespace
|
|
11
11
|
|
|
12
|
+
import security_md
|
|
13
|
+
|
|
12
14
|
import c2cciutils
|
|
13
15
|
import c2cciutils.configuration
|
|
14
|
-
import c2cciutils.security
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def print_versions(
|
|
@@ -209,7 +210,7 @@ def outdated_versions(
|
|
|
209
210
|
return True
|
|
210
211
|
|
|
211
212
|
with open("SECURITY.md", encoding="utf-8") as security_file:
|
|
212
|
-
security =
|
|
213
|
+
security = security_md.Security(security_file.read())
|
|
213
214
|
|
|
214
215
|
version_index = security.version_index
|
|
215
216
|
date_index = security.support_until_index
|
|
@@ -217,9 +218,9 @@ def outdated_versions(
|
|
|
217
218
|
for row in security.data:
|
|
218
219
|
str_date = row[date_index]
|
|
219
220
|
if str_date not in (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
security_md.SUPPORT_TO_BE_DEFINED,
|
|
222
|
+
security_md.SUPPORT_BEST_EFFORT,
|
|
223
|
+
security_md.SUPPORT_UNSUPPORTED,
|
|
223
224
|
):
|
|
224
225
|
date = datetime.datetime.strptime(row[date_index], "%d/%m/%Y")
|
|
225
226
|
if date < datetime.datetime.now():
|
c2cciutils/configuration.py
CHANGED
|
@@ -456,18 +456,15 @@ K8S_DB_CHART_OPTIONS_DEFAULT = {
|
|
|
456
456
|
|
|
457
457
|
|
|
458
458
|
PRINT_VERSIONS_VERSIONS_DEFAULT = [
|
|
459
|
-
{"name": "c2cciutils", "cmd": ["c2cciutils", "--version"]},
|
|
460
459
|
{"name": "python", "cmd": ["python3", "--version"]},
|
|
461
460
|
{"name": "pip", "cmd": ["python3", "-m", "pip", "--version"]},
|
|
462
|
-
{"name": "twine", "cmd": ["twine", "--version"]},
|
|
463
461
|
{"name": "node", "prefix": "node ", "cmd": ["node", "--version"]},
|
|
464
462
|
{"name": "npm", "prefix": "npm ", "cmd": ["npm", "--version"]},
|
|
465
|
-
{"name": "make", "cmd": ["make", "--version"]
|
|
463
|
+
{"name": "make", "cmd": ["make", "--version"]},
|
|
466
464
|
{"name": "docker", "cmd": ["docker", "--version"]},
|
|
467
465
|
{"name": "docker compose", "cmd": ["docker", "compose", "version"]},
|
|
468
466
|
{"name": "java", "cmd": ["java", "-version"]},
|
|
469
|
-
{"name": "
|
|
470
|
-
{"name": "helm", "cmd": ["helm", "version"]},
|
|
467
|
+
{"name": "helm", "cmd": ["helm", "version"], "prefix": "HELM: "},
|
|
471
468
|
]
|
|
472
469
|
""" Default value of the field path 'Print versions versions' """
|
|
473
470
|
|
|
@@ -582,10 +579,6 @@ class PrintVersions(TypedDict, total=False):
|
|
|
582
579
|
Print versions versions.
|
|
583
580
|
|
|
584
581
|
default:
|
|
585
|
-
- cmd:
|
|
586
|
-
- c2cciutils
|
|
587
|
-
- --version
|
|
588
|
-
name: c2cciutils
|
|
589
582
|
- cmd:
|
|
590
583
|
- python3
|
|
591
584
|
- --version
|
|
@@ -596,10 +589,6 @@ class PrintVersions(TypedDict, total=False):
|
|
|
596
589
|
- pip
|
|
597
590
|
- --version
|
|
598
591
|
name: pip
|
|
599
|
-
- cmd:
|
|
600
|
-
- twine
|
|
601
|
-
- --version
|
|
602
|
-
name: twine
|
|
603
592
|
- cmd:
|
|
604
593
|
- node
|
|
605
594
|
- --version
|
|
@@ -614,7 +603,6 @@ class PrintVersions(TypedDict, total=False):
|
|
|
614
603
|
- make
|
|
615
604
|
- --version
|
|
616
605
|
name: make
|
|
617
|
-
prefix: 'make '
|
|
618
606
|
- cmd:
|
|
619
607
|
- docker
|
|
620
608
|
- --version
|
|
@@ -628,14 +616,11 @@ class PrintVersions(TypedDict, total=False):
|
|
|
628
616
|
- java
|
|
629
617
|
- -version
|
|
630
618
|
name: java
|
|
631
|
-
- cmd:
|
|
632
|
-
- kubectl
|
|
633
|
-
- version
|
|
634
|
-
name: kubectl
|
|
635
619
|
- cmd:
|
|
636
620
|
- helm
|
|
637
621
|
- version
|
|
638
622
|
name: helm
|
|
623
|
+
prefix: 'HELM: '
|
|
639
624
|
"""
|
|
640
625
|
|
|
641
626
|
|
c2cciutils/schema.json
CHANGED
|
@@ -451,18 +451,15 @@
|
|
|
451
451
|
"title": "Print versions versions",
|
|
452
452
|
"type": "array",
|
|
453
453
|
"default": [
|
|
454
|
-
{ "name": "c2cciutils", "cmd": ["c2cciutils", "--version"] },
|
|
455
454
|
{ "name": "python", "cmd": ["python3", "--version"] },
|
|
456
455
|
{ "name": "pip", "cmd": ["python3", "-m", "pip", "--version"] },
|
|
457
|
-
{ "name": "twine", "cmd": ["twine", "--version"] },
|
|
458
456
|
{ "name": "node", "prefix": "node ", "cmd": ["node", "--version"] },
|
|
459
457
|
{ "name": "npm", "prefix": "npm ", "cmd": ["npm", "--version"] },
|
|
460
|
-
{ "name": "make", "cmd": ["make", "--version"]
|
|
458
|
+
{ "name": "make", "cmd": ["make", "--version"] },
|
|
461
459
|
{ "name": "docker", "cmd": ["docker", "--version"] },
|
|
462
460
|
{ "name": "docker compose", "cmd": ["docker", "compose", "version"] },
|
|
463
461
|
{ "name": "java", "cmd": ["java", "-version"] },
|
|
464
|
-
{ "name": "
|
|
465
|
-
{ "name": "helm", "cmd": ["helm", "version"] }
|
|
462
|
+
{ "name": "helm", "cmd": ["helm", "version"], "prefix": "HELM: " }
|
|
466
463
|
],
|
|
467
464
|
"items": {
|
|
468
465
|
"type": "object",
|
c2cciutils/scripts/main.py
CHANGED
|
@@ -27,11 +27,8 @@ def main() -> None:
|
|
|
27
27
|
print(yaml.dump(c2cciutils.get_config(), default_flow_style=False, Dumper=yaml.SafeDumper))
|
|
28
28
|
|
|
29
29
|
if args.version:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
print(f"{pkg} {pkg_resources.get_distribution(pkg).version}")
|
|
33
|
-
except pkg_resources.DistributionNotFound:
|
|
34
|
-
print(f"{pkg} missing")
|
|
30
|
+
version = pkg_resources.get_distribution("c2cciutils").version
|
|
31
|
+
print(f"c2cciutils {version}")
|
|
35
32
|
|
|
36
33
|
if args.ls_files_mime:
|
|
37
34
|
for file_name in c2cciutils.get_git_files_mime(args.ls_files_mime):
|
c2cciutils/scripts/publish.py
CHANGED
|
@@ -13,6 +13,7 @@ from re import Match
|
|
|
13
13
|
from typing import Optional, cast
|
|
14
14
|
|
|
15
15
|
import requests
|
|
16
|
+
import security_md
|
|
16
17
|
import yaml
|
|
17
18
|
|
|
18
19
|
import c2cciutils
|
|
@@ -21,7 +22,6 @@ import c2cciutils.env
|
|
|
21
22
|
import c2cciutils.lib.docker
|
|
22
23
|
import c2cciutils.publish
|
|
23
24
|
import c2cciutils.scripts.download_applications
|
|
24
|
-
import c2cciutils.security
|
|
25
25
|
from c2cciutils.publish import GoogleCalendar
|
|
26
26
|
from c2cciutils.scripts.trigger_image_update import dispatch
|
|
27
27
|
|
|
@@ -213,7 +213,7 @@ def main() -> None:
|
|
|
213
213
|
print(f"::error:: {security_response.status_code} {security_response.text}")
|
|
214
214
|
sys.exit(1)
|
|
215
215
|
|
|
216
|
-
security =
|
|
216
|
+
security = security_md.Security(security_text)
|
|
217
217
|
version_index = security.version_index
|
|
218
218
|
alternate_tag_index = security.alternate_tag_index
|
|
219
219
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: c2cciutils
|
|
3
|
-
Version: 1.7.0.
|
|
3
|
+
Version: 1.7.0.dev281
|
|
4
4
|
Summary: Common utilities for Camptocamp CI
|
|
5
5
|
Home-page: https://github.com/camptocamp/c2cciutils
|
|
6
6
|
License: FreeBSD
|
|
@@ -39,6 +39,7 @@ Requires-Dist: multi-repo-automation (>=1.0.0,<2.0.0) ; extra == "version"
|
|
|
39
39
|
Requires-Dist: python-magic (>=0.0.0,<1.0.0)
|
|
40
40
|
Requires-Dist: requests (>=2.0.0,<3.0.0)
|
|
41
41
|
Requires-Dist: ruamel.yaml (>=0.0.0,<1.0.0)
|
|
42
|
+
Requires-Dist: security-md (>=0.0.0,<1.0.0)
|
|
42
43
|
Requires-Dist: toml (>=0.0.0,<1.0.0)
|
|
43
44
|
Requires-Dist: tomlkit (>=0.0.0,<1.0.0) ; extra == "publish"
|
|
44
45
|
Requires-Dist: twine (>=5.0.0,<6.0.0) ; extra == "publish"
|
|
@@ -2,10 +2,10 @@ c2cciutils/__init__.py,sha256=M6hqae9Eai2yB2dD4igKHktBJ5ZRqh6Cpv18fLP9Kzo,20992
|
|
|
2
2
|
c2cciutils/applications-versions.yaml,sha256=6zZVsRCsCVvHGXPS-PgnRGGOoUBTksnhlleWDzPCj98,225
|
|
3
3
|
c2cciutils/applications.yaml,sha256=yn0XRi08cS29A_jXPofcBPxsGBv7PEBliztjRC3WtfM,504
|
|
4
4
|
c2cciutils/applications_definition.py,sha256=rOEZ3ISl5fUNDrow6H58Immy3KWJtWwGshicVDpnyNA,1321
|
|
5
|
-
c2cciutils/audit.py,sha256=
|
|
5
|
+
c2cciutils/audit.py,sha256=T2pNVumr-N5qZOsDvAP48SarNUvQP7OdAnbeZuEYwwQ,7384
|
|
6
6
|
c2cciutils/branches.graphql,sha256=UZrj1RO-H527M1SKqWm1VnkWtNsuKTnPTf4BCU2YcOU,358
|
|
7
7
|
c2cciutils/commits.graphql,sha256=3HAuIEig5V7j1L-6mqBaOkiTD3Fb8_gl1ilpZjPJf74,308
|
|
8
|
-
c2cciutils/configuration.py,sha256
|
|
8
|
+
c2cciutils/configuration.py,sha256=-jX3R2tkIy0vSNjbX_iNL3DwRAqPJgSNAJoItI2JXRM,28167
|
|
9
9
|
c2cciutils/default_branch.graphql,sha256=CaP3rRsNiyg_7RvqbMk0tOJr0aqWd8cOeSV-ZKgvKY4,131
|
|
10
10
|
c2cciutils/env.py,sha256=J-lC7GdOkdFVIrWFZEkAxHmIuTYwhDJiE30BICj2UoM,3425
|
|
11
11
|
c2cciutils/lib/docker.py,sha256=lwvCarwSSUWK1Y4O7qcTILPdpkTf2Ujhl_fCwZ6dBUY,5677
|
|
@@ -14,7 +14,7 @@ c2cciutils/package.json,sha256=eVSEaP7N8qu5EyPpkBpefKtnjlKLlfCHTfBXgbOoHDY,134
|
|
|
14
14
|
c2cciutils/pr_checks.py,sha256=tBwDHxThcu6648pE2cqpLNsaU711lwwgRc7sB4qR6fU,10109
|
|
15
15
|
c2cciutils/publish.py,sha256=KOEtPe-y1uw0-DWfKnF5jmYfQb5c0_URKBxakthcrBI,17259
|
|
16
16
|
c2cciutils/schema-applications.json,sha256=Tus-s9NB7uwKhTrQwhWQM4_oJygF_yHUqShtZhN1IxE,1551
|
|
17
|
-
c2cciutils/schema.json,sha256=
|
|
17
|
+
c2cciutils/schema.json,sha256=UjKdtlMj7gIcKhkkOPm7zRkyT4Q5eYSPjqXjm9wx6GY,23114
|
|
18
18
|
c2cciutils/scripts/__init__.py,sha256=N4tcdvUifXQrK9vEvFWrGvoyY9oZ0uRcjb-FoYe41cc,36
|
|
19
19
|
c2cciutils/scripts/audit.py,sha256=MUQqpA8CNkbSyK5e0HiSC5w-4GPKYEqFgV82lIwKkQk,1104
|
|
20
20
|
c2cciutils/scripts/clean.py,sha256=tpyipZjqK7om9_dNiLxvz6-l6le7N0L03inkrKe7Y_A,3039
|
|
@@ -28,15 +28,14 @@ c2cciutils/scripts/k8s/db.py,sha256=GK1tzzyCqrCyIJzcBdIXjyNJUXrBPFNa-9fdtwxyrlU,
|
|
|
28
28
|
c2cciutils/scripts/k8s/install.py,sha256=OIQ8KHA3Pst2pjO2E-J5FYNaBHW-i-fqCXlAUcG1tw0,933
|
|
29
29
|
c2cciutils/scripts/k8s/logs.py,sha256=-xJYu8BBUmSmMrPEwiTBKZjJBRyIlMp1depCB04_NWs,2655
|
|
30
30
|
c2cciutils/scripts/k8s/wait.py,sha256=qzQn6hbB9p1CX4bUxrkukPnbu_p6oRNem29WiMtplNk,5661
|
|
31
|
-
c2cciutils/scripts/main.py,sha256=
|
|
31
|
+
c2cciutils/scripts/main.py,sha256=ZksoYEDRJD0igEU6i0PnuOFtch4OzsxyHZQxbrjd5AY,1029
|
|
32
32
|
c2cciutils/scripts/pin_pipenv.py,sha256=jBTwlolcEL0MUyq6VYzO-adkcL1gqN7B3kBb3UjTo2k,2150
|
|
33
33
|
c2cciutils/scripts/pr_checks.py,sha256=PA9z9QB81H2JhGSr4T02eoxyeWDjQZ4XoIKFzS5o5A0,2190
|
|
34
|
-
c2cciutils/scripts/publish.py,sha256=
|
|
34
|
+
c2cciutils/scripts/publish.py,sha256=D-J-GwkJ5sxVCANSGBolcoZ7cVyU5aqwixD1T1sqaZw,19922
|
|
35
35
|
c2cciutils/scripts/trigger_image_update.py,sha256=UPCSgFcllewo1NOC7kUkJ2QMXU0dCA2QAq6LFQHr0Uw,2780
|
|
36
36
|
c2cciutils/scripts/version.py,sha256=BU6I3nG3ofgUXCLrUBNOql45Dz9Loox4gt4ebHRM3iQ,8912
|
|
37
|
-
c2cciutils/
|
|
38
|
-
c2cciutils-1.7.0.
|
|
39
|
-
c2cciutils-1.7.0.
|
|
40
|
-
c2cciutils-1.7.0.
|
|
41
|
-
c2cciutils-1.7.0.
|
|
42
|
-
c2cciutils-1.7.0.dev277.dist-info/RECORD,,
|
|
37
|
+
c2cciutils-1.7.0.dev281.dist-info/LICENSE,sha256=pK1gU5i1jYBv--vi5omcf6-86pYmAWk6ZGbdERjAgcw,1307
|
|
38
|
+
c2cciutils-1.7.0.dev281.dist-info/METADATA,sha256=oZ1f-gAY3QDGzWYUQyhCxJAuDSb-ej-fzxRTs0cAf9k,18524
|
|
39
|
+
c2cciutils-1.7.0.dev281.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
|
40
|
+
c2cciutils-1.7.0.dev281.dist-info/entry_points.txt,sha256=qB_mezKHsYy5j11RAhsEB_gPVZC2BebEvfT5Giu_D7s,1111
|
|
41
|
+
c2cciutils-1.7.0.dev281.dist-info/RECORD,,
|
|
@@ -16,7 +16,6 @@ c2cciutils-k8s-wait=c2cciutils.scripts.k8s.wait:main
|
|
|
16
16
|
c2cciutils-pin-pipenv=c2cciutils.scripts.pin_pipenv:main
|
|
17
17
|
c2cciutils-publish=c2cciutils.scripts.publish:main
|
|
18
18
|
c2cciutils-pull-request-checks=c2cciutils.scripts.pr_checks:main
|
|
19
|
-
c2cciutils-security-md=c2cciutils.scripts.security_md:main
|
|
20
19
|
c2cciutils-trigger-image-update=c2cciutils.scripts.trigger_image_update:main
|
|
21
20
|
c2cciutils-version=c2cciutils.scripts.version:main
|
|
22
21
|
|
c2cciutils/security.py
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Read the table of versions from SECURITY.md.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import xml.etree.ElementTree # nosec
|
|
6
|
-
from typing import Optional
|
|
7
|
-
|
|
8
|
-
import markdown
|
|
9
|
-
from markdown.extensions.tables import TableExtension
|
|
10
|
-
|
|
11
|
-
HEADER_VERSION = "Version"
|
|
12
|
-
HEADER_ALTERNATE_TAG = "Alternate Tag"
|
|
13
|
-
HEADER_SUPPORTED_UNTIL = "Supported Until"
|
|
14
|
-
SUPPORT_TO_BE_DEFINED = "To be defined"
|
|
15
|
-
SUPPORT_BEST_EFFORT = "Best effort"
|
|
16
|
-
SUPPORT_UNSUPPORTED = "Unsupported"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class Security:
|
|
20
|
-
"""
|
|
21
|
-
Read the table of versions from SECURITY.md.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
headers: list[str]
|
|
25
|
-
data: list[list[str]]
|
|
26
|
-
_row: Optional[list[str]] = None
|
|
27
|
-
|
|
28
|
-
def __init__(self, status: str, check: bool = True):
|
|
29
|
-
"""
|
|
30
|
-
Initialize.
|
|
31
|
-
|
|
32
|
-
Arguments:
|
|
33
|
-
status: the content of the SECURITY.md file.
|
|
34
|
-
check: Set to `False` to skip the check.
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
self.headers = []
|
|
38
|
-
self.data = []
|
|
39
|
-
|
|
40
|
-
markdown_instance = markdown.Markdown(extensions=[TableExtension()])
|
|
41
|
-
|
|
42
|
-
elem = markdown_instance.parser.parseDocument(
|
|
43
|
-
[s for s in status.split("\n") if s != "" and s[0] == "|"]
|
|
44
|
-
)
|
|
45
|
-
self._pe(elem.getroot())
|
|
46
|
-
|
|
47
|
-
self.data = [r for r in self.data if len([c for c in r if c is not None]) > 0]
|
|
48
|
-
|
|
49
|
-
self.version_index = self.headers.index(HEADER_VERSION) if HEADER_VERSION in self.headers else -1
|
|
50
|
-
self.alternate_tag_index = (
|
|
51
|
-
self.headers.index(HEADER_ALTERNATE_TAG) if HEADER_ALTERNATE_TAG in self.headers else -1
|
|
52
|
-
)
|
|
53
|
-
self.support_until_index = (
|
|
54
|
-
self.headers.index(HEADER_SUPPORTED_UNTIL) if HEADER_SUPPORTED_UNTIL in self.headers else -1
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
# Check the content if the content isn't empty
|
|
58
|
-
if check and status:
|
|
59
|
-
if not self.check(verbose=0):
|
|
60
|
-
raise ValueError("SECURITY.md file is not valid.")
|
|
61
|
-
|
|
62
|
-
def check(self, verbose: int = -1) -> bool:
|
|
63
|
-
"""
|
|
64
|
-
Check the content.
|
|
65
|
-
|
|
66
|
-
Arguments:
|
|
67
|
-
verbose: the verbosity level, `-1` for no output, `0` for errors only, `1` for all.
|
|
68
|
-
|
|
69
|
-
Return:
|
|
70
|
-
`True` if the content is valid, `False` otherwise.
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
success = True
|
|
74
|
-
if self.version_index == -1:
|
|
75
|
-
if verbose >= 0:
|
|
76
|
-
print("`Version` column not found.")
|
|
77
|
-
success = False
|
|
78
|
-
elif verbose >= 1:
|
|
79
|
-
print(f"`Version` column found at index {self.version_index}.")
|
|
80
|
-
|
|
81
|
-
if self.alternate_tag_index == -1:
|
|
82
|
-
if verbose >= 1:
|
|
83
|
-
print("Optional `Alternate Tag` column not found.")
|
|
84
|
-
elif verbose >= 1:
|
|
85
|
-
print(f"`Alternate Tag` column found at index {self.alternate_tag_index}.")
|
|
86
|
-
|
|
87
|
-
if self.support_until_index == -1:
|
|
88
|
-
if verbose >= 0:
|
|
89
|
-
print("`Supported Until` column not found.")
|
|
90
|
-
success = False
|
|
91
|
-
elif verbose >= 1:
|
|
92
|
-
print(f"`Supported Until` column found at index {self.support_until_index}.")
|
|
93
|
-
|
|
94
|
-
return success
|
|
95
|
-
|
|
96
|
-
def _pe(self, elem: xml.etree.ElementTree.Element) -> None:
|
|
97
|
-
"""
|
|
98
|
-
Parse the HTML table.
|
|
99
|
-
|
|
100
|
-
Arguments:
|
|
101
|
-
elem: The XML element
|
|
102
|
-
"""
|
|
103
|
-
if elem.tag == "th":
|
|
104
|
-
assert elem.text is not None
|
|
105
|
-
self.headers.append(elem.text)
|
|
106
|
-
if elem.tag == "tr":
|
|
107
|
-
self._row = []
|
|
108
|
-
self.data.append(self._row)
|
|
109
|
-
if elem.tag == "td":
|
|
110
|
-
self._row.append(elem.text) # type: ignore
|
|
111
|
-
for element in list(elem):
|
|
112
|
-
self._pe(element)
|
|
File without changes
|
|
File without changes
|