Skip to content

Commit

Permalink
Merge pull request #12 from pomponchik/develop
Browse files Browse the repository at this point in the history
0.0.10
  • Loading branch information
pomponchik authored Jul 23, 2024
2 parents 106b3dd + d48127c commit f9a835b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests_and_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: pip list

- name: Run tests and show coverage on the command line
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=100

- name: Upload reports to codecov
env:
Expand All @@ -45,4 +45,4 @@ jobs:
./codecov -t ${CODECOV_TOKEN}
- name: Run tests and show the branch coverage on the command line
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m
run: coverage run --branch --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=100
4 changes: 2 additions & 2 deletions .github/workflows/tests_and_coverage_old.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: pip list

- name: Run tests and show coverage on the command line
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=100

- name: Upload reports to codecov
env:
Expand All @@ -45,4 +45,4 @@ jobs:
./codecov -t ${CODECOV_TOKEN}
- name: Run tests and show the branch coverage on the command line
run: coverage run --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m
run: coverage run --branch --source=metronomes --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=100
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This library offers the easiest way to run regular tasks. Just give it a functio
- [**Logging**](#logging)
- [**Error escaping**](#error-escaping)
- [**Working with Cancellation Tokens**](#working-with-cancellation-tokens)
- [**Limitations**](#limitations)
- [**How to set a time limit**](#how-to-set-a-time-limit)


## Quick start
Expand Down Expand Up @@ -247,19 +247,32 @@ metronome.start(token=TimeoutToken(1))
If you pass cancellation tokens both during metronome initialization and in the `start()` method, their limitations will be summed up.


## Limitations
## How to set a time limit

You can limit the total running time of the metronome by setting the `duration` value (in seconds):
You can specify a time limit (in seconds) for which the metronome will tick. When the specified time is over, it will simply stop. There are 2 ways to do this: when creating a metronome object or when calling the `start()` method.

```python
from time import sleep
from metronomes import Metronome
In the first way, the time will start counting from the moment the metronome object is created:

metronome = Metronome(0.2, lambda: print('go!'), duration=0.6)
```python
metronome = Metronome(0.2, lambda: print('go!'), duration=0.6)

metronome.start()
sleep(1)
#> go!
#> go!
#> go!
```

In the second way, the countdown will start by calling the `start()` method:

```python
metronome = Metronome(0.2, lambda: print('go!'))

metronome.start(duration=0.6)
sleep(1)
#> go!
#> go!
#> go!
```

Choose the right way to limit time. When using the metronome in the [context manager mode](#use-it-as-a-context-manager), only the first way is available to you, in almost all other situations - the second one is preferable.
19 changes: 13 additions & 6 deletions metronomes/metronome.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ def __init__(self, iteration: Union[int, float], callback: Callable[[], Any], su
self.logger: LoggerProtocol = logger
self.token: AbstractToken = SimpleToken(token)
if duration is not None:
if duration < 0:
raise ValueError('The total duration of the metronome operation cannot be less than zero.')
elif iteration > duration:
raise ValueError('The time of one iteration cannot exceed the running time of the metronome as a whole.')
self.token = self.token + TimeoutToken(duration)
self.token += self.create_duration_token(duration)
self.thread: Optional[Thread] = None
self.started: bool = False
self.stopped: bool = False
Expand All @@ -52,13 +48,16 @@ def __exit__(self, exception_type: Optional[Type[BaseException]], exception_valu
self.stop()
return False

def start(self, token: AbstractToken = DefaultToken()) -> 'Metronome':
def start(self, token: AbstractToken = DefaultToken(), duration: Optional[Union[int, float]] = None) -> 'Metronome':
with self.lock:
if self.stopped:
raise RunStoppedMetronomeError('Metronomes are disposable, you cannot restart a stopped metronome.')
if self.started:
raise RunAlreadyStartedMetronomeError('The metronome has already been launched.')

if duration is not None:
token += self.create_duration_token(duration)

self.thread = Thread(target=self.run_loop, args=(self.token + token,))
self.thread.daemon = True

Expand Down Expand Up @@ -102,3 +101,11 @@ def run_loop(self, token: AbstractToken) -> None:
self.sleeping_callback(sleep_time)

self.stopped = True

def create_duration_token(self, duration: Union[int, float]) -> TimeoutToken:
if duration < 0:
raise ValueError('The total duration of the metronome operation cannot be less than zero.')
elif self.iteration > duration:
raise ValueError('The time of one iteration cannot exceed the running time of the metronome as a whole.')

return TimeoutToken(duration)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'

[project]
name = 'metronomes'
version = '0.0.9'
version = '0.0.10'
authors = [
{ name='Evgeniy Blinov', email='[email protected]' },
]
Expand Down
21 changes: 21 additions & 0 deletions tests/units/test_metronome.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,21 @@ def test_iteration_more_than_duration():
Metronome(5, lambda: None, duration=1)


def test_iteration_more_than_duration_in_start_method():
with pytest.raises(ValueError, match=full_match('The time of one iteration cannot exceed the running time of the metronome as a whole.')):
Metronome(5, lambda: None).start(duration=1)


def test_duration_less_than_zero():
with pytest.raises(ValueError, match=full_match('The total duration of the metronome operation cannot be less than zero.')):
Metronome(0.5, lambda: None, duration=-1)


def test_duration_less_than_zero_in_start_method():
with pytest.raises(ValueError, match=full_match('The total duration of the metronome operation cannot be less than zero.')):
Metronome(0.5, lambda: None).start(duration=-1)


def test_set_duration_time():
metronome = Metronome(0.00001, lambda: None, duration=0.001)

Expand All @@ -258,6 +268,17 @@ def test_set_duration_time():
assert metronome.stopped


def test_set_duration_in_start_method():
metronome = Metronome(0.00001, lambda: None)

assert not metronome.stopped

metronome.start(duration=0.001)
sleep(0.1)

assert metronome.stopped


def test_context_manager_basics():
actions = []
metronome = Metronome(0.00001, lambda: actions.append(1))
Expand Down

0 comments on commit f9a835b

Please sign in to comment.