diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index fd75256f..2c083b1e 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -15,5 +15,5 @@
- [ ] Version updated in changelog
- [ ] Branch merged
- [ ] Tag created and pushed
-- [ ] Published
+- [ ] Confirm published job runs successfully
- [ ] Github release created
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index afea5ff8..56619941 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,10 +1,11 @@
š Changelog
============
-0.6.3 (2024-07-??)
+0.6.3 (2024-07-13)
------------------
- Improve robustness and speed of keyword argument parsing in Rust extension (#149)
+- Add more answers to common questions in the docs and FAQ (#148, #150)
0.6.2 (2024-07-04)
------------------
diff --git a/Cargo.lock b/Cargo.lock
index 05407df8..fbafad8c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -165,7 +165,7 @@ checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
[[package]]
name = "whenever"
-version = "0.6.0-beta.1"
+version = "0.6.3"
dependencies = [
"pyo3",
"pyo3-build-config",
diff --git a/Cargo.toml b/Cargo.toml
index 356c191d..07ca0663 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "whenever"
-version = "0.6.0-beta.1"
+version = "0.6.3"
authors = []
description = "Rust extension module for whenever"
edition = "2021"
diff --git a/README.md b/README.md
index 086e8886..6dbc1ab6 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[![](https://img.shields.io/github/actions/workflow/status/ariebovenberg/whenever/checks.yml?branch=main&style=flat-square)](https://github.com/ariebovenberg/whenever)
[![](https://img.shields.io/readthedocs/whenever.svg?style=flat-square)](http://whenever.readthedocs.io/)
-**Typed and DST-safe datetimes for Python, written in Rust**
+**Typed and DST-safe datetimes for Python, written in Rust\***
Do you cross your fingers every time you work with Python's datetimeāhoping that you didn't mix naive and aware?
or that you avoided its [other pitfalls](https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/)?
@@ -33,6 +33,7 @@ It's also **way faster** than other third-party librariesāand usually the stan
RFC3339-parse, normalize, compare to now, shift, and change timezone (1M times)
+
[šĀ Docs](https://whenever.readthedocs.io)Ā |
@@ -49,6 +50,8 @@ It's also **way faster** than other third-party librariesāand usually the stan
> as we gather feedback and improve the library.
> Leave a āļø on github if you'd like to see how this project develops!
+\**Skeptical of Rust? Don't worry, it's available in pure Python too!*
+
## Why not the standard library?
Over 20+ years, Python's `datetime` has grown
diff --git a/docs/faq.rst b/docs/faq.rst
index 7ce3f24c..c15304fc 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -139,6 +139,12 @@ You can check if the Rust extension is being used by running:
you should consult its documentation on opting out of binary wheels.
+What's the performance of the pure-Python version?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In casual benchmarks, the pure-Python version is about 10x slower than the Rust version,
+making it 5x slower than the standard library but still (in general) faster than Pendulum and Arrow.
+
What about ``dateutil``?
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -150,3 +156,21 @@ That said, here are my thoughts on dateutil: while it certainly provides
useful helpers (especially for parsing and arithmetic), it doesn't solve the
(IMHO) most glaring issues with the standard library: DST-safety and typing
for naive/aware. These are issues that only a full replacement can solve.
+
+Why use ``pyo3_ffi`` instead of ``PyO3``?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are two main reasons:
+
+1. The higher-level binding library PyO3 has a small additional overhead for function calls,
+ which can be significant for small functions. Whenever has a lot of small functions.
+ Only with ``pyo3_ffi`` can these functions be on par (or faster) than the standard library.
+ The overhead has decreased in recent versions of PyO3, but it's still there.
+2. I was eager to learn to use the bare C API of Python, in order to better
+ understand how Python extension modules and PyO3 work under the hood.
+
+Additional advantages of ``pyo3_ffi`` are:
+
+- Its API is more stable than PyO3's, which is still evolving.
+- It allows support for per-interpreter GIL, and free-threaded Python,
+ which are not yet supported by PyO3.
diff --git a/docs/overview.rst b/docs/overview.rst
index dd79a802..a55dd840 100644
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -375,6 +375,20 @@ and :class:`~whenever.SystemDateTime` types:
Common approaches are to extrapolate the time forward or backwards
to 1:30am or 3:30am.
+ .. important::
+
+ You may wonder why skipped time is "extrapolated" like this,
+ and not truncated. Why turn 2:30am into 3:30am and not cut
+ it off at 1:59am when the gap occurs?
+
+ The reason for the "extrapolation" approach is:
+
+ * It fits the most likely reason the time is skipped: we forgot to adjust the clock, or adjusted it too early
+ * This is how other datetime libraries do it (e.g. Javascript (Temporal), C# (Nodatime), Java, Python itself)
+ * It corresponds with the iCalendar (RFC5545) standard of handling gaps
+
+ The figure in the Python docs `here `_ also shows how this "extrapolation" makes sense graphically.
+
**Whenever** `refuses to guess `_
and requires that you explicitly handle these situations
with the ``disambiguate=`` argument:
diff --git a/pyproject.toml b/pyproject.toml
index 6edc7b8d..4bfbbe2f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ authors = [
{name = "Arie Bovenberg", email = "a.c.bovenberg@gmail.com"},
]
readme = "README.md"
-version = "0.6.1"
+version = "0.6.3"
description = "Modern datetime library for Python, written in Rust"
requires-python = ">=3.9"
classifiers = [
diff --git a/pysrc/whenever/_pywhenever.py b/pysrc/whenever/_pywhenever.py
index 48c47404..5cf4ff3a 100644
--- a/pysrc/whenever/_pywhenever.py
+++ b/pysrc/whenever/_pywhenever.py
@@ -32,7 +32,7 @@
# - It saves some overhead
from __future__ import annotations
-__version__ = "0.6.2"
+__version__ = "0.6.3"
import enum
import re