circup 2.0.2__tar.gz → 2.0.4__tar.gz

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 (78) hide show
  1. {circup-2.0.2 → circup-2.0.4}/.pre-commit-config.yaml +1 -1
  2. {circup-2.0.2 → circup-2.0.4}/.pylintrc +1 -1
  3. {circup-2.0.2/circup.egg-info → circup-2.0.4}/PKG-INFO +1 -1
  4. {circup-2.0.2 → circup-2.0.4}/circup/backends.py +6 -2
  5. {circup-2.0.2 → circup-2.0.4}/circup/command_utils.py +2 -2
  6. {circup-2.0.2 → circup-2.0.4}/circup/commands.py +34 -4
  7. {circup-2.0.2 → circup-2.0.4}/circup/shared.py +3 -4
  8. {circup-2.0.2 → circup-2.0.4/circup.egg-info}/PKG-INFO +1 -1
  9. {circup-2.0.2 → circup-2.0.4}/.github/ISSUE_TEMPLATE.md +0 -0
  10. {circup-2.0.2 → circup-2.0.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  11. {circup-2.0.2 → circup-2.0.4}/.github/workflows/build.yml +0 -0
  12. {circup-2.0.2 → circup-2.0.4}/.github/workflows/release.yml +0 -0
  13. {circup-2.0.2 → circup-2.0.4}/.gitignore +0 -0
  14. {circup-2.0.2 → circup-2.0.4}/.isort.cfg +0 -0
  15. {circup-2.0.2 → circup-2.0.4}/CODE_OF_CONDUCT.rst +0 -0
  16. {circup-2.0.2 → circup-2.0.4}/CODE_OF_CONDUCT.rst.license +0 -0
  17. {circup-2.0.2 → circup-2.0.4}/CONTRIBUTING.rst +0 -0
  18. {circup-2.0.2 → circup-2.0.4}/CONTRIBUTING.rst.license +0 -0
  19. {circup-2.0.2 → circup-2.0.4}/LICENSE +0 -0
  20. {circup-2.0.2 → circup-2.0.4}/LICENSES/CC-BY-4.0.txt +0 -0
  21. {circup-2.0.2 → circup-2.0.4}/LICENSES/MIT.txt +0 -0
  22. {circup-2.0.2 → circup-2.0.4}/LICENSES/Unlicense.txt +0 -0
  23. {circup-2.0.2 → circup-2.0.4}/README.rst +0 -0
  24. {circup-2.0.2 → circup-2.0.4}/README.rst.license +0 -0
  25. {circup-2.0.2 → circup-2.0.4}/circup/__init__.py +0 -0
  26. {circup-2.0.2 → circup-2.0.4}/circup/bundle.py +0 -0
  27. {circup-2.0.2 → circup-2.0.4}/circup/config/bundle_config.json +0 -0
  28. {circup-2.0.2 → circup-2.0.4}/circup/config/bundle_config.json.license +0 -0
  29. {circup-2.0.2 → circup-2.0.4}/circup/logging.py +0 -0
  30. {circup-2.0.2 → circup-2.0.4}/circup/module.py +0 -0
  31. {circup-2.0.2 → circup-2.0.4}/circup.egg-info/SOURCES.txt +0 -0
  32. {circup-2.0.2 → circup-2.0.4}/circup.egg-info/dependency_links.txt +0 -0
  33. {circup-2.0.2 → circup-2.0.4}/circup.egg-info/entry_points.txt +0 -0
  34. {circup-2.0.2 → circup-2.0.4}/circup.egg-info/requires.txt +0 -0
  35. {circup-2.0.2 → circup-2.0.4}/circup.egg-info/top_level.txt +0 -0
  36. {circup-2.0.2 → circup-2.0.4}/docs/_static/favicon.ico +0 -0
  37. {circup-2.0.2 → circup-2.0.4}/docs/_static/favicon.ico.license +0 -0
  38. {circup-2.0.2 → circup-2.0.4}/docs/conf.py +0 -0
  39. {circup-2.0.2 → circup-2.0.4}/docs/index.rst +0 -0
  40. {circup-2.0.2 → circup-2.0.4}/docs/index.rst.license +0 -0
  41. {circup-2.0.2 → circup-2.0.4}/docs/logo.png +0 -0
  42. {circup-2.0.2 → circup-2.0.4}/docs/logo.png.license +0 -0
  43. {circup-2.0.2 → circup-2.0.4}/optional_requirements.txt +0 -0
  44. {circup-2.0.2 → circup-2.0.4}/optional_requirements.txt.license +0 -0
  45. {circup-2.0.2 → circup-2.0.4}/pyproject.toml +0 -0
  46. {circup-2.0.2 → circup-2.0.4}/readthedocs.yml +0 -0
  47. {circup-2.0.2 → circup-2.0.4}/requirements.txt +0 -0
  48. {circup-2.0.2 → circup-2.0.4}/requirements.txt.license +0 -0
  49. {circup-2.0.2 → circup-2.0.4}/setup.cfg +0 -0
  50. {circup-2.0.2 → circup-2.0.4}/tests/__init__.py +0 -0
  51. {circup-2.0.2 → circup-2.0.4}/tests/bad_module/__init__.py +0 -0
  52. {circup-2.0.2 → circup-2.0.4}/tests/bad_module/my_module.py +0 -0
  53. {circup-2.0.2 → circup-2.0.4}/tests/bad_python.py +0 -0
  54. {circup-2.0.2 → circup-2.0.4}/tests/bundle.json +0 -0
  55. {circup-2.0.2 → circup-2.0.4}/tests/bundle.json.license +0 -0
  56. {circup-2.0.2 → circup-2.0.4}/tests/device.json +0 -0
  57. {circup-2.0.2 → circup-2.0.4}/tests/device.json.license +0 -0
  58. {circup-2.0.2 → circup-2.0.4}/tests/dir_module/__init__.py +0 -0
  59. {circup-2.0.2 → circup-2.0.4}/tests/dir_module/my_module.py +0 -0
  60. {circup-2.0.2 → circup-2.0.4}/tests/import_styles.py +0 -0
  61. {circup-2.0.2 → circup-2.0.4}/tests/local_module.py +0 -0
  62. {circup-2.0.2 → circup-2.0.4}/tests/local_module_cp7.mpy +0 -0
  63. {circup-2.0.2 → circup-2.0.4}/tests/local_module_cp7.mpy.license +0 -0
  64. {circup-2.0.2 → circup-2.0.4}/tests/mock_device/boot_out.txt +0 -0
  65. {circup-2.0.2 → circup-2.0.4}/tests/mock_device/boot_out.txt.license +0 -0
  66. {circup-2.0.2 → circup-2.0.4}/tests/mock_device/lib/adafruit_waveform/.gitkeep +0 -0
  67. {circup-2.0.2 → circup-2.0.4}/tests/mount_exists.txt +0 -0
  68. {circup-2.0.2 → circup-2.0.4}/tests/mount_exists.txt.license +0 -0
  69. {circup-2.0.2 → circup-2.0.4}/tests/mount_missing.txt +0 -0
  70. {circup-2.0.2 → circup-2.0.4}/tests/mount_missing.txt.license +0 -0
  71. {circup-2.0.2 → circup-2.0.4}/tests/remote_module.py +0 -0
  72. {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config.json +0 -0
  73. {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config.json.license +0 -0
  74. {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config_local.json +0 -0
  75. {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config_local.json.license +0 -0
  76. {circup-2.0.2 → circup-2.0.4}/tests/test_circup.py +0 -0
  77. {circup-2.0.2 → circup-2.0.4}/tests/test_module.mpy +0 -0
  78. {circup-2.0.2 → circup-2.0.4}/tests/test_module.mpy.license +0 -0
@@ -9,7 +9,7 @@ repos:
9
9
  - id: black
10
10
  exclude: "^tests/bad_python.py$"
11
11
  - repo: https://github.com/pycqa/pylint
12
- rev: v2.15.5
12
+ rev: v3.1.0
13
13
  hooks:
14
14
  - id: pylint
15
15
  name: lint (examples)
@@ -246,7 +246,7 @@ ignore-docstrings=yes
246
246
  ignore-imports=yes
247
247
 
248
248
  # Minimum lines number of a similarity.
249
- min-similarity-lines=4
249
+ min-similarity-lines=8
250
250
 
251
251
 
252
252
  [BASIC]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: circup
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: A tool to manage/update libraries on CircuitPython devices.
5
5
  Author-email: Adafruit Industries <circuitpython@adafruit.com>
6
6
  License: MIT License
@@ -277,7 +277,7 @@ class WebBackend(Backend):
277
277
  """
278
278
 
279
279
  def __init__( # pylint: disable=too-many-arguments
280
- self, host, password, logger, timeout=10, version_override=None
280
+ self, host, port, password, logger, timeout=10, version_override=None
281
281
  ):
282
282
  super().__init__(logger)
283
283
  if password is None:
@@ -297,8 +297,9 @@ class WebBackend(Backend):
297
297
  self.FS_PATH = "fs/"
298
298
  self.LIB_DIR_PATH = f"{self.FS_PATH}lib/"
299
299
  self.host = host
300
+ self.port = port
300
301
  self.password = password
301
- self.device_location = f"http://:{self.password}@{self.host}"
302
+ self.device_location = f"http://:{self.password}@{self.host}:{self.port}"
302
303
 
303
304
  self.session = requests.Session()
304
305
  self.session.mount(self.device_location, HTTPAdapter(max_retries=5))
@@ -306,6 +307,9 @@ class WebBackend(Backend):
306
307
  self.timeout = timeout
307
308
  self.version_override = version_override
308
309
 
310
+ def __repr__(self):
311
+ return f"<WebBackend @{self.device_location}>"
312
+
309
313
  def install_file_http(self, source, location=None):
310
314
  """
311
315
  Install file to device using web workflow.
@@ -610,7 +610,7 @@ def libraries_from_code_py(code_py, mod_names):
610
610
  return [r for r in imports if r in mod_names]
611
611
 
612
612
 
613
- def get_device_path(host, password, path):
613
+ def get_device_path(host, port, password, path):
614
614
  """
615
615
  :param host Hostname or IP address.
616
616
  :param password REST API password.
@@ -621,7 +621,7 @@ def get_device_path(host, password, path):
621
621
  device_path = path
622
622
  elif host:
623
623
  # pylint: enable=no-member
624
- device_path = f"http://:{password}@" + host
624
+ device_path = f"http://:{password}@{host}:{port}"
625
625
  else:
626
626
  device_path = find_device()
627
627
  return device_path
@@ -11,6 +11,7 @@ and the respective Backends which *are* tested. Most of the logic of the followi
11
11
  functions is to prepare things for presentation to / interaction with the user.
12
12
  """
13
13
  import os
14
+ import subprocess
14
15
  import time
15
16
  import sys
16
17
  import re
@@ -56,6 +57,9 @@ from circup.command_utils import (
56
57
  "--host",
57
58
  help="Hostname or IP address of a device. Overrides automatic path detection.",
58
59
  )
60
+ @click.option(
61
+ "--port", help="Port to contact. Overrides automatic path detection.", default=80
62
+ )
59
63
  @click.option(
60
64
  "--password",
61
65
  help="Password to use for authentication when --host is used."
@@ -85,7 +89,7 @@ from circup.command_utils import (
85
89
  )
86
90
  @click.pass_context
87
91
  def main( # pylint: disable=too-many-locals
88
- ctx, verbose, path, host, password, timeout, board_id, cpy_version
92
+ ctx, verbose, path, host, port, password, timeout, board_id, cpy_version
89
93
  ): # pragma: no cover
90
94
  """
91
95
  A tool to manage and update libraries on a CircuitPython device.
@@ -97,7 +101,7 @@ def main( # pylint: disable=too-many-locals
97
101
  if password is None:
98
102
  password = os.getenv("CIRCUP_WEBWORKFLOW_PASSWORD")
99
103
 
100
- device_path = get_device_path(host, password, path)
104
+ device_path = get_device_path(host, port, password, path)
101
105
 
102
106
  using_webworkflow = "host" in ctx.params.keys() and ctx.params["host"] is not None
103
107
 
@@ -113,6 +117,7 @@ def main( # pylint: disable=too-many-locals
113
117
  try:
114
118
  ctx.obj["backend"] = WebBackend(
115
119
  host=host,
120
+ port=port,
116
121
  password=password,
117
122
  logger=logger,
118
123
  timeout=timeout,
@@ -304,6 +309,12 @@ def list_cli(ctx): # pragma: no cover
304
309
  @click.option(
305
310
  "--upgrade", "-U", is_flag=True, help="Upgrade modules that are already installed."
306
311
  )
312
+ @click.option(
313
+ "--stubs",
314
+ "-s",
315
+ is_flag=True,
316
+ help="Install stubs module from PyPi for context in IDE.",
317
+ )
307
318
  @click.option(
308
319
  "--auto-file",
309
320
  default=None,
@@ -312,7 +323,7 @@ def list_cli(ctx): # pragma: no cover
312
323
  )
313
324
  @click.pass_context
314
325
  def install(
315
- ctx, modules, pyext, requirement, auto, auto_file, upgrade=False
326
+ ctx, modules, pyext, requirement, auto, auto_file, upgrade=False, stubs=False
316
327
  ): # pragma: no cover
317
328
  """
318
329
  Install a named module(s) onto the device. Multiple modules
@@ -320,6 +331,7 @@ def install(
320
331
  separated by a space. Modules can be from a Bundle or local filepaths.
321
332
  """
322
333
 
334
+ # pylint: disable=too-many-branches
323
335
  # TODO: Ensure there's enough space on the device
324
336
  available_modules = get_bundle_versions(get_bundles_list())
325
337
  mod_names = {}
@@ -373,6 +385,24 @@ def install(
373
385
  upgrade,
374
386
  )
375
387
 
388
+ if stubs:
389
+ library_stubs = "adafruit-circuitpython-{}".format(
390
+ library.replace("adafruit_", "")
391
+ )
392
+ try:
393
+ output = subprocess.check_output(["pip", "install", library_stubs])
394
+ if (
395
+ f"Requirement already satisfied: {library_stubs}"
396
+ in output.decode()
397
+ ):
398
+ click.echo(f"'{library}' stubs already installed.")
399
+ else:
400
+ click.echo(f"Installed '{library}' stubs.")
401
+ except subprocess.CalledProcessError:
402
+ click.secho(
403
+ f"Could not install stubs module {library_stubs}", fg="yellow"
404
+ )
405
+
376
406
 
377
407
  @main.command()
378
408
  @click.option("--overwrite", is_flag=True, help="Overwrite the file if it exists.")
@@ -697,7 +727,7 @@ def bundle_remove(bundle, reset):
697
727
  bundles_local_dict = get_bundles_local_dict()
698
728
  modified = False
699
729
  for bun in bundle:
700
- # cleanup in case seombody pastes the URL to the repo/releases
730
+ # cleanup in case somebody pastes the URL to the repo/releases
701
731
  bun = re.sub(r"https?://github.com/([^/]+/[^/]+)(/.*)?", r"\1", bun)
702
732
  found = False
703
733
  for name, repo in list(bundles_local_dict.items()):
@@ -10,8 +10,8 @@ import glob
10
10
  import os
11
11
  import re
12
12
  import json
13
+ import importlib.resources
13
14
  import appdirs
14
- import pkg_resources
15
15
  import requests
16
16
 
17
17
  #: Version identifier for a bad MPY file format
@@ -27,9 +27,8 @@ PLATFORMS = {"py": "py", "8mpy": "8.x-mpy", "9mpy": "9.x-mpy"}
27
27
  REQUESTS_TIMEOUT = 30
28
28
 
29
29
  #: The path to the JSON file containing the metadata about the bundles.
30
- BUNDLE_CONFIG_FILE = pkg_resources.resource_filename(
31
- "circup", "config/bundle_config.json"
32
- )
30
+ BUNDLE_CONFIG_FILE = importlib.resources.files("circup") / "config/bundle_config.json"
31
+
33
32
  #: Overwrite the bundles list with this file (only done manually)
34
33
  BUNDLE_CONFIG_OVERWRITE = os.path.join(DATA_DIR, "bundle_config.json")
35
34
  #: The path to the JSON file containing the local list of bundles.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: circup
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: A tool to manage/update libraries on CircuitPython devices.
5
5
  Author-email: Adafruit Industries <circuitpython@adafruit.com>
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes