micropython-stubber 1.24.2__py3-none-any.whl → 1.24.4.post1__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 (83) hide show
  1. {micropython_stubber-1.24.2.dist-info → micropython_stubber-1.24.4.post1.dist-info}/METADATA +7 -28
  2. micropython_stubber-1.24.4.post1.dist-info/RECORD +107 -0
  3. {micropython_stubber-1.24.2.dist-info → micropython_stubber-1.24.4.post1.dist-info}/WHEEL +1 -1
  4. stubber/__init__.py +1 -1
  5. stubber/board/createstubs_db.py +1 -1
  6. stubber/board/createstubs_mem.py +1 -1
  7. stubber/bulk/mcu_stubber.py +1 -1
  8. stubber/codemod/board.py +1 -1
  9. stubber/codemod/enrich.py +12 -10
  10. stubber/codemod/merge_docstub.py +83 -53
  11. stubber/codemod/visitors/type_helpers.py +143 -41
  12. stubber/commands/enrich_folder_cmd.py +17 -17
  13. stubber/commands/get_docstubs_cmd.py +22 -3
  14. stubber/commands/get_frozen_cmd.py +1 -0
  15. stubber/commands/merge_cmd.py +2 -4
  16. stubber/merge_config.py +5 -39
  17. stubber/minify.py +3 -3
  18. stubber/modcat.py +118 -0
  19. stubber/publish/merge_docstubs.py +21 -3
  20. stubber/publish/stubpackage.py +10 -27
  21. stubber/rst/lookup.py +3 -23
  22. stubber/stubs_from_docs.py +2 -1
  23. stubber/{cst_transformer.py → typing_collector.py} +34 -3
  24. micropython_stubber-1.24.2.dist-info/RECORD +0 -163
  25. mpflash/README.md +0 -220
  26. mpflash/libusb_flash.ipynb +0 -203
  27. mpflash/mpflash/__init__.py +0 -0
  28. mpflash/mpflash/add_firmware.py +0 -98
  29. mpflash/mpflash/ask_input.py +0 -236
  30. mpflash/mpflash/basicgit.py +0 -324
  31. mpflash/mpflash/bootloader/__init__.py +0 -2
  32. mpflash/mpflash/bootloader/activate.py +0 -60
  33. mpflash/mpflash/bootloader/detect.py +0 -82
  34. mpflash/mpflash/bootloader/manual.py +0 -101
  35. mpflash/mpflash/bootloader/micropython.py +0 -12
  36. mpflash/mpflash/bootloader/touch1200.py +0 -36
  37. mpflash/mpflash/cli_download.py +0 -129
  38. mpflash/mpflash/cli_flash.py +0 -224
  39. mpflash/mpflash/cli_group.py +0 -111
  40. mpflash/mpflash/cli_list.py +0 -87
  41. mpflash/mpflash/cli_main.py +0 -39
  42. mpflash/mpflash/common.py +0 -217
  43. mpflash/mpflash/config.py +0 -44
  44. mpflash/mpflash/connected.py +0 -96
  45. mpflash/mpflash/download.py +0 -364
  46. mpflash/mpflash/downloaded.py +0 -138
  47. mpflash/mpflash/errors.py +0 -9
  48. mpflash/mpflash/flash/__init__.py +0 -55
  49. mpflash/mpflash/flash/esp.py +0 -59
  50. mpflash/mpflash/flash/stm32.py +0 -19
  51. mpflash/mpflash/flash/stm32_dfu.py +0 -104
  52. mpflash/mpflash/flash/uf2/__init__.py +0 -104
  53. mpflash/mpflash/flash/uf2/boardid.py +0 -15
  54. mpflash/mpflash/flash/uf2/linux.py +0 -136
  55. mpflash/mpflash/flash/uf2/macos.py +0 -42
  56. mpflash/mpflash/flash/uf2/uf2disk.py +0 -12
  57. mpflash/mpflash/flash/uf2/windows.py +0 -43
  58. mpflash/mpflash/flash/worklist.py +0 -170
  59. mpflash/mpflash/list.py +0 -106
  60. mpflash/mpflash/logger.py +0 -41
  61. mpflash/mpflash/mpboard_id/__init__.py +0 -98
  62. mpflash/mpflash/mpboard_id/add_boards.py +0 -265
  63. mpflash/mpflash/mpboard_id/board.py +0 -37
  64. mpflash/mpflash/mpboard_id/board_id.py +0 -92
  65. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  66. mpflash/mpflash/mpboard_id/store.py +0 -48
  67. mpflash/mpflash/mpremoteboard/__init__.py +0 -271
  68. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +0 -152
  69. mpflash/mpflash/mpremoteboard/runner.py +0 -140
  70. mpflash/mpflash/vendor/board_database.py +0 -185
  71. mpflash/mpflash/vendor/click_aliases.py +0 -91
  72. mpflash/mpflash/vendor/dfu.py +0 -165
  73. mpflash/mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt +0 -21
  74. mpflash/mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2 +0 -0
  75. mpflash/mpflash/vendor/pydfu.py +0 -605
  76. mpflash/mpflash/vendor/readme.md +0 -14
  77. mpflash/mpflash/versions.py +0 -123
  78. mpflash/poetry.lock +0 -2869
  79. mpflash/pyproject.toml +0 -66
  80. mpflash/stm32_udev_rules.md +0 -63
  81. stubber/codemod/test_enrich.py +0 -87
  82. {micropython_stubber-1.24.2.dist-info → micropython_stubber-1.24.4.post1.dist-info}/LICENSE +0 -0
  83. {micropython_stubber-1.24.2.dist-info → micropython_stubber-1.24.4.post1.dist-info}/entry_points.txt +0 -0
@@ -14,6 +14,8 @@ import stubber.utils as utils
14
14
  from mpflash.logger import log
15
15
  from stubber.codemod.enrich import enrich_folder
16
16
  from stubber.commands.cli import stubber_cli
17
+ from stubber.merge_config import copy_type_modules
18
+ from stubber.modcat import CP_REFERENCE_TO_DOCSTUB
17
19
  from stubber.stubs_from_docs import generate_from_rst
18
20
  from stubber.utils.config import CONFIG
19
21
  from stubber.utils.repos import fetch_repos
@@ -68,6 +70,22 @@ from stubber.utils.repos import fetch_repos
68
70
  help="Enrich with type information from reference/micropython",
69
71
  show_default=True,
70
72
  )
73
+ # @click.option(
74
+ # "--copy-params",
75
+ # "copy_params",
76
+ # default=False,
77
+ # help="Copy the function/method parameters",
78
+ # show_default=True,
79
+ # is_flag=True,
80
+ # )
81
+ # @click.option(
82
+ # "--copy-docstr",
83
+ # "copy_docstr",
84
+ # default=False,
85
+ # help="Copy the docstrings",
86
+ # show_default=False,
87
+ # is_flag=True,
88
+ # )
71
89
  @click.pass_context
72
90
  def cli_docstubs(
73
91
  ctx: click.Context,
@@ -126,9 +144,8 @@ def cli_docstubs(
126
144
 
127
145
  if enrich:
128
146
  if Version(version) < Version("1.24"):
129
- log.warning(f"Enriching is not supported for version {version}")
147
+ log.warning(f"Enriching is only supported for version v1.24+, not {version}")
130
148
  else:
131
- # !stubber enrich --params-only --source {reference} --dest {docstubs}
132
149
  reference_path = CONFIG.stub_path.parent / "reference/micropython"
133
150
  _ = enrich_folder(
134
151
  reference_path,
@@ -136,8 +153,10 @@ def cli_docstubs(
136
153
  show_diff=False,
137
154
  write_back=True,
138
155
  require_docstub=False,
139
- params_only=True,
156
+ copy_params=True,
157
+ copy_docstr=False,
140
158
  )
159
+ copy_type_modules(reference_path, dst_path, CP_REFERENCE_TO_DOCSTUB)
141
160
  log.info("::group:: start post processing of retrieved stubs")
142
161
  # do not run stubgen
143
162
  utils.do_post_processing([dst_path], stubgen=False, black=black, autoflake=autoflake)
@@ -109,6 +109,7 @@ def cli_get_frozen(
109
109
  show_diff=False,
110
110
  write_back=True,
111
111
  require_docstub=False,
112
+ copy_docstr=True,
112
113
  ext = ".pyi",
113
114
  ):
114
115
  log.info(f" > Enriched {merged} frozen modules.")
@@ -5,8 +5,8 @@ enrich machinestubs with docstubs
5
5
  from typing import List, Union
6
6
 
7
7
  import rich_click as click
8
- from mpflash.logger import log
9
8
 
9
+ from mpflash.logger import log
10
10
  from stubber.commands.cli import stubber_cli
11
11
  from stubber.publish.merge_docstubs import merge_all_docstubs
12
12
  from stubber.publish.package import GENERIC_L
@@ -60,6 +60,4 @@ def cli_merge_docstubs(
60
60
  versions = list(versions)
61
61
  # single version should be a string
62
62
  log.info(f"Merge docstubs for {family} {versions}")
63
- _ = merge_all_docstubs(
64
- versions=versions, family=family, boards=boards, ports=ports, mpy_path=CONFIG.mpy_path
65
- )
63
+ _ = merge_all_docstubs(versions=versions, family=family, boards=boards, ports=ports)
stubber/merge_config.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """
2
2
  Merge configuration for the stubber.
3
- defines constants and util functions to copy, update or remove type modules
3
+ util functions to copy, update or remove type modules
4
4
  """
5
5
 
6
6
  import shutil
@@ -8,46 +8,11 @@ from pathlib import Path
8
8
  from typing import Final, List
9
9
 
10
10
  from mpflash.logger import log
11
- from stubber.rst.lookup import U_MODULES
12
11
 
13
- EXT: Final = [".pyi", ".py", ""]
14
- CP_REFERENCE_TO_DOCSTUB: Final = [
15
- "asyncio",
16
- "rp2/PIOASMEmit.pyi",
17
- "rp2/asm_pio.pyi",
18
- ]
19
- "Modules to copy from reference modules to the docstubs"
20
-
21
-
22
- STDLIB_MODULES: Final = [
23
- "collections",
24
- "io",
25
- "builtins",
26
- "asyncio",
27
- "sys",
28
- # "os", # TODO # Do not remove `os` to allow better typing by mypy for the `os` module
29
- # "ssl", # TODO
30
- ]
31
- """Modules that should be in /stdlib"""
32
- # and should not be in the individual packes as that causes duplication
12
+ from stubber.modcat import (CP_REFERENCE_TO_DOCSTUB, RM_MERGED,
13
+ STDLIB_ONLY_MODULES, U_MODULES)
33
14
 
34
- RM_MERGED: Final = (
35
- [
36
- "sys", # use auto patched version from mpy_stdlib
37
- "asyncio", # use manually patched version from mpy_stdlib
38
- "_asyncio", # ditto
39
- "uasyncio", # ditto
40
- "_rp2", # Leave out for now , to avoid conflicts with the rp2 module
41
- "pycopy_imphook", # pycopy only: not needed in the merged stubs
42
- # "os",
43
- "types", # defined in webassembly pyscript - shadows stdlib
44
- "abc", # defined in webassembly pyscript - shadows stdlib
45
- # "uos", # ???? problems with mypy & webassembly stubs
46
- ]
47
- + STDLIB_MODULES
48
- + [f"u{mod}" for mod in U_MODULES]
49
- )
50
- "Modules to remove from merged stubs, U_MODULES will be recreated later"
15
+ EXT: Final = [".pyi", ".py", ""]
51
16
 
52
17
 
53
18
  def copy_type_modules(source_folder: Path, target_folder: Path, CP_REFERENCE_MODULES: List[str]):
@@ -112,3 +77,4 @@ def remove_modules(target_folder: Path, RM_MODULES: List[str]):
112
77
  target.unlink()
113
78
  finally:
114
79
  log.debug(f" - remove {target}")
80
+
stubber/minify.py CHANGED
@@ -370,8 +370,8 @@ def cross_compile(
370
370
  # target must be a Path object
371
371
  _target = get_temp_file(suffix=".mpy")
372
372
  result = pipx_mpy_cross(version, source_file, _target)
373
- if result.stderr and "No matching distribution found for mpy-cross==" in result.stderr:
374
- log.warning(f"mpy-cross=={version} not found, using most current version.")
373
+ if result.stderr and "No matching distribution found for mpy-cross~=" in result.stderr:
374
+ log.warning(f"mpy-cross~={version} not found, using most current version.")
375
375
  result = pipx_mpy_cross(V_PREVIEW, source_file, _target)
376
376
 
377
377
  if result.returncode == 0:
@@ -395,7 +395,7 @@ def pipx_mpy_cross(version: str, source_file, _target):
395
395
  if version in SET_PREVIEW:
396
396
  version = ""
397
397
  if version:
398
- version = "==" + version
398
+ version = "~=" + version.lstrip("v")
399
399
 
400
400
  cmd = ["pipx", "run", f"mpy-cross{version}"] if version else ["pipx", "run", "mpy-cross"]
401
401
  # Add params
stubber/modcat.py ADDED
@@ -0,0 +1,118 @@
1
+ """
2
+ Used to define where stub modules should and should not be copied to, or merged to
3
+
4
+ This is shared between stubber, and external build scripts.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Final
9
+
10
+ from stubber.publish.enums import StubSource
11
+
12
+ ########################################################
13
+ STDLIB_ONLY_MODULES = [
14
+ "abc",
15
+ "array",
16
+ "collections",
17
+ "io",
18
+ "builtins",
19
+ "asyncio",
20
+ "sys",
21
+ "types",
22
+ "ssl",
23
+ "os",
24
+ # Experiment
25
+ "json",
26
+ "struct"
27
+ # "socket", # should be ins tdlib - but is only available on networked boards
28
+ # time # should be in stdlib - but has implementation differences per port)
29
+ ]
30
+ """Modules that should only be in stdlib, and not in the individual packages"""
31
+ # and should not be in the individual packes as that causes duplication
32
+
33
+
34
+ ########################################################
35
+ # stubber.publish.stubpacker #
36
+ ########################################################
37
+ # Indicates which stubs will NOT be copied from the stub sources
38
+ # and shared with multiple modules and the sdtbli build.py that is in the stubs repo
39
+ STUBS_COPY_FILTER = {
40
+ StubSource.FROZEN: [
41
+ "espnow", # merged stubs + documentation of the espnow module is better than the info in the frozen stubs
42
+ # "collections", # must be in stdlib
43
+ # "types", # must be in stdlib
44
+ # "abc", # must be in stdlib
45
+ "time", # used from merged ( should be in stdlib - but has implementation differences per port)
46
+ # "io", # must be in stdlib
47
+ ] + STDLIB_ONLY_MODULES,
48
+ StubSource.FIRMWARE: [
49
+ "builtins",
50
+ # "collections", # collections must be in stdlib
51
+ ] + STDLIB_ONLY_MODULES,
52
+ StubSource.MERGED: STDLIB_ONLY_MODULES,
53
+ }
54
+
55
+ # these modules will be replaced by a simple import statement to import from stdlib
56
+ STDLIB_UMODULES = ["ucollections"]
57
+
58
+ ########################################################
59
+ # stubber.rst... #
60
+ ########################################################
61
+ U_MODULES = [
62
+ "array",
63
+ "asyncio",
64
+ "binascii",
65
+ "bluetooth",
66
+ "errno",
67
+ "io",
68
+ "json",
69
+ "machine",
70
+ "os",
71
+ "platform",
72
+ "select",
73
+ "ssl",
74
+ "struct",
75
+ "socket",
76
+ "sys",
77
+ "time",
78
+ "zlib",
79
+ ]
80
+ """
81
+ List of modules that are documented with the base name only,
82
+ but can also be imported with a `u` prefix
83
+ """
84
+
85
+ ########################################################
86
+ # stubber.merge_config #
87
+ # defines constants to copy, update, remove type stubs #
88
+ ########################################################
89
+
90
+ CP_REFERENCE_TO_DOCSTUB: Final = [
91
+ "asyncio", # just for documentation
92
+ # stdlib stubs are using the version from stdlib/asyncio
93
+ "rp2/PIOASMEmit.pyi",
94
+ "rp2/asm_pio.pyi",
95
+ ]
96
+ "Modules to copy from reference modules to the docstubs"
97
+
98
+
99
+
100
+
101
+ RM_MERGED = (
102
+ [
103
+ "sys", # use auto patched version from mpy_stdlib
104
+ "asyncio", # use manually patched version from mpy_stdlib
105
+ "_asyncio", # ditto
106
+ "uasyncio", # ditto
107
+ "_rp2", # Leave out for now , to avoid conflicts with the rp2 module
108
+ "pycopy_imphook", # pycopy only: not needed in the merged stubs
109
+ # "os",
110
+ "types", # defined in webassembly pyscript - shadows stdlib
111
+ "abc", # defined in webassembly pyscript - shadows stdlib
112
+ # "uos", # ???? problems with mypy & webassembly stubs
113
+ ]
114
+ + STDLIB_ONLY_MODULES
115
+ + [f"u{mod}" for mod in U_MODULES]
116
+ )
117
+ "Modules to remove from merged stubs, U_MODULES will be recreated later"
118
+
@@ -20,8 +20,8 @@ def merge_all_docstubs(
20
20
  family: str = "micropython",
21
21
  ports: Optional[Union[List[str], str]] = None,
22
22
  boards: Optional[Union[List[str], str]] = None,
23
- *,
24
- mpy_path: Path = CONFIG.mpy_path,
23
+ # *,
24
+ # mpy_path: Path = CONFIG.mpy_path,
25
25
  ):
26
26
  """merge docstubs and MCU stubs to merged stubs"""
27
27
  if versions is None:
@@ -66,7 +66,19 @@ def merge_all_docstubs(
66
66
  continue
67
67
  log.info(f"Merge {candidate['version']} docstubs with boardstubs to {merged_path.name}")
68
68
  try:
69
+ # TODO : webassembly: Need to merge from reference/pyscript as well
69
70
  result = copy_and_merge_docstubs(board_path, merged_path, doc_path)
71
+ if candidate["port"] == "webassembly":
72
+ # TODO : webassembly: Need to merge from reference/pyscript as well
73
+ # use enrich_folder to merge the docstubs
74
+ enrich_folder(
75
+ source_folder=CONFIG.mpy_stubs_path / "reference/pyscript",
76
+ target_folder=merged_path,
77
+ write_back=True,
78
+ copy_params=True,
79
+ copy_docstr=True,
80
+ )
81
+ pass
70
82
  except Exception as e:
71
83
  log.error(f"Error parsing {candidate['version']} docstubs: {e}")
72
84
  continue
@@ -121,7 +133,13 @@ def copy_and_merge_docstubs(fw_path: Path, dest_path: Path, docstub_path: Path):
121
133
  recreate_umodules(dest_path)
122
134
 
123
135
  # 2 - Enrich the MCU stubs with the document stubs
124
- result = enrich_folder(source_folder=docstub_path, target_folder=dest_path, write_back=True)
136
+ result = enrich_folder(
137
+ source_folder=docstub_path,
138
+ target_folder=dest_path,
139
+ write_back=True,
140
+ copy_params=True,
141
+ copy_docstr=True,
142
+ )
125
143
 
126
144
  refactor_rp2_module(dest_path)
127
145
 
@@ -18,8 +18,8 @@ from pathlib import Path
18
18
  from typing import Any, Dict, List, Optional, Tuple, Union
19
19
 
20
20
  import tenacity
21
-
22
21
  from mpflash.basicgit import get_git_describe
22
+
23
23
  from stubber.publish.helpers import get_module_docstring
24
24
 
25
25
  if sys.version_info >= (3, 11):
@@ -30,41 +30,20 @@ else:
30
30
  from typing import NewType
31
31
 
32
32
  import tomli_w
33
- from packaging.version import Version, parse
34
-
35
33
  from mpflash.logger import log
36
34
  from mpflash.versions import SET_PREVIEW, V_PREVIEW, clean_version
35
+ from packaging.version import Version, parse
36
+
37
37
  from stubber.publish.bump import bump_version
38
38
  from stubber.publish.defaults import GENERIC_U, default_board
39
39
  from stubber.publish.enums import StubSource
40
40
  from stubber.publish.pypi import Version, get_pypi_versions
41
41
  from stubber.utils.config import CONFIG
42
+ from stubber.modcat import STDLIB_UMODULES, STUBS_COPY_FILTER
42
43
 
43
44
  Status = NewType("Status", Dict[str, Union[str, None]])
44
45
  StubSources = List[Tuple[StubSource, Path]]
45
46
 
46
- # indicates which stubs will not be copyied from the stub sources
47
- STUBS_COPY_FILTER = {
48
- StubSource.FROZEN: [
49
- "espnow", # merged stubs + documentation of the espnow module is better than the info in the frozen stubs
50
- "collections", # must be in stdlib
51
- "types", # must be in stdlib
52
- "abc", # must be in stdlib
53
- "time", # must be in stdlib
54
- "io", # must be in stdlib
55
- ],
56
- StubSource.FIRMWARE: [
57
- "builtins",
58
- "collections", # collections must be in stdlib
59
- ],
60
- StubSource.MERGED: [
61
- "collections", # collections must be in stdlib
62
- ],
63
- }
64
-
65
- # these modules will be replaced by a simple import statement to import from stdlib
66
- STDLIB_UMODULES = ["ucollections"]
67
-
68
47
 
69
48
  class VersionedPackage:
70
49
  """
@@ -287,8 +266,12 @@ class Builder(VersionedPackage):
287
266
  # make sure parent folder exists
288
267
  _toml = self.toml_path
289
268
  (_toml).parent.mkdir(parents=True, exist_ok=True)
290
- with open(_toml, "wb") as output:
291
- tomli_w.dump(pyproject, output)
269
+ try:
270
+ with open(_toml, "wb") as output:
271
+ tomli_w.dump(pyproject, output)
272
+ except OSError as e:
273
+ log.error(e)
274
+ log.debug(repr(_toml))
292
275
 
293
276
  # -----------------------------------------------
294
277
  def create_update_pyproject_toml(self) -> None:
stubber/rst/lookup.py CHANGED
@@ -16,7 +16,6 @@ __all__ = [
16
16
  "MODULE_GLUE",
17
17
  "RST_DOC_FIXES",
18
18
  "DOCSTUB_SKIP",
19
- "U_MODULES",
20
19
  ]
21
20
 
22
21
  # all possible Types needed for the stubs - excess types should be removed later , and otherwise won't do much harm
@@ -52,25 +51,6 @@ class Fix:
52
51
  "the from_ string is a regular expression"
53
52
 
54
53
 
55
- U_MODULES = [
56
- "array",
57
- "asyncio",
58
- "binascii",
59
- "io",
60
- "json",
61
- "machine",
62
- "os",
63
- "select",
64
- "ssl",
65
- "struct",
66
- "socket",
67
- "time",
68
- "zlib",
69
- ]
70
- """
71
- List of modules that are documented with the base name only,
72
- but can also be imported with a `u` prefix
73
- """
74
54
 
75
55
  # This table is used to try to correct the errors in the documentation,
76
56
  # or adapt the human readable documentation to machine readable.
@@ -157,8 +137,8 @@ LOOKUP_LIST = {
157
137
  "uio.open": ("IO", 0.95), # Open a file.
158
138
  "uos.listdir": ("List[Incomplete]", 0.95),
159
139
  "os.uname": ("uname_result", 0.95),
160
- # undocumented CPython class ssl.SSLSocket
161
- # TODO: include ssl.SSLSocket from stdlib / mpy_typeshed, currently Incomplete
140
+ # ssl.SSLSocket is defined in reference/micropython/ssl
141
+
162
142
  "ssl.wrap_socket": ("SSLSocket", 0.95),
163
143
  "ussl.wrap_socket": ("SSLSocket", 0.95),
164
144
  #
@@ -370,7 +350,7 @@ MODULE_GLUE = {
370
350
  "ssl": [
371
351
  "from typing_extensions import TypeAlias",
372
352
  "from _mpy_shed import StrOrBytesPath",
373
- "SSLSocket : TypeAlias = Incomplete",
353
+ # SSLSocket is part of the refence stubs
374
354
  ],
375
355
  "struct": ANY_BUF,
376
356
  "time": [
@@ -10,7 +10,8 @@ from typing import List, Optional
10
10
  from mpflash.logger import log
11
11
 
12
12
  from stubber import utils
13
- from stubber.rst import DOCSTUB_SKIP, U_MODULES
13
+ from stubber.rst import DOCSTUB_SKIP
14
+ from stubber.modcat import U_MODULES
14
15
  from stubber.rst.reader import RSTWriter
15
16
 
16
17
 
@@ -44,12 +44,33 @@ MODULE_KEY = ("__module",)
44
44
  MOD_DOCSTR_KEY = ("__module_docstring",)
45
45
 
46
46
  # debug helper
47
- _m = cst.parse_module("")
47
+ _code = cst.parse_module("").code_for_node
48
+
49
+
50
+ def is_property(node: cst.FunctionDef) -> bool:
51
+ """check if the function is a property"""
52
+ return any(m.matches(dec, m.Decorator(decorator=m.Name(value="property"))) for dec in node.decorators)
53
+
54
+
55
+ # FIXME : this is a clumsy way - but I cant find a working matcher for this
56
+ def is_setter(node: cst.FunctionDef) -> bool:
57
+ """check if the function is a setter"""
58
+ return any(d for d in _code(node).split("\n") if d.startswith("@") and d.endswith(".setter"))
59
+
60
+
61
+ def is_getter(node: cst.FunctionDef) -> bool:
62
+ """check if the function is a getter"""
63
+ return any(d for d in _code(node).split("\n") if d.startswith("@") and d.endswith(".getter"))
64
+
65
+
66
+ def is_deleter(node: cst.FunctionDef) -> bool:
67
+ """check if the function is a deleter"""
68
+ return any(d for d in _code(node).split("\n") if d.startswith("@") and d.endswith(".deleter"))
48
69
 
49
70
 
50
71
  class StubTypingCollector(cst.CSTVisitor):
51
72
  """
52
- Collect the function/method and class definitions from the stubs source
73
+ Collect the function/method and class definitions from ta rich .py or .pyi source
53
74
  """
54
75
 
55
76
  def __init__(self):
@@ -120,11 +141,21 @@ class StubTypingCollector(cst.CSTVisitor):
120
141
  def_type="funcdef",
121
142
  def_node=node,
122
143
  )
123
- key = tuple(self.stack)
144
+ if is_getter(node):
145
+ extra = ["getter"]
146
+ elif is_setter(node):
147
+ extra = ["setter"]
148
+ elif is_deleter(node):
149
+ extra = ["deleter"]
150
+ else:
151
+ extra = []
152
+ key = tuple(self.stack + extra)
153
+
124
154
  if not key in self.annotations:
125
155
  # store the first function/method signature
126
156
  self.annotations[key] = AnnoValue(type_info=ti)
127
157
 
158
+
128
159
  if any(m.matches(dec , m.Decorator(decorator=m.Name("overload"))) for dec in node.decorators):
129
160
  # and store the overloads
130
161
  self.annotations[key].overloads.append(ti)