v0.18.6
=======

- Support free-threaded CPython 3.14 (cp314t), and build wheels for it.
  Free-threaded servers handle requests concurrently, so registry objects
  (including C++ bindings, which the GIL otherwise keeps from running
  concurrently) must be thread-safe. For registry objects that aren't, run
  tuberd on a standard (GIL) Python build.

- Each call's server-side warnings are now emitted when the caller retrieves
  that call's result (or, for calls not retrieved one by one, their whole
  batch's): from the calling thread in the simple client, and from the
  awaiting task in the async client, so that they can be caught on
  free-threaded Python.

- Replace libhttpserver/libmicrohttpd with cpp-httplib, vendored as a single
  header in extern/. Building from source no longer needs any external HTTP
  dependency. The old libhttpserver API changed significantly with a 2.0
  release, and with the 1.x API marked EOL, some churn was already coming our
  way.

- Client objects no longer hold reference cycles, so a dropped client closes
  its HTTP connections as soon as it's no longer referenced, rather than at
  the next garbage collection. (Each idle keep-alive connection occupies one
  of tuberd's worker threads.) Simple client objects also gain a close()
  method, and can be used as context managers, to close their connection pool
  explicitly.

- Add ``tuber.server.Server``: construction binds the port, ``serve()`` runs
  until ``stop()`` is called from another thread (or SIGINT, on the main
  thread), and ``port`` reports the bound port. Port 0 selects a free port.
  ``run()`` and ``main()`` are now thin wrappers; ``parse_args()`` exposes the
  command-line parsing ``main()`` uses. The SIGINT handler is only installed
  when serving on the main thread, and Python's handler is restored on exit.

- Tests run the server in-process on a free port rather than spawning a
  tuberd on port 8080, so concurrent test runs (``ctest -j``) don't collide.

- The ``TUBER_SERVER`` environment variable is no longer set or consulted. It
  had no effect since the server moved to Python: ``import tuber`` doesn't
  need the client's optional dependencies, which are imported lazily.

- The server no longer caps request bodies (cpp-httplib's default was 100 MB,
  beyond which a request failed with an empty 413 or a broken connection).

- The synchronous client no longer runs charset detection over every response
  body, which made large responses take tens of seconds to receive.

- The server no longer loses a request's warnings when an overlapping request
  finishes first. Warnings were collected with warnings.catch_warnings(),
  whose process-wide save and restore breaks when requests finish out of
  order; a single hook now hands each warning to the request that raised it.
  Warning filters a registry method changes are no longer reverted when it
  returns.

- A request that fails now fails every call in it with its error, in both
  clients. Before, a request that failed in transit (e.g. by timing out, or
  with the connection refused) left all but the call whose result triggered
  it pending forever; and one that failed with an error from the server (an
  HTTP error status, or an unexpected content type) cancelled its calls,
  whose futures then raised CancelledError instead. Likewise, cancelling the
  future returned by a simple context's send() before the request starts
  cancels its calls' futures. send() now returns a RequestFuture, a
  concurrent.futures.Future whose result is the requests.Response, as
  before.

- Both clients now report an error response from the server with the same
  message, decoding its body as UTF-8 unless the response names a charset
  (the synchronous client no longer uses charset detection here either), and
  keeping undecodable bytes as replacement characters.

v0.18.5
=======

- Async Context: awaiting a queued call now flushes the context (everything
  queued so far, in order, as a single request) and returns that call's
  result. Previously this deadlocked, since nothing resolved the returned
  future until the context was flushed explicitly or on exit. The flush is
  shielded from cancellation so a timed-out awaiter (e.g. asyncio.wait_for)
  cannot strand other queued calls.

- Context result parsing now tolerates per-call futures that the caller has
  cancelled, instead of failing the whole batch with InvalidStateError.

v0.18.4
=======

Released 2026-05-19

- Allow HTTP timeout to be specified across the API (via TuberObject, tuber_context)
- Fix "self" argument in function signatures
- Add useful string __repr__  for TuberObjects

There are a few CI/CD chores included in this release as well.

v0.18.3
=======

Released 2025-09-02

New features:

- Added support for transparent gzip compression
Bug fixes:

- Pybind11 3.x fixes for str_enum

- tuberd: Unify simplejson/json/cbor treatment of bytes objects (simplejson
  encodes bytes using utf-8 by default, which doesn't match either of the other
  two encoders)

Distribution / CI / CD:

- CI/CD: Linux/x84 packages are now built natively

- tuberd: tests are no longer installed by default

- tuberd: Python requests, requests-futures are no longer pre-requisites

v0.18.2
=======

Released 2025-07-07

- Pass through trace-backs for server-side exceptions

v0.18.1
=======

Released 2025-06-26

- Fixes convert_json=False behaviour with SimpleTuberContext. (Fixes #3)

v0.18
=====

Released 2025-06-13

- Adds "convert_json" support to prevent dict results from being converted
  into TuberResult objects. This is an optional setting for those who prefer
  dict["like"]["APIs"] to the current object.like.API.

- Replaces the underlying "TuberResult" objects with SimpleNamespace objects.
  This is part of an ongoing effort to make the Tuber codebase less special
  where it doesn't need to be special.

- Python 3.8 support has been removed.

- When remote exceptions occur inside a chain of RPC calls in a Context,
  it's now possible to return them "in-band" (as list elements) rather than
  "out-of-band" (as an exception, which interrupts control flow). This is an
  optional setting and does not affect default behaviour.

- Mandate use of mDNS-capable resolver (either aiohttp_asyncmdnsresolver if
  available, falling back on ThreadedResolver.) aiohttp's DefaultResolver is
  AsyncResolver under some conditions (and that resolver doesn't support mDNS.)

v0.17
=====

Released 2024-12-13

Bug fixes:

- DocStrings and __signature__ metadata has been reworked. This fixes missing
  DocStrings and correctly attempts to tunnel signatures to Python clients.

v0.16
=====

Released 2024-09-13

- Adds "--validate" to tuberd invocation, which checks served data against a
  jsonschema. This is intended as a developer aid, NOT as a security feature
  (since it's only server-side, and not default!)

- Synchronous (SimpleTuberObject) and asynchronous (TuberObject) APIs are
  brought together using requests-futures package, and tested alongside each
  other.

- Server hotpath is now partly Python - this has very little performance cost
  and is much more maintainable.

- Libfmt dependency removed.

- Server-side container API added (allowing objects to host other objects)

v0.15
=====

Released 2024-08-20

- Fix enum class serialization. The str_enum helper now produces enum.Enum()
  classes in Python that are also str() subclasses. For all 3 serializers we
  use (json, orjson, cbor2) this is enough to correctly serialize enum classes.

v0.14
=====

Released 2024-08-08

- CI/CD improvements: builds wheels for manylinux and OS X

v0.13
=====

Released 2024-05-29

- A "simple" (non-asyncio) client now lives alongside the asyncio client. The
  points of entry for these are "resolve" and "resolve_simple". They are
  approximately API-compatible, but the non-asyncio version entirely avoids
  async code style (async def / await / ...).

- Multiple calls (using a Context or SimpleContext) can now optionally continue
  after errors, using the continue_on_error flag. When this is True, all calls
  in a Context/SimpleContext run to completion even if some of them fail.
  The default behaviour remains the same - when continue_on_error is False,
  server-side execution proceeds in sequence and halts at the first call that
  encounters an error.

v0.12
=====

Released 2024-04-22

- Headers are now properly included in binary builds (.whl files)
- Corrected PYTHONPATH for "make test"; broken in 0.11.

v0.11
=====

Released 2024-04-22

- resolve now required (20)
- tuber package rearranged to tuber.server / tuber.client; registry moved to server (#19)
- linter (black) added to CI/CD flow (#17)
- client-side Python packages (aiohttpd) no longer required in server environment (#18)
- setuptools now builds client and server (#14)

v0.10
=====

Released 2024-04-16

- Adds support for CBOR as a transport mechanism.

v0.9
====

Released 2024-02-21

- Removes dependency on boost::program_options in favour of getoptA
- Compatibility fixes for libfmt, libhttpserver, OS X, Clang

v0.8
====

Released 2024-01-29

- Compatibility fix for libfmt

v0.7
====

Released 2023-12-11

* New features:

  - Added support for warnings.warn calls in server-side code - these are
    propagated through a "warnings" field in the result object and bubbled up
    as client-side warnings.

v0.6
====

Released 2023-02-24

* Fixes:

  - Acquire GIL earlier in response scope, outside "try" block.  Otherwise, the
    exception path occurs outside the GIL block, and it's not valid to use
    json_dumps to emit error messages. Fixes a segfault when invalid JSON is
    supplied.

v0.5
====

Released 2022-05-24

* Fixes:

  - Correct preamble install path.

v0.4
====

Released 2022-04-14

* Features:

  - Adds --orjson-with-numpy extension to enable orjson fast-path. This
    serializer offers significant performance gains, especially when using
    numpy objects.

v0.3
====

Released 2022-04-07

* Features:

  - Adds option for use of user-specified JSON module.

v0.2
====

Released 2022-04-06

* Features:

  - Removes dependency on nlohmann::json. The JSON dependency is intended to
    speed up serialization. The Python-native JSON serializer is implemented in
    C under the hood, and should be better able to avoid casual
    copy-conversions of arguments and results.

  - Adds Python test framework. The test framework is a starting point (it does not exercise unhappy
    paths or argument variations right now.)

v0.1
====

Released 2022-04-03

* Features:

   - Initial release.
