cleepcli 1.45.0__tar.gz → 1.45.1__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 (37) hide show
  1. {cleepcli-1.45.0/cleepcli.egg-info → cleepcli-1.45.1}/PKG-INFO +2 -2
  2. {cleepcli-1.45.0 → cleepcli-1.45.1}/README.md +1 -1
  3. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/console.py +45 -8
  4. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/test.py +9 -52
  5. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/version.py +1 -1
  6. {cleepcli-1.45.0 → cleepcli-1.45.1/cleepcli.egg-info}/PKG-INFO +2 -2
  7. {cleepcli-1.45.0 → cleepcli-1.45.1}/LICENSE +0 -0
  8. {cleepcli-1.45.0 → cleepcli-1.45.1}/MANIFEST.in +0 -0
  9. {cleepcli-1.45.0 → cleepcli-1.45.1}/bin/ccli +0 -0
  10. {cleepcli-1.45.0 → cleepcli-1.45.1}/bin/cleep-cli +0 -0
  11. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/__init__.py +0 -0
  12. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/check.py +0 -0
  13. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/ci.py +0 -0
  14. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/cleepapi.py +0 -0
  15. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/config.py +0 -0
  16. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/docs.py +0 -0
  17. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/file.py +0 -0
  18. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/git.py +0 -0
  19. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/module.py +0 -0
  20. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/package.py +0 -0
  21. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/tools.py +0 -0
  22. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/watch.py +0 -0
  23. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/SOURCES.txt +0 -0
  24. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/dependency_links.txt +0 -0
  25. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/requires.txt +0 -0
  26. {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/top_level.txt +0 -0
  27. {cleepcli-1.45.0 → cleepcli-1.45.1}/pyproject.toml +0 -0
  28. {cleepcli-1.45.0 → cleepcli-1.45.1}/requirements.txt +0 -0
  29. {cleepcli-1.45.0 → cleepcli-1.45.1}/setup.cfg +0 -0
  30. {cleepcli-1.45.0 → cleepcli-1.45.1}/setup.py +0 -0
  31. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_check.py +0 -0
  32. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_config.py +0 -0
  33. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_console.py +0 -0
  34. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_coverage.py +0 -0
  35. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_docs_breaking.py +0 -0
  36. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_module_scaffold.py +0 -0
  37. {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_watch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cleepcli
3
- Version: 1.45.0
3
+ Version: 1.45.1
4
4
  Summary: Cleep-cli helps developers to build great Cleep applications from command line.
5
5
  Home-page: https://github.com/CleepDevice/cleep-cli
6
6
  Author: Tanguy Bonneau
@@ -142,7 +142,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
142
142
 
143
143
  ## CI (GitHub Actions)
144
144
 
145
- A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.9) via `python -m build` and uploads them to PyPI.
145
+ A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
146
146
 
147
147
  GitHub **environment** `actions` (Settings → Environments), secret:
148
148
 
@@ -106,7 +106,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
106
106
 
107
107
  ## CI (GitHub Actions)
108
108
 
109
- A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.9) via `python -m build` and uploads them to PyPI.
109
+ A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
110
110
 
111
111
  GitHub **environment** `actions` (Settings → Environments), secret:
112
112
 
@@ -4,6 +4,7 @@
4
4
  import sys
5
5
  import subprocess
6
6
  import time
7
+ import atexit
7
8
  from threading import Timer, Thread
8
9
  try: # pragma: no cover
9
10
  from Queue import Queue, Empty
@@ -58,12 +59,40 @@ class EndlessConsole(Thread):
58
59
  self.__stderr_queue = Queue()
59
60
  self.__stdout_thread = None
60
61
  self.__stderr_thread = None
62
+ self.__proc = None
63
+ self.__pid = None
64
+ # Child runs in its own session (setsid). Reap it if the CLI exits via
65
+ # Ctrl-C before kill() — otherwise coverage/pytest can orphan and OOM a Pi.
66
+ atexit.register(self.__reap_child)
61
67
 
62
68
  def __del__(self):
63
69
  """
64
70
  Destructor
65
71
  """
66
72
  self.__stop()
73
+ self.__reap_child()
74
+
75
+ def __reap_child(self):
76
+ """Kill leftover process group if the subprocess is still running."""
77
+ pid = self.__pid
78
+ proc = self.__proc
79
+ if not pid or pid == 1:
80
+ return
81
+ try:
82
+ if proc is not None and proc.poll() is None:
83
+ self.logger.debug('Reaping leftover process group pid=%s', pid)
84
+ if ON_POSIX:
85
+ os.killpg(os.getpgid(pid), signal.SIGKILL)
86
+ else: # pragma: no cover
87
+ proc.kill()
88
+ self.killed = True
89
+ except Exception: # pragma: no cover
90
+ pass
91
+ finally:
92
+ try:
93
+ atexit.unregister(self.__reap_child)
94
+ except Exception: # pragma: no cover
95
+ pass
67
96
 
68
97
  def __enqueue_output(self, output, queue):
69
98
  for line in iter(output.readline, b''):
@@ -103,6 +132,7 @@ class EndlessConsole(Thread):
103
132
  self.logger.debug('Process killed manually')
104
133
  self.killed = True
105
134
  self.__stop()
135
+ self.__reap_child()
106
136
 
107
137
  def __send_stds(self):
108
138
  """
@@ -156,7 +186,9 @@ class EndlessConsole(Thread):
156
186
  close_fds=True,
157
187
  preexec_fn=os.setsid
158
188
  )
159
- pid = proc.pid
189
+ self.__proc = proc
190
+ self.__pid = proc.pid
191
+ pid = self.__pid
160
192
  self.logger.trace('PID=%d' % pid)
161
193
 
162
194
  if self.callback:
@@ -214,14 +246,19 @@ class EndlessConsole(Thread):
214
246
  except Exception: # pragma: no cover
215
247
  pass
216
248
 
217
- # make sure process (and child processes) is really killed
218
- if self.killed and pid != 1:
249
+ # Always reap the process group if still alive. The child is started in its
250
+ # own session (setsid): if the CLI exits on Ctrl-C without kill(), pytest/
251
+ # coverage would otherwise keep running and can OOM a Raspberry Pi.
252
+ if pid != 1:
219
253
  try:
220
- if ON_POSIX:
221
- os.killpg(os.getpgid(pid), signal.SIGKILL)
222
- else: # pragma: no cover
223
- proc.kill()
224
- except Exception: # pragma: no cover
254
+ if proc.poll() is None:
255
+ self.logger.debug('Terminating leftover process group pid=%s', pid)
256
+ if ON_POSIX:
257
+ os.killpg(os.getpgid(pid), signal.SIGKILL)
258
+ else: # pragma: no cover
259
+ proc.kill()
260
+ self.killed = True
261
+ except Exception: # pragma: no cover
225
262
  pass
226
263
 
227
264
  # process is over
@@ -379,56 +379,6 @@ PYTHONPATH=. python3 -m pytest tests -k "%s"
379
379
  """
380
380
  return config.REPO_DIR
381
381
 
382
- def __list_core_files(self, core_path, pattern=None):
383
- """
384
- Return all python files on core with their associated tests
385
-
386
- Args:
387
- core_path (string): core path
388
- pattern (str): custom pattern to filter files to process
389
-
390
- Returns:
391
- dict: list of files with test file path::
392
-
393
- {
394
- python file (string): test file (string)
395
- }
396
-
397
- """
398
- files = []
399
- tests_path = self.__get_core_tests_path()
400
-
401
- self.logger.info('Searching core files...')
402
- for root, _, filenames in os.walk(core_path):
403
- for filename in filenames:
404
- # build paths
405
- filepath = os.path.join(root, filename)
406
- core_relative_path = root.replace('%s' % core_path, '')
407
- core_relative_path = core_relative_path[1:] if core_relative_path.startswith('/') else core_relative_path
408
- test_filepath = os.path.join(tests_path, core_relative_path, 'test_%s' % filename)
409
-
410
- # drop useless files
411
- if not filename.endswith('.py'):
412
- self.logger.debug(' Drop file "%s": not python file', filepath)
413
- continue
414
- if filename.startswith('__init__'):
415
- self.logger.debug(' Drop file "%s": python init file', filepath)
416
- continue
417
- if filename.startswith('test_'):
418
- self.logger.debug(' Drop file "%s": test file', filepath)
419
- continue
420
- if root.endswith('libs/tests'):
421
- self.logger.debug(' Drop file "%s": test lib', filepath)
422
- continue
423
- if pattern and not re.search(pattern, test_filepath) and not re.search(pattern, filepath):
424
- self.logger.debug(' Drop file "%s": does not match pattern %s', filepath, pattern)
425
- continue
426
-
427
- self.logger.debug(' Found "%s" [%s]' % (filepath, test_filepath))
428
- files.append((filepath, test_filepath))
429
-
430
- return files
431
-
432
382
  def core_tests(self, display_coverage=False, display_test_output=False, xml=False, quiet=True, pattern=None):
433
383
  """
434
384
  Execute core unit tests and display process output on stdout
@@ -469,8 +419,15 @@ PYTHONPATH=. coverage run --omit="*/lib/python*/*","*/tests/*","*test_*.py" --so
469
419
  c = EndlessConsole(cmd, console_callback, self.__console_end_callback)
470
420
  c.start()
471
421
 
472
- while self.__endless_command_running:
473
- time.sleep(0.25)
422
+ try:
423
+ while self.__endless_command_running:
424
+ time.sleep(0.25)
425
+ except KeyboardInterrupt:
426
+ self.logger.warning('Interrupted — stopping tests...')
427
+ c.kill()
428
+ while self.__endless_command_running:
429
+ time.sleep(0.1)
430
+ raise
474
431
 
475
432
  success = self.__endless_command_return_code == 0
476
433
 
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- VERSION = "1.45.0"
4
+ VERSION = "1.45.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cleepcli
3
- Version: 1.45.0
3
+ Version: 1.45.1
4
4
  Summary: Cleep-cli helps developers to build great Cleep applications from command line.
5
5
  Home-page: https://github.com/CleepDevice/cleep-cli
6
6
  Author: Tanguy Bonneau
@@ -142,7 +142,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
142
142
 
143
143
  ## CI (GitHub Actions)
144
144
 
145
- A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.9) via `python -m build` and uploads them to PyPI.
145
+ A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
146
146
 
147
147
  GitHub **environment** `actions` (Settings → Environments), secret:
148
148
 
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