micropython-stubber 1.23.3__py3-none-any.whl → 1.24.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 (69) hide show
  1. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/METADATA +29 -11
  2. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/RECORD +68 -65
  3. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/WHEEL +1 -1
  4. mpflash/README.md +2 -2
  5. mpflash/mpflash/basicgit.py +22 -2
  6. mpflash/mpflash/common.py +23 -13
  7. mpflash/mpflash/downloaded.py +10 -2
  8. mpflash/mpflash/flash/esp.py +1 -1
  9. mpflash/mpflash/mpboard_id/__init__.py +9 -4
  10. mpflash/mpflash/mpboard_id/add_boards.py +25 -14
  11. mpflash/mpflash/mpboard_id/board.py +2 -2
  12. mpflash/mpflash/mpboard_id/board_id.py +10 -6
  13. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  14. mpflash/mpflash/mpremoteboard/__init__.py +13 -8
  15. mpflash/mpflash/vendor/board_database.py +185 -0
  16. mpflash/mpflash/vendor/readme.md +10 -1
  17. mpflash/mpflash/versions.py +28 -40
  18. mpflash/poetry.lock +1147 -231
  19. mpflash/pyproject.toml +4 -3
  20. stubber/__init__.py +1 -1
  21. stubber/board/createstubs.py +76 -34
  22. stubber/board/createstubs_db.py +34 -25
  23. stubber/board/createstubs_db_min.py +90 -83
  24. stubber/board/createstubs_db_mpy.mpy +0 -0
  25. stubber/board/createstubs_mem.py +34 -25
  26. stubber/board/createstubs_mem_min.py +123 -116
  27. stubber/board/createstubs_mem_mpy.mpy +0 -0
  28. stubber/board/createstubs_min.py +154 -145
  29. stubber/board/createstubs_mpy.mpy +0 -0
  30. stubber/board/modulelist.txt +16 -0
  31. stubber/codemod/enrich.py +301 -86
  32. stubber/codemod/merge_docstub.py +251 -66
  33. stubber/codemod/test_enrich.py +87 -0
  34. stubber/codemod/visitors/type_helpers.py +182 -0
  35. stubber/commands/build_cmd.py +16 -3
  36. stubber/commands/clone_cmd.py +3 -3
  37. stubber/commands/config_cmd.py +4 -2
  38. stubber/commands/enrich_folder_cmd.py +33 -21
  39. stubber/commands/get_core_cmd.py +1 -2
  40. stubber/commands/get_docstubs_cmd.py +60 -6
  41. stubber/commands/get_frozen_cmd.py +15 -12
  42. stubber/commands/get_mcu_cmd.py +3 -3
  43. stubber/commands/merge_cmd.py +1 -2
  44. stubber/commands/publish_cmd.py +19 -4
  45. stubber/commands/stub_cmd.py +3 -3
  46. stubber/commands/switch_cmd.py +3 -5
  47. stubber/commands/variants_cmd.py +3 -3
  48. stubber/cst_transformer.py +52 -17
  49. stubber/freeze/common.py +27 -11
  50. stubber/freeze/freeze_manifest_2.py +8 -1
  51. stubber/freeze/get_frozen.py +4 -1
  52. stubber/merge_config.py +111 -0
  53. stubber/minify.py +1 -2
  54. stubber/publish/database.py +51 -10
  55. stubber/publish/merge_docstubs.py +38 -17
  56. stubber/publish/package.py +32 -18
  57. stubber/publish/publish.py +8 -8
  58. stubber/publish/stubpackage.py +117 -50
  59. stubber/rst/lookup.py +205 -41
  60. stubber/rst/reader.py +106 -59
  61. stubber/rst/rst_utils.py +24 -11
  62. stubber/stubber.py +1 -1
  63. stubber/stubs_from_docs.py +31 -13
  64. stubber/update_module_list.py +2 -2
  65. stubber/utils/config.py +33 -13
  66. stubber/utils/post.py +9 -6
  67. stubber/publish/missing_class_methods.py +0 -51
  68. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/LICENSE +0 -0
  69. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/entry_points.txt +0 -0
@@ -7,8 +7,8 @@ prepare a set of stub files for publishing to PyPi
7
7
  from typing import Any, Dict, List, Optional, Union
8
8
 
9
9
  from mpflash.logger import log
10
-
11
10
  from mpflash.versions import V_PREVIEW
11
+
12
12
  from stubber.publish.candidates import board_candidates, filter_list
13
13
  from stubber.publish.database import get_database
14
14
  from stubber.publish.defaults import GENERIC_U
@@ -33,7 +33,7 @@ def build_multiple(
33
33
  ports = ports or ["all"]
34
34
  boards = boards or [GENERIC_U]
35
35
 
36
- db = get_database(CONFIG.publish_path, production=production)
36
+ db_conn = get_database(CONFIG.publish_path, production=production)
37
37
  results: List[Dict[str, Any]] = []
38
38
  worklist = build_worklist(family, versions, ports, boards)
39
39
  if len(worklist) == 0:
@@ -42,7 +42,7 @@ def build_multiple(
42
42
  log.info(f"checking {len(worklist)} possible board candidates")
43
43
 
44
44
  for todo in worklist:
45
- if package := get_package(db, **todo):
45
+ if package := get_package(db_conn, **todo):
46
46
  package.build_distribution(force=force, production=production)
47
47
  results.append(package.status)
48
48
  else:
@@ -69,18 +69,18 @@ def publish_multiple(
69
69
  ports = ports or ["all"]
70
70
  boards = boards or [GENERIC_U]
71
71
 
72
- db = get_database(CONFIG.publish_path, production=production)
72
+ db_conn = get_database(CONFIG.publish_path, production=production)
73
73
  results = []
74
74
  worklist = build_worklist(family, versions, ports, boards)
75
75
 
76
76
  if len(worklist) == 0:
77
- log.error("Could not find any packages than can be published.")
77
+ log.error("Could not find any packages that can be published.")
78
78
  return results
79
79
 
80
80
  for todo in worklist:
81
- if package := get_package(db, **todo):
81
+ if package := get_package(db_conn, **todo):
82
82
  package.publish_distribution_ifchanged(
83
- db=db,
83
+ db_conn=db_conn,
84
84
  clean=clean,
85
85
  force=force,
86
86
  build=build,
@@ -113,7 +113,7 @@ def build_worklist(
113
113
  worklist = filter_list(worklist, ports, boards)
114
114
 
115
115
  for b in boards:
116
- if b == "auto":
116
+ if b in ["auto", "all", "*"]:
117
117
  continue
118
118
  if not any(i for i in worklist if i["board"].lower() == b.lower()):
119
119
  log.warning(f"Could not find any package candidate for board {b}")
@@ -3,29 +3,29 @@
3
3
  import hashlib
4
4
  import json
5
5
  import shutil
6
+ import sqlite3
6
7
  import subprocess
7
- from pathlib import Path
8
8
  import sys
9
+ from pathlib import Path
9
10
  from typing import Any, Dict, List, Optional, Tuple, Union
10
11
 
11
12
  import tenacity
12
-
13
13
  from mpflash.basicgit import get_git_describe
14
+
14
15
  from stubber.publish.helpers import get_module_docstring
15
16
 
16
17
  if sys.version_info >= (3, 11):
17
- import tomllib # type: ignore
18
+ import tomllib # type: ignore
18
19
  else:
19
- import tomli as tomllib # type: ignore
20
+ import tomli as tomllib # type: ignore
20
21
 
21
22
  from typing import NewType
22
23
 
23
24
  import tomli_w
24
25
  from mpflash.logger import log
26
+ from mpflash.versions import SET_PREVIEW, V_PREVIEW, clean_version
25
27
  from packaging.version import Version, parse
26
- from pysondb import PysonDB
27
28
 
28
- from mpflash.versions import SET_PREVIEW, V_PREVIEW, clean_version
29
29
  from stubber.publish.bump import bump_version
30
30
  from stubber.publish.defaults import GENERIC_U, default_board
31
31
  from stubber.publish.enums import StubSource
@@ -53,7 +53,7 @@ STUBS_COPY_FILTER = {
53
53
  STDLIB_UMODULES = ["ucollections"]
54
54
 
55
55
 
56
- class VersionedPackage(object):
56
+ class VersionedPackage:
57
57
  """
58
58
  Represents a versioned package.
59
59
 
@@ -82,6 +82,7 @@ class VersionedPackage(object):
82
82
  return f"{self.package_name}=={self.mpy_version}"
83
83
 
84
84
  def __repr__(self) -> str:
85
+ # todo: use pkg_version to allow for comparing different versions of the same package
85
86
  return f"{self.package_name}=={self.mpy_version}"
86
87
 
87
88
  def __eq__(self, o: object) -> bool:
@@ -215,6 +216,7 @@ class Builder(VersionedPackage):
215
216
  mpy_version: str = "0.0.1",
216
217
  port: str,
217
218
  board: str = GENERIC_U,
219
+ variant: Optional[str] = None,
218
220
  description: str = "MicroPython stubs",
219
221
  stubs: Optional[StubSources] = None,
220
222
  # json_data: Optional[Dict[str, Any]] = None,
@@ -225,6 +227,7 @@ class Builder(VersionedPackage):
225
227
  self.mpy_version = mpy_version
226
228
  self.port = port
227
229
  self.board = board
230
+ self.variant = variant or ""
228
231
  self.description = description
229
232
  self.stub_sources = stubs or []
230
233
  self.hash = None # intial hash
@@ -252,8 +255,12 @@ class Builder(VersionedPackage):
252
255
  pyproject = None
253
256
  _toml = self.toml_path
254
257
  if (_toml).exists():
255
- with open(_toml, "rb") as f:
256
- pyproject = tomllib.load(f)
258
+ log.debug(f"Load pyproject from {_toml}")
259
+ try:
260
+ with open(_toml, "rb") as f:
261
+ pyproject = tomllib.load(f)
262
+ except tomllib.TOMLDecodeError as e:
263
+ log.error(f"Could not load pyproject.toml file {e}")
257
264
  return pyproject
258
265
 
259
266
  @pyproject.setter
@@ -340,7 +347,7 @@ class Builder(VersionedPackage):
340
347
  def update_umodules(self):
341
348
  """
342
349
  Replace the STDLIB umodules with a simple import statement
343
- in order to allow the typecheckers to resove the stdlib modules in the usual stdlib location.
350
+ in order to allow the typecheckers to resovle the stdlib modules in the usual stdlib location.
344
351
  """
345
352
  for f in self.package_path.rglob("*.pyi"):
346
353
  if f.stem in STDLIB_UMODULES:
@@ -386,10 +393,12 @@ class Builder(VersionedPackage):
386
393
  json.dump(self.to_dict(), f, indent=4)
387
394
 
388
395
  def to_dict(self) -> dict:
389
- """return the package as a dict to store in the jsondb
396
+ """return the package as a Dict[str,str] to store in the db
390
397
 
391
398
  need to simplify some of the Objects to allow serialization to json
392
- - the paths to posix paths
399
+ - stub_sources
400
+ List[Tuple[StubSource, Path]] -> List[List[str, str]] # convert
401
+ the paths to posix paths
393
402
  - the version (semver) to a string
394
403
  - toml file to list of lines
395
404
 
@@ -400,14 +409,19 @@ class Builder(VersionedPackage):
400
409
  "publish": self._publish,
401
410
  "pkg_version": str(self.pkg_version),
402
411
  "path": self.package_path.name, # only store the folder name , as it is relative to the publish folder
403
- "stub_sources": [(name, Path(path).as_posix()) for (name, path) in self.stub_sources],
412
+ "stub_sources": json.dumps(
413
+ [(name, Path(path).as_posix()) for (name, path) in self.stub_sources]
414
+ ),
404
415
  "description": self.description,
405
416
  "hash": self.hash,
406
417
  "stub_hash": self.stub_hash,
418
+ "port": self.port,
419
+ "board": self.board,
420
+ "variant": "", # TODO: get the variant
407
421
  }
408
422
 
409
423
  def from_dict(self, json_data: Dict) -> None:
410
- """load the package from a dict (from the jsondb)"""
424
+ """load the package from a dict (from the db)"""
411
425
  self.package_name = json_data["name"]
412
426
  # self.package_path = Path(json_data["path"])
413
427
  self.description = json_data["description"]
@@ -415,6 +429,10 @@ class Builder(VersionedPackage):
415
429
  self._publish = json_data["publish"]
416
430
  self.hash = json_data["hash"]
417
431
  self.stub_hash = json_data["stub_hash"]
432
+ self.port = json_data["port"]
433
+ self.board = json_data["board"]
434
+ self.variant = json_data["variant"]
435
+
418
436
  # create folder
419
437
  if not self.package_path.exists():
420
438
  self.package_path.mkdir(parents=True, exist_ok=True)
@@ -423,7 +441,7 @@ class Builder(VersionedPackage):
423
441
  # set pkg version after creating the toml file
424
442
  self.pkg_version = json_data["pkg_version"]
425
443
  self.stub_sources = []
426
- for name, path in json_data["stub_sources"]:
444
+ for name, path in json.loads(json_data["stub_sources"]):
427
445
  if path.startswith("stubs/"):
428
446
  path = path.replace("stubs/", "")
429
447
  self.stub_sources.append((name, Path(path)))
@@ -529,13 +547,13 @@ class Builder(VersionedPackage):
529
547
  with open(self.package_path / "README.md", "w") as f:
530
548
  f.write(f"# {self.package_name}\n\n")
531
549
  f.write(TEMPLATE_README)
532
- f.write(f"Included stubs:\n")
550
+ f.write("Included stubs:\n")
533
551
  for name, folder in self.stub_sources:
534
552
  f.write(f"* {name} from `stubs/{Path(folder).as_posix()}`\n")
535
553
 
536
- f.write(f"\n\n")
537
- f.write(f"origin | Family | Port | Board | Version\n")
538
- f.write(f"-------|--------|------|-------|--------\n")
554
+ f.write("\n\n")
555
+ f.write("origin | Family | Port | Board | Version\n")
556
+ f.write("-------|--------|------|-------|--------\n")
539
557
  try:
540
558
  f.write(
541
559
  f"Firmware | {firmware_stubs['firmware']['family']} | {firmware_stubs['firmware']['port']} | {firmware_stubs['firmware']['machine']} | {clean_version(firmware_stubs['firmware']['version'])} \n"
@@ -592,7 +610,14 @@ class PoetryBuilder(Builder):
592
610
  return self.mpy_version
593
611
  with open(_toml, "rb") as f:
594
612
  pyproject = tomllib.load(f)
595
- ver = pyproject["tool"]["poetry"]["version"]
613
+ # read the version new pyproject format / old format / self.mpy_version
614
+ try:
615
+ ver = pyproject["project"]["version"]
616
+ except KeyError:
617
+ try:
618
+ ver = pyproject["tool"]["poetry"]["version"]
619
+ except KeyError:
620
+ ver = self.mpy_version
596
621
  return str(parse(ver)) if ver not in SET_PREVIEW else ver
597
622
 
598
623
  @pkg_version.setter
@@ -606,7 +631,8 @@ class PoetryBuilder(Builder):
606
631
  try:
607
632
  with open(_toml, "rb") as f:
608
633
  pyproject = tomllib.load(f)
609
- pyproject["tool"]["poetry"]["version"] = version
634
+ # pyproject["tool"]["poetry"]["version"] = version
635
+ pyproject["project"]["version"] = version
610
636
  # update the version in the toml file
611
637
  with open(_toml, "wb") as output:
612
638
  tomli_w.dump(pyproject, output)
@@ -694,7 +720,14 @@ class PoetryBuilder(Builder):
694
720
  # update the dependencies section by reading these from the template file
695
721
  with open(CONFIG.template_path / "pyproject.toml", "rb") as f:
696
722
  tpl = tomllib.load(f)
697
- _pyproject["tool"]["poetry"]["dependencies"] = tpl["tool"]["poetry"]["dependencies"]
723
+
724
+ # copy new / poetry style dependencies
725
+ for section in ["dependencies"]:
726
+ for key in ["tool.poetry", "project"]:
727
+ try:
728
+ _pyproject[key][section] = tpl[key][section]
729
+ except KeyError:
730
+ pass
698
731
 
699
732
  else:
700
733
  # read the template pyproject.toml file from the template folder
@@ -702,14 +735,17 @@ class PoetryBuilder(Builder):
702
735
  with open(CONFIG.template_path / "pyproject.toml", "rb") as f:
703
736
  _pyproject = tomllib.load(f)
704
737
  # note: can be 'latest' which is not semver
705
- _pyproject["tool"]["poetry"]["version"] = self.mpy_version
738
+ # _pyproject["tool"]["poetry"]["version"] = self.mpy_version
739
+ _pyproject["project"]["version"] = self.mpy_version
706
740
  except FileNotFoundError as e:
707
741
  log.error(f"Could not find template pyproject.toml file {e}")
708
742
  raise (e)
709
743
 
710
744
  # update the name , version and description of the package
711
- _pyproject["tool"]["poetry"]["name"] = self.package_name
712
- _pyproject["tool"]["poetry"]["description"] = self.description
745
+ # _pyproject["tool"]["poetry"]["name"] = self.package_name
746
+ # _pyproject["tool"]["poetry"]["description"] = self.description
747
+ _pyproject["project"]["name"] = self.package_name
748
+ _pyproject["project"]["description"] = self.description
713
749
  # write out the pyproject.toml file
714
750
  self.pyproject = _pyproject
715
751
 
@@ -779,6 +815,14 @@ class StubPackage(PoetryBuilder):
779
815
  STUB_PATH - root-relative path to the folder where the stubs are stored ('./stubs').
780
816
 
781
817
  """
818
+ super().__init__(
819
+ package_name=package_name,
820
+ mpy_version=clean_version(version, drop_v=True), # Initial version
821
+ port=port,
822
+ board=board,
823
+ description=description,
824
+ stubs=stubs or [],
825
+ )
782
826
  self.port = port
783
827
  self.board = board
784
828
  if json_data is not None:
@@ -787,14 +831,14 @@ class StubPackage(PoetryBuilder):
787
831
  # store essentials
788
832
  self.package_name = package_name
789
833
  self.description = description
790
- self.mpy_version = clean_version(version, drop_v=True) # Initial version
834
+ # self.mpy_version = clean_version(version, drop_v=True) # Initial version
791
835
 
792
836
  self.create_update_pyproject_toml()
793
837
 
794
- self.stub_sources: StubSources = []
795
- # save the stub sources
796
- if stubs:
797
- self.stub_sources = stubs
838
+ # self.stub_sources: StubSources = []
839
+ # # save the stub sources
840
+ # if stubs:
841
+ # self.stub_sources = stubs
798
842
 
799
843
  self.status: Status = Status(
800
844
  {
@@ -805,14 +849,6 @@ class StubPackage(PoetryBuilder):
805
849
  "path": self.package_path.as_posix(),
806
850
  }
807
851
  )
808
- super().__init__(
809
- package_name=package_name,
810
- mpy_version=self.mpy_version,
811
- port=port,
812
- board=board,
813
- description=description,
814
- stubs=self.stub_sources,
815
- )
816
852
 
817
853
  def update_sources(self) -> StubSources:
818
854
  """
@@ -838,8 +874,9 @@ class StubPackage(PoetryBuilder):
838
874
  # use if folder exists , else use GENERIC folder
839
875
  if (CONFIG.stub_path / fw_path).exists():
840
876
  updated_sources.append((stub_type, fw_path))
841
- elif fw_path.with_name("GENERIC").exists():
877
+ elif (CONFIG.stub_path / fw_path).with_name("GENERIC").exists():
842
878
  updated_sources.append((stub_type, fw_path.with_name("GENERIC")))
879
+
843
880
  elif stub_type == StubSource.MERGED:
844
881
  # Use the default board folder instead of the GENERIC board folder (if it exists)
845
882
  if self.board.upper() == GENERIC_U:
@@ -857,7 +894,7 @@ class StubPackage(PoetryBuilder):
857
894
 
858
895
  def update_distribution(self, production: bool) -> bool:
859
896
  """Update the package .pyi files, if all the sources are available"""
860
- log.info(f"- Update {self.package_path.name}")
897
+ log.debug(f"- Update {self.package_path.name}")
861
898
  log.trace(f"{self.package_path.as_posix()}")
862
899
 
863
900
  # check if the sources exist
@@ -866,7 +903,7 @@ class StubPackage(PoetryBuilder):
866
903
  log.debug(
867
904
  f"{self.package_name}: skipping as one or more source stub folders are missing"
868
905
  )
869
- self.status["error"] = "Skipped, stub folder(s) missing"
906
+ self.status["error"] = "Skipped, No stubs found."
870
907
  shutil.rmtree(self.package_path.as_posix())
871
908
  self._publish = False # type: ignore
872
909
  return False
@@ -900,15 +937,15 @@ class StubPackage(PoetryBuilder):
900
937
  :param force: BUILD even if no changes
901
938
  :return: True if the package was built
902
939
  """
903
- log.info(f"Build: {self.package_path.name}")
904
940
 
905
941
  ok = self.update_distribution(production)
906
942
  self.status["version"] = self.pkg_version
907
943
  if not ok:
908
- log.info(f"{self.package_name}: skip - Could not build/update package")
944
+ log.debug(f"{self.package_name}: skip - Could not build/update package")
909
945
  if not self.status["error"]:
910
946
  self.status["error"] = "Could not build/update package"
911
947
  return False
948
+ log.info(f"Build: {self.package_path.name}")
912
949
 
913
950
  # If there are changes to the package, then publish it
914
951
  if self.is_changed() or force:
@@ -939,7 +976,7 @@ class StubPackage(PoetryBuilder):
939
976
 
940
977
  def publish_distribution_ifchanged(
941
978
  self,
942
- db: PysonDB,
979
+ db_conn: sqlite3.Connection,
943
980
  *,
944
981
  production: bool, # PyPI or Test-PyPi
945
982
  build=False, #
@@ -984,9 +1021,9 @@ class StubPackage(PoetryBuilder):
984
1021
  )
985
1022
  self.status["result"] = "Published to GitHub"
986
1023
  else:
987
- return self.publish_distribution(dry_run, production, db)
1024
+ return self.publish_distribution(dry_run, production, db_conn)
988
1025
  elif force:
989
- return self.publish_distribution(dry_run, production, db)
1026
+ return self.publish_distribution(dry_run, production, db_conn)
990
1027
  else:
991
1028
  log.info(f"No changes to package : {self.package_name} {self.pkg_version}")
992
1029
 
@@ -994,7 +1031,12 @@ class StubPackage(PoetryBuilder):
994
1031
  self.clean()
995
1032
  return True
996
1033
 
997
- def publish_distribution(self, dry_run, production, db):
1034
+ def publish_distribution(
1035
+ self,
1036
+ dry_run: bool,
1037
+ production: bool,
1038
+ db_conn: sqlite3.Connection,
1039
+ ) -> bool:
998
1040
  """
999
1041
  Publishes the package to PyPi or Test-PyPi.
1000
1042
 
@@ -1023,9 +1065,34 @@ class StubPackage(PoetryBuilder):
1023
1065
  if dry_run:
1024
1066
  log.warning(f"{self.package_name}: Dry run, not saving to database")
1025
1067
  else:
1026
- # get the package state and add it to the database
1027
- db.add(self.to_dict())
1028
- db.commit()
1068
+ cursor = db_conn.cursor()
1069
+
1070
+ d = self.to_dict()
1071
+
1072
+ cursor.execute(
1073
+ """
1074
+ INSERT INTO packages (name, description, mpy_version, pkg_version, publish, stub_sources, path, hash, stub_hash, port, board, variant)
1075
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1076
+ """,
1077
+ (
1078
+ d["name"],
1079
+ d["description"],
1080
+ d["mpy_version"],
1081
+ d["pkg_version"],
1082
+ d["publish"],
1083
+ d["stub_sources"],
1084
+ d["path"],
1085
+ d["hash"],
1086
+ d["stub_hash"],
1087
+ d["port"],
1088
+ d["board"],
1089
+ d["variant"],
1090
+ ),
1091
+ )
1092
+
1093
+ # # get the package state and add it to the database
1094
+ # db_conn.add(self.to_dict())
1095
+ db_conn.commit()
1029
1096
  return True
1030
1097
 
1031
1098
  def are_package_sources_available(self) -> bool: