micropython-stubber 1.23.2__py3-none-any.whl → 1.24.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.
Files changed (70) hide show
  1. {micropython_stubber-1.23.2.dist-info → micropython_stubber-1.24.0.dist-info}/METADATA +30 -12
  2. {micropython_stubber-1.23.2.dist-info → micropython_stubber-1.24.0.dist-info}/RECORD +69 -66
  3. {micropython_stubber-1.23.2.dist-info → micropython_stubber-1.24.0.dist-info}/WHEEL +1 -1
  4. mpflash/README.md +2 -2
  5. mpflash/mpflash/basicgit.py +49 -9
  6. mpflash/mpflash/common.py +23 -16
  7. mpflash/mpflash/downloaded.py +10 -2
  8. mpflash/mpflash/mpboard_id/__init__.py +9 -4
  9. mpflash/mpflash/mpboard_id/add_boards.py +25 -14
  10. mpflash/mpflash/mpboard_id/board.py +2 -2
  11. mpflash/mpflash/mpboard_id/board_id.py +10 -6
  12. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  13. mpflash/mpflash/mpboard_id/store.py +8 -3
  14. mpflash/mpflash/mpremoteboard/__init__.py +13 -8
  15. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +27 -16
  16. mpflash/mpflash/vendor/board_database.py +185 -0
  17. mpflash/mpflash/vendor/readme.md +10 -1
  18. mpflash/mpflash/versions.py +28 -40
  19. mpflash/poetry.lock +1605 -601
  20. mpflash/pyproject.toml +4 -3
  21. stubber/__init__.py +1 -1
  22. stubber/board/createstubs.py +51 -27
  23. stubber/board/createstubs_db.py +36 -28
  24. stubber/board/createstubs_db_min.py +171 -165
  25. stubber/board/createstubs_db_mpy.mpy +0 -0
  26. stubber/board/createstubs_mem.py +36 -28
  27. stubber/board/createstubs_mem_min.py +184 -178
  28. stubber/board/createstubs_mem_mpy.mpy +0 -0
  29. stubber/board/createstubs_min.py +102 -94
  30. stubber/board/createstubs_mpy.mpy +0 -0
  31. stubber/board/modulelist.txt +16 -0
  32. stubber/codemod/enrich.py +297 -88
  33. stubber/codemod/merge_docstub.py +250 -65
  34. stubber/codemod/test_enrich.py +87 -0
  35. stubber/codemod/visitors/typevars.py +200 -0
  36. stubber/commands/build_cmd.py +16 -3
  37. stubber/commands/clone_cmd.py +3 -3
  38. stubber/commands/config_cmd.py +4 -2
  39. stubber/commands/enrich_folder_cmd.py +33 -21
  40. stubber/commands/get_core_cmd.py +1 -2
  41. stubber/commands/get_docstubs_cmd.py +60 -6
  42. stubber/commands/get_frozen_cmd.py +15 -12
  43. stubber/commands/get_mcu_cmd.py +3 -3
  44. stubber/commands/merge_cmd.py +1 -2
  45. stubber/commands/publish_cmd.py +19 -4
  46. stubber/commands/stub_cmd.py +3 -3
  47. stubber/commands/switch_cmd.py +3 -5
  48. stubber/commands/variants_cmd.py +3 -3
  49. stubber/cst_transformer.py +52 -17
  50. stubber/freeze/common.py +27 -11
  51. stubber/freeze/freeze_manifest_2.py +8 -1
  52. stubber/freeze/get_frozen.py +4 -1
  53. stubber/merge_config.py +111 -0
  54. stubber/minify.py +1 -2
  55. stubber/publish/database.py +51 -10
  56. stubber/publish/merge_docstubs.py +33 -16
  57. stubber/publish/package.py +32 -18
  58. stubber/publish/publish.py +8 -8
  59. stubber/publish/stubpackage.py +110 -47
  60. stubber/rst/lookup.py +205 -43
  61. stubber/rst/reader.py +106 -59
  62. stubber/rst/rst_utils.py +24 -11
  63. stubber/stubber.py +1 -1
  64. stubber/stubs_from_docs.py +31 -13
  65. stubber/update_module_list.py +2 -2
  66. stubber/utils/config.py +33 -13
  67. stubber/utils/post.py +9 -6
  68. stubber/publish/missing_class_methods.py +0 -51
  69. {micropython_stubber-1.23.2.dist-info → micropython_stubber-1.24.0.dist-info}/LICENSE +0 -0
  70. {micropython_stubber-1.23.2.dist-info → micropython_stubber-1.24.0.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,14 +3,15 @@
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):
@@ -22,10 +23,9 @@ 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,7 +255,7 @@ class Builder(VersionedPackage):
252
255
  pyproject = None
253
256
  _toml = self.toml_path
254
257
  if (_toml).exists():
255
- log.info(f"Load pyproject from {_toml}")
258
+ log.debug(f"Load pyproject from {_toml}")
256
259
  try:
257
260
  with open(_toml, "rb") as f:
258
261
  pyproject = tomllib.load(f)
@@ -344,7 +347,7 @@ class Builder(VersionedPackage):
344
347
  def update_umodules(self):
345
348
  """
346
349
  Replace the STDLIB umodules with a simple import statement
347
- 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.
348
351
  """
349
352
  for f in self.package_path.rglob("*.pyi"):
350
353
  if f.stem in STDLIB_UMODULES:
@@ -390,10 +393,12 @@ class Builder(VersionedPackage):
390
393
  json.dump(self.to_dict(), f, indent=4)
391
394
 
392
395
  def to_dict(self) -> dict:
393
- """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
394
397
 
395
398
  need to simplify some of the Objects to allow serialization to json
396
- - the paths to posix paths
399
+ - stub_sources
400
+ List[Tuple[StubSource, Path]] -> List[List[str, str]] # convert
401
+ the paths to posix paths
397
402
  - the version (semver) to a string
398
403
  - toml file to list of lines
399
404
 
@@ -404,14 +409,19 @@ class Builder(VersionedPackage):
404
409
  "publish": self._publish,
405
410
  "pkg_version": str(self.pkg_version),
406
411
  "path": self.package_path.name, # only store the folder name , as it is relative to the publish folder
407
- "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
+ ),
408
415
  "description": self.description,
409
416
  "hash": self.hash,
410
417
  "stub_hash": self.stub_hash,
418
+ "port": self.port,
419
+ "board": self.board,
420
+ "variant": "", # TODO: get the variant
411
421
  }
412
422
 
413
423
  def from_dict(self, json_data: Dict) -> None:
414
- """load the package from a dict (from the jsondb)"""
424
+ """load the package from a dict (from the db)"""
415
425
  self.package_name = json_data["name"]
416
426
  # self.package_path = Path(json_data["path"])
417
427
  self.description = json_data["description"]
@@ -419,6 +429,10 @@ class Builder(VersionedPackage):
419
429
  self._publish = json_data["publish"]
420
430
  self.hash = json_data["hash"]
421
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
+
422
436
  # create folder
423
437
  if not self.package_path.exists():
424
438
  self.package_path.mkdir(parents=True, exist_ok=True)
@@ -427,7 +441,7 @@ class Builder(VersionedPackage):
427
441
  # set pkg version after creating the toml file
428
442
  self.pkg_version = json_data["pkg_version"]
429
443
  self.stub_sources = []
430
- for name, path in json_data["stub_sources"]:
444
+ for name, path in json.loads(json_data["stub_sources"]):
431
445
  if path.startswith("stubs/"):
432
446
  path = path.replace("stubs/", "")
433
447
  self.stub_sources.append((name, Path(path)))
@@ -533,13 +547,13 @@ class Builder(VersionedPackage):
533
547
  with open(self.package_path / "README.md", "w") as f:
534
548
  f.write(f"# {self.package_name}\n\n")
535
549
  f.write(TEMPLATE_README)
536
- f.write(f"Included stubs:\n")
550
+ f.write("Included stubs:\n")
537
551
  for name, folder in self.stub_sources:
538
552
  f.write(f"* {name} from `stubs/{Path(folder).as_posix()}`\n")
539
553
 
540
- f.write(f"\n\n")
541
- f.write(f"origin | Family | Port | Board | Version\n")
542
- f.write(f"-------|--------|------|-------|--------\n")
554
+ f.write("\n\n")
555
+ f.write("origin | Family | Port | Board | Version\n")
556
+ f.write("-------|--------|------|-------|--------\n")
543
557
  try:
544
558
  f.write(
545
559
  f"Firmware | {firmware_stubs['firmware']['family']} | {firmware_stubs['firmware']['port']} | {firmware_stubs['firmware']['machine']} | {clean_version(firmware_stubs['firmware']['version'])} \n"
@@ -596,7 +610,14 @@ class PoetryBuilder(Builder):
596
610
  return self.mpy_version
597
611
  with open(_toml, "rb") as f:
598
612
  pyproject = tomllib.load(f)
599
- 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
600
621
  return str(parse(ver)) if ver not in SET_PREVIEW else ver
601
622
 
602
623
  @pkg_version.setter
@@ -610,7 +631,8 @@ class PoetryBuilder(Builder):
610
631
  try:
611
632
  with open(_toml, "rb") as f:
612
633
  pyproject = tomllib.load(f)
613
- pyproject["tool"]["poetry"]["version"] = version
634
+ # pyproject["tool"]["poetry"]["version"] = version
635
+ pyproject["project"]["version"] = version
614
636
  # update the version in the toml file
615
637
  with open(_toml, "wb") as output:
616
638
  tomli_w.dump(pyproject, output)
@@ -698,7 +720,14 @@ class PoetryBuilder(Builder):
698
720
  # update the dependencies section by reading these from the template file
699
721
  with open(CONFIG.template_path / "pyproject.toml", "rb") as f:
700
722
  tpl = tomllib.load(f)
701
- _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
702
731
 
703
732
  else:
704
733
  # read the template pyproject.toml file from the template folder
@@ -706,14 +735,17 @@ class PoetryBuilder(Builder):
706
735
  with open(CONFIG.template_path / "pyproject.toml", "rb") as f:
707
736
  _pyproject = tomllib.load(f)
708
737
  # note: can be 'latest' which is not semver
709
- _pyproject["tool"]["poetry"]["version"] = self.mpy_version
738
+ # _pyproject["tool"]["poetry"]["version"] = self.mpy_version
739
+ _pyproject["project"]["version"] = self.mpy_version
710
740
  except FileNotFoundError as e:
711
741
  log.error(f"Could not find template pyproject.toml file {e}")
712
742
  raise (e)
713
743
 
714
744
  # update the name , version and description of the package
715
- _pyproject["tool"]["poetry"]["name"] = self.package_name
716
- _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
717
749
  # write out the pyproject.toml file
718
750
  self.pyproject = _pyproject
719
751
 
@@ -783,6 +815,14 @@ class StubPackage(PoetryBuilder):
783
815
  STUB_PATH - root-relative path to the folder where the stubs are stored ('./stubs').
784
816
 
785
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
+ )
786
826
  self.port = port
787
827
  self.board = board
788
828
  if json_data is not None:
@@ -791,14 +831,14 @@ class StubPackage(PoetryBuilder):
791
831
  # store essentials
792
832
  self.package_name = package_name
793
833
  self.description = description
794
- self.mpy_version = clean_version(version, drop_v=True) # Initial version
834
+ # self.mpy_version = clean_version(version, drop_v=True) # Initial version
795
835
 
796
836
  self.create_update_pyproject_toml()
797
837
 
798
- self.stub_sources: StubSources = []
799
- # save the stub sources
800
- if stubs:
801
- self.stub_sources = stubs
838
+ # self.stub_sources: StubSources = []
839
+ # # save the stub sources
840
+ # if stubs:
841
+ # self.stub_sources = stubs
802
842
 
803
843
  self.status: Status = Status(
804
844
  {
@@ -809,14 +849,6 @@ class StubPackage(PoetryBuilder):
809
849
  "path": self.package_path.as_posix(),
810
850
  }
811
851
  )
812
- super().__init__(
813
- package_name=package_name,
814
- mpy_version=self.mpy_version,
815
- port=port,
816
- board=board,
817
- description=description,
818
- stubs=self.stub_sources,
819
- )
820
852
 
821
853
  def update_sources(self) -> StubSources:
822
854
  """
@@ -842,8 +874,9 @@ class StubPackage(PoetryBuilder):
842
874
  # use if folder exists , else use GENERIC folder
843
875
  if (CONFIG.stub_path / fw_path).exists():
844
876
  updated_sources.append((stub_type, fw_path))
845
- elif fw_path.with_name("GENERIC").exists():
877
+ elif (CONFIG.stub_path / fw_path).with_name("GENERIC").exists():
846
878
  updated_sources.append((stub_type, fw_path.with_name("GENERIC")))
879
+
847
880
  elif stub_type == StubSource.MERGED:
848
881
  # Use the default board folder instead of the GENERIC board folder (if it exists)
849
882
  if self.board.upper() == GENERIC_U:
@@ -861,7 +894,7 @@ class StubPackage(PoetryBuilder):
861
894
 
862
895
  def update_distribution(self, production: bool) -> bool:
863
896
  """Update the package .pyi files, if all the sources are available"""
864
- log.info(f"- Update {self.package_path.name}")
897
+ log.debug(f"- Update {self.package_path.name}")
865
898
  log.trace(f"{self.package_path.as_posix()}")
866
899
 
867
900
  # check if the sources exist
@@ -870,7 +903,7 @@ class StubPackage(PoetryBuilder):
870
903
  log.debug(
871
904
  f"{self.package_name}: skipping as one or more source stub folders are missing"
872
905
  )
873
- self.status["error"] = "Skipped, stub folder(s) missing"
906
+ self.status["error"] = "Skipped, No stubs found."
874
907
  shutil.rmtree(self.package_path.as_posix())
875
908
  self._publish = False # type: ignore
876
909
  return False
@@ -904,15 +937,15 @@ class StubPackage(PoetryBuilder):
904
937
  :param force: BUILD even if no changes
905
938
  :return: True if the package was built
906
939
  """
907
- log.info(f"Build: {self.package_path.name}")
908
940
 
909
941
  ok = self.update_distribution(production)
910
942
  self.status["version"] = self.pkg_version
911
943
  if not ok:
912
- 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")
913
945
  if not self.status["error"]:
914
946
  self.status["error"] = "Could not build/update package"
915
947
  return False
948
+ log.info(f"Build: {self.package_path.name}")
916
949
 
917
950
  # If there are changes to the package, then publish it
918
951
  if self.is_changed() or force:
@@ -943,7 +976,7 @@ class StubPackage(PoetryBuilder):
943
976
 
944
977
  def publish_distribution_ifchanged(
945
978
  self,
946
- db: PysonDB,
979
+ db_conn: sqlite3.Connection,
947
980
  *,
948
981
  production: bool, # PyPI or Test-PyPi
949
982
  build=False, #
@@ -988,9 +1021,9 @@ class StubPackage(PoetryBuilder):
988
1021
  )
989
1022
  self.status["result"] = "Published to GitHub"
990
1023
  else:
991
- return self.publish_distribution(dry_run, production, db)
1024
+ return self.publish_distribution(dry_run, production, db_conn)
992
1025
  elif force:
993
- return self.publish_distribution(dry_run, production, db)
1026
+ return self.publish_distribution(dry_run, production, db_conn)
994
1027
  else:
995
1028
  log.info(f"No changes to package : {self.package_name} {self.pkg_version}")
996
1029
 
@@ -998,7 +1031,12 @@ class StubPackage(PoetryBuilder):
998
1031
  self.clean()
999
1032
  return True
1000
1033
 
1001
- 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:
1002
1040
  """
1003
1041
  Publishes the package to PyPi or Test-PyPi.
1004
1042
 
@@ -1027,9 +1065,34 @@ class StubPackage(PoetryBuilder):
1027
1065
  if dry_run:
1028
1066
  log.warning(f"{self.package_name}: Dry run, not saving to database")
1029
1067
  else:
1030
- # get the package state and add it to the database
1031
- db.add(self.to_dict())
1032
- 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()
1033
1096
  return True
1034
1097
 
1035
1098
  def are_package_sources_available(self) -> bool: