diff --git a/.claude/00-obiettivo.md b/.claude/00-obiettivo.md new file mode 100644 index 00000000..049ecf13 --- /dev/null +++ b/.claude/00-obiettivo.md @@ -0,0 +1,14 @@ +# Obiettivo + +Questa branch è dedicata esclusivamente +al miglioramento della documentazione. + +Obiettivi: +- migliorare leggibilità e manutenibilità +- supportare l’onboarding di nuovi contributor +- chiarire le scelte di design e le modalità d’uso + +Ambito escluso: +- nessuna modifica funzionale +- nessun refactoring +- nessuna ottimizzazione delle prestazioni diff --git a/.claude/01-python-style.md b/.claude/01-python-style.md new file mode 100644 index 00000000..e69de29b diff --git a/.claude/02-regole-documentazione.md b/.claude/02-regole-documentazione.md new file mode 100644 index 00000000..948f8efb --- /dev/null +++ b/.claude/02-regole-documentazione.md @@ -0,0 +1,16 @@ +# Regole per la documentazione + +La documentazione deve: +- riflettere il comportamento reale del codice +- basarsi esclusivamente su elementi osservabili +- essere orientata a sviluppatori + +Struttura consigliata: +- panoramica ad alto livello +- modalità d’uso +- assunzioni e casi limite + +Da evitare: +- linguaggio promozionale +- ridondanze +- riscrivere il codice riga per riga diff --git a/.claude/03-vincoli-e-scope.md b/.claude/03-vincoli-e-scope.md new file mode 100644 index 00000000..7d527f89 --- /dev/null +++ b/.claude/03-vincoli-e-scope.md @@ -0,0 +1,15 @@ +# Vincoli e perimetro di intervento + +Consentito: +- aggiungere o migliorare sezioni del README +- aggiungere docstring a interfacce pubbliche +- produrre documentazione di onboarding (guide, panoramiche, esempi d'uso) + +Non consentito: +- modificare firme di funzioni o metodi pubblici +- alterare logica o flussi di controllo, anche in modo apparentemente benigno +- introdurre nuove funzionalità o parametri +- rimuovere comportamento esistente o cambiare il contratto dell'API + +In caso di dubbio: +- fermarsi e richiedere chiarimenti prima di procedere diff --git a/.claude/claude.md b/.claude/claude.md new file mode 100644 index 00000000..550f6e19 --- /dev/null +++ b/.claude/claude.md @@ -0,0 +1,18 @@ +# Contesto iniziale + +Questa repository è stata appena clonata. +Il progetto non è ancora conosciuto in dettaglio. + +Scopo di questa fase: +- esplorare la codebase +- comprenderne struttura e responsabilità +- raccogliere informazioni utili alla documentazione + +Assunzioni iniziali: +- il codice è considerato corretto e funzionante +- l’assenza di documentazione non implica scarsa qualità + +Modalità di collaborazione: +- fornire spiegazioni chiare e sintetiche +- evidenziare eventuali incertezze +- porre domande in caso di ambiguità \ No newline at end of file diff --git a/README.rst b/README.rst index a764cf6a..bc603c0a 100644 --- a/README.rst +++ b/README.rst @@ -53,6 +53,111 @@ Usage schedule.run_pending() time.sleep(1) +Project Structure +----------------- + +The library consists of a single module: + +- ``schedule/__init__.py``: 945 lines containing all scheduling logic (``Scheduler``, ``Job`` classes and module-level functions) +- ``test_schedule.py``: single test file covering the entire codebase + +**Dependencies:** + +- Core: none (standard library only) +- Optional: ``pytz`` (required only for timezone-aware scheduling via ``.at("HH:MM", "Timezone")``) + +Install with timezone support: + +.. code-block:: bash + + $ pip install schedule[timezone] + +Key API Concepts +---------------- + +**Default Scheduler** + +The module provides a default ``Scheduler`` instance. Functions like ``every()``, ``run_pending()``, ``clear()``, and ``get_jobs()`` operate on this shared instance. + +.. code-block:: python + + import schedule + + schedule.every(10).seconds.do(lambda: print("tick")) + schedule.run_pending() # execute jobs that are due + schedule.get_jobs() # list all scheduled jobs + schedule.clear() # remove all jobs + +**Job Tagging** + +Jobs can be tagged for selective retrieval or cancellation. + +.. code-block:: python + + schedule.every().day.do(send_report).tag("daily", "reports") + schedule.every().hour.do(cleanup).tag("maintenance") + + schedule.get_jobs("reports") # jobs tagged "reports" + schedule.clear("maintenance") # cancel jobs tagged "maintenance" + +**Randomized Intervals with** ``.to()`` + +Run a job at random intervals within a range. + +.. code-block:: python + + # Executes every N minutes where 5 <= N <= 10 + schedule.every(5).to(10).minutes.do(refresh_cache) + +**Job Expiration with** ``.until()`` + +Schedule a job to stop running after a given time. + +.. code-block:: python + + from datetime import datetime, timedelta + + # Stop after a specific datetime + schedule.every(1).hour.do(task).until(datetime(2024, 12, 31, 23, 59)) + + # Stop after a duration + schedule.every(30).seconds.do(task).until(timedelta(hours=2)) + + # Stop at a specific time today + schedule.every(5).minutes.do(task).until("18:00") + +**Decorator Syntax with** ``@repeat`` + +Define scheduled jobs using a decorator. + +.. code-block:: python + + from schedule import every, repeat, run_pending + + @repeat(every(10).seconds) + def heartbeat(): + print("alive") + + while True: + run_pending() + +Automated Tests +--------------- + +Tests are written using ``unittest`` from the Python standard library and are contained in a single file: ``test_schedule.py``. They verify the behavior of the public API (scheduling, execution, tagging, cancellation, timezone handling). + +Run tests with the built-in runner: + +.. code-block:: bash + + $ python -m unittest test_schedule + +Or use ``pytest`` as an alternative runner (not required): + +.. code-block:: bash + + $ pytest test_schedule.py + Documentation ------------- diff --git a/docs/development.rst b/docs/development.rst index 56a6c1d0..7d44a2d0 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -11,6 +11,11 @@ All required tooling and libraries can be installed using the ``requirements-dev pip install -r requirements-dev.txt +.. note:: + + On WSL/Ubuntu, run ``sudo apt update`` before installing ``python3-pip``. + The package index must be refreshed to resolve dependencies correctly. + Running tests ------------- @@ -21,6 +26,18 @@ Running tests py.test test_schedule.py --flake8 schedule -v --cov schedule --cov-report term-missing +Platform requirements for timezone tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tests involving timezone manipulation rely on ``time.tzset()``, which is only available on Unix-like systems. +On Windows, ``time.tzset()`` is not implemented, and some timezone-related tests may fail or be skipped. + +If you are developing on Windows, consider the following alternatives: + +- **WSL (Windows Subsystem for Linux)**: Run the test suite inside a WSL distribution. +- **Docker**: Use a Linux-based container to execute the tests. +- **CI with Linux runners**: Rely on continuous integration pipelines configured with Linux environments. + Formatting the code ------------------- This project uses `black formatter `_. diff --git a/example.py b/example.py new file mode 100644 index 00000000..f980d40d --- /dev/null +++ b/example.py @@ -0,0 +1,11 @@ +import schedule +import time + +def job(): + print("Hello, schedule!") + +schedule.every(5).seconds.do(job) + +while True: + schedule.run_pending() + time.sleep(1)