Upgrade to release 4.67.1:
- Preserve ignore (-) and invert (!) exit code prefixes on commands
when referenced via TOML { replace = "ref", ... }.
- Installing from a pylock.toml with no dependency_groups selected
now uses the lock file's default-groups, as 751 specifies.
Previously packages marked 'default' in dependency_groups (as
written by pdm export -f pylock) were skipped - by
pcbeingused333.
- A positional {factor:N} label in an env_base now resolves against
that table's own factors, so with several env_base tables or an
env_list product it no longer expands to an empty string.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 6.6:
- Python 3.15 is now supported. Python 3.9 and 3.10 are no longer
supported; 3.11 is the minimum supported version.
- Free-threaded python interpreters are now supported; prebuilt
wheels are available for 3.14t and 3.15t.
- Windows on ARM is now supported and prebuilt wheels are available.
- Prebuilt wheels are now available for riscv64, ppc64le, and s390x
architectures on Linux. These architectures are experimental and
have limited support and testing.
- PyPy 8.0 is now supported (for both Python 3.11 and 3.12).
- Error messages have been improved in many places.
- Improved handling of asyncio.CancelledError in various parts of
the framework.
- New feature cross_origin_protection provides a new mechanism for
protecting against XSRF and other cross-origin attacks. This
feature is easier to use than xsrf_cookies and is expected to
become the default in Tornado 6.7.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 1.2.0:
- Support Python 3.15
- Add signature for frozendict
- Support Python 3.15 and refresh dev tooling
- Add more tests for merge, get_in, and dissoc
- Expose combined __annotations__ on composed functions
- Fix interpose([]) raising StopIteration
- Add pysentry-pre-commit
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.5.0:
- Binary wheels for Python 3.15
- Set nested inline array/table limit to 400 to fix mypyc generated
binaries crashing unrecoverably in constrained environments (e.g.
worker thread in a python:3.13-alpine image)
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.3.2:
Security:
- A long run of digits in the arguments of a path arc command (A or
a) could make parsing take exponential time, so a tiny SVG could
block a process for minutes or longer (CWE-1333, CWE-400,
GHSA-249c-7rgc-f52h). Arc arguments are now read one token at a
time, without regex backtracking. Parsing of a malformed arc
stops at the first argument that does not fit.
Fixed:
- Accept explicit plus signs on arc rotation and endpoints, and
tab, carriage return and line feed separators in transform
arguments, as allowed by SVG.
- svg2rlg() no longer unpacks a .svgz file to a sibling .svg file,
which overwrote an existing file of that name and then deleted
it. The compressed data is now read as a stream.
- A <use> that refers to itself, or to a cycle of elements that
each <use> the next one, no longer crashes with RecursionError.
The offending <use> is skipped and an error is logged, as already
done for cyclic references between external files.
Extend RDEPENDS with the runtime dependency python3-reportlab.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.0.4:
- FIX: Keep own and descendant text separate when combining
:-soup-contains() and :-soup-contains-own().
- FIX: Cache resolved directionality when matching :dir() to avoid
quadratic time on deeply nested dir="auto" elements.
- FIX: Fix auto handling in regard to :dir() selector. When an
element with dir="auto" (or a <bdi>) contains no strong direction
characters, it should be assumed as left-to-right and not assume
the direction of the parent.
- FIX: Match numeric input ranges correctly when values or bounds
use scientific notation.
- FIX: Fix :in-range and :out-of-range raising ValueError for week
inputs whose week-year is 10000 or greater.
- FIX: Fix :nth-last-child(an+b of S) matching the wrong elements
when the first sibling tested does not match S.
- FIX: escape() now only leaves non-ASCII identifier code points
unescaped, as defined by the CSS specification. All other
non-ASCII characters are escaped.
- FIX: Allow unescaped U+0080 - U+009F characters in identifiers to
match browser behavior.
- FIX: Fix :in-range and :out-of-range treating time and
datetime-local values with seconds as invalid.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 4.4:
- Install in the defined prefix
- Use setuptools instead of distutils
License-Update: Check from line 1 to 13. License remains the same.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 4.2.0:
- Start building CPython 3.15 wheels
- Use the first-key error message in the C scanner
- Support large integer stringification thresholds in both encoders
- Check circular references introduced by custom JSON methods
- ci: build and test riscv64 wheels
- Prep for v4.2.0 - Update CHANGES and build matrix
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.2.0:
Features:
- Added support for dynamic-metadata 0.4+ through the
setuptools_git_versioning.dynamic_metadata provider.
This enables automatic versioning with scikit-build-core 1.0+
and other compatible backends.
- Added new prefer_tag: bool = False option for
:ref:version-file-option.
Deprecation:
- Deprecated the setuptools_git_versioning.scikit_metadata
provider.
Migrate to [[tool.dynamic-metadata]] with provider =
"setuptools_git_versioning.dynamic_metadata" on scikit-build-core
1.0+ or another compatible backend.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.73.0:
New Features:
- (arq) Add an option to monitor arq cron jobs
- (huey) Add an option to monitor Huey periodic tasks
- (rq) Add an option to monitor rq-scheduler jobs
- (types) Export Attributes from the public types module
Bug Fixes:
- (arq) Don't monitor cron jobs with unsupported schedules
- (attributes) Handle special float values correctly
- (celery) Don't round down beat schedule intervals
- (cohere) Stop swallowing exceptions during stream iteration
- (huggingface_hub) Stop swallowing exceptions during stream
iteration
- Exclude litellm==1.107.0 from extras
Other:
- (litellm) Require filelock>=4.0.3 on Python 3.10/3.11
- (monitor) Stop background health checks in tests that drive the
monitor
- Update AGENTS.md
- Update test matrix with new releases (10/12)
Extend RDEPENDS with the runtime dependency python3-certifi.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.1.0:
- Remove duplicate code Version.bump_build
- Improve bump_prerelease to alway get a newer version
- 441 update pydantic section of docs
- Remove Python 3.7-3.9 (EOL)
- fix: replace semver.parse() with semver.Version.parse() in
docstrings
- fix: next_version should bump version for build-only versions
- fix(next_version): reset prerelease when token changes
- Declare support for Python 3.15
- Add optional native parser backend (minimal adapter)
- Reject non-ASCII digits and trailing newlines in version parsing
- Fix bump_build() silently returning an unchanged version for
digitless build metadata
- Handle malformed collection operands in Version comparisons
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 7.5:
Robot Framework 7.5 is a new feature release with major enhancements to
the library documentation tool Libdoc, support for test/task metadata,
enhanced console logging configuration and several other enhancements
and bug fixes.
For more details, see the full release notes.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 5.1.0:
- Allow for bool values in rl_config.py
- Fix some file issues and download afmfer in setup.py
- Special case ListFloables in PTOContainer
- Require 3.10 at least (3.9 is now EOL)
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2026.9.29:
- Updated to Unicode 18.0.0.
- Switched to using stdbool.h and stdint.h.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2026.5:
- Add Python 3.14 to test suite
- IANA 2026e
- Add Order in Council for Manitoba’s change
- Fix misuse of America/Edmonton in example
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.17.0:
- Failures of mock assertions such as assert_called_with are
again reported only once, instead of two or three times with the
original error from the mock module chained before them.
- Mock assertion failures no longer show misleading
introspection when they are not about the arguments of the last
call: assert_called, assert_called_once, assert_not_called,
assert_any_call, their await counterparts, and
assert_called_once_with/assert_awaited_once_with when the mock
was not called (awaited) exactly once. The introspection also no
longer reports arguments passed by position versus by keyword as
different for autospecced mocks, and no longer shows empty
Args:/Kwargs: sections when assertion rewriting is not available.
- assert_has_calls and assert_has_awaits failures no longer show
pytest introspection, which compared the expected and actual
calls position by position and so reported differences between
unrelated calls. The mock's own message, listing the expected
and actual calls, is still shown.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 1.4.1:
Added:
- Declared support for Python 3.15
Fixed:
- Allow *AsyncIterable* as a return type for asynchronous generator
fixtures decorated with *pytest_asyncio.fixture*
Notes for Downstream Packagers:
- Source-tree development dependencies now use PEP 735 dependency
groups and uv.lock.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.6.0:
Breaking changes:
Check these before upgrading from 2.5.4. Details follow under Changes.
- Requirements: Python 3.10 or later; building from source needs
setuptools 77 or later. The test and docs extras are replaced by
dependency groups, so pip install pyrad[test] no longer installs
pytest.
- Packets on the wire change:
- Access-Request and Status-Server packets of Client and
ClientAsync, and replies to them built with CreateReply(),
carry a Message-Authenticator as first attribute; it shows up
in keys(). Pass message_authenticator=False to leave it out.
- Status-Server packets built with AcctPacket get a random
Request Authenticator and a Message-Authenticator, as RFC 5997
requires, instead of an Accounting-Request style authenticator.
AcctPacket.VerifyAcctRequest() verifies the
Message-Authenticator of Status-Server packets and fails
without one, so code that calls it on Status-Server packets
doesn't accept those of pyrad 2.5.4 clients, and pyrad 2.5.4
doesn't accept those of this version. The pyrad servers don't
answer Status-Server, and Status-Server on the authentication
port is not affected.
- CreateReply() copies the Proxy-State attributes of the request.
A handler that copies them itself sends them twice, and the
client rejects that reply.
- An untagged Tunnel-Password, and an untagged value of a tagged
string attribute starting with an octet up to 0x1F, are sent
with the tag 0 (RFC 2868). Tunnel-Passwords without tag from
pyrad 2.5.4 are still decoded.
- Packets that were accepted before are dropped:
- Servers verify the Request Authenticator of Accounting-, CoA-
and Disconnect-Requests (the Twisted integration:
Accounting-Requests) by default (enable_pkt_verify=True).
Clients whose secret doesn't match, e.g. accepted with a
catch-all 0.0.0.0 hosts entry, are no longer served; pass
enable_pkt_verify=False to accept them.
- Servers drop Access-Requests with an invalid
Message-Authenticator; this cannot be disabled. In ServerAsync
enable_pkt_verify no longer affects Access-Requests.
- Clients discard replies with an invalid Message-Authenticator
or with a Proxy-State the request didn't have, so the request
times out.
- enforce_ma of the clients now requires a Message-Authenticator
in replies to Access-Request and Status-Server; it no longer
adds one to requests (that is the default now).
- The blocking Server no longer passes Accounting-Response
packets on the accounting port to HandleAcctPacket.
- A Vendor-Specific attribute containing a malformed vendor TLV
makes the whole packet invalid (PacketError).
- Attribute values read from packets change:
- Tagged attributes (RFC 2868): pkt['Tunnel-Type'] returns the
values, e.g. ['L2TP'] instead of 16777219 with the tag in the
high octet, and the tag is stripped from string values. A
received string value of a tagged attribute starting with an
octet up to 0x1F is read as tag and value (RFC 2868).
- Values of string attributes that are not valid UTF-8 are
returned as bytes instead of str with replacement characters.
This applies to every string attribute (e.g. a Latin-1
Calling-Station-Id), not only User-Password.
- Undefined TLV sub-attributes are returned keyed by their code
instead of raising KeyError. A Vendor-Specific attribute whose
sub-attribute lengths don't add up is kept as raw value of
attribute 26.
- pkt['Name'] = value, pkt['Name'], in and del of a TLV
sub-attribute use its TLV instead of a top-level attribute with
the sub-attribute's code.
- PwCrypt('') returns 16 octets instead of none.
- Exception types change:
- Values out of range or too long for their type or attribute
raise ValueError instead of struct.error, which is not a
subclass of ValueError.
- Dictionary errors raise ParseError instead of ValueError,
TypeError, KeyError or struct.error. ParseError is not a
subclass of ValueError.
- AddAttribute with a key that is not a name raises TypeError
instead of AttributeError. PwDecrypt and SaltDecrypt of a value
with a wrong length raise PacketError.
- Decoding a value with the wrong length (e.g. integer, ipaddr,
ipv6prefix) raises ValueError instead of struct.error or
returning a wrong value.
- ipaddr attributes reject IPv6 addresses, and strings longer
than 253 octets in UTF-8 are rejected.
- Dictionaries:
- Attributes pyrad cannot encode correctly are skipped with a
warning instead of being loaded: vendors with a format other
than 1,1 (e.g. USR, Lucent, Starent, WiMAX, Kineto,
Alcatel-ESAM), nested TLVs (also TLV-typed sub-attributes,
which loaded before), arrays (also those with has_tag or
encrypt, which loaded before) and others. Code using them gets
KeyError; see Dictionary.skipped_attributes.
- A sub-attribute of a TLV of another vendor makes the dictionary
fail to load with ParseError instead of being attached to the
wrong TLV.
- Reading a dictionary that skips attributes logs a warning on
the pyrad logger.
- Servers and clients:
- Client with auth_type='eap-md5': the EAP-Identity is the
User-Name instead of the User-Password, the User-Password is
not sent, and a request without User-Name or User-Password
raises ValueError instead of using the User-Name as password.
- The reply to a Disconnect-Request created with CreateReply() or
CreateReplyPacket() is a Disconnect-ACK instead of a CoA-ACK; a
handler that sets reply.code is not affected.
- An exception raised by a handler of the blocking Server or
Proxy is logged and the packet dropped; it no longer stops
Run().
- Proxy passes Access-Challenge, CoA-ACK/NAK and
Disconnect-ACK/NAK replies on the proxy socket to
_HandleProxyPacket instead of dropping them.
- Twisted integration: the RADIUS constructor takes (hosts=None,
dict=None, enforce_ma=False, enable_pkt_verify=True), hosts
must map addresses to RemoteHost instances or secrets, and an
overridden createPacket is called.
- ClientAsync: requests pending when the transport is closed fail
with ConnectionAbortedError (a request nobody awaits logs
"Future exception was never retrieved"); retransmissions send
the bytes of the first attempt, so changes to the packet after
SendPacket are not sent; a request is retried only after
timeout seconds, so a request times out after (retries + 1) *
timeout seconds; CreatePacket raises if all 256 ids are in use
(the Create*Packet methods raise Exception).
- ClientAsync and ServerAsync: loop is a property. Without a loop
passed to the constructor it returns the running loop at the
time it is used.
Changes:
- BlastRADIUS (CVE-2024-3596) countermeasures (#200):
- Clients add a Message-Authenticator to all Access-Request and
Status-Server packets by default.
- Clients always verify a Message-Authenticator in replies
(enforce_ma verified the request instead) and discard replies
with unexpected Proxy-State attributes.
- Servers add a Message-Authenticator to all replies to
Access-Requests, verify it in received Access-Requests and can
require it with the new enforce_ma option.
- Message-Authenticator is added as first attribute and
verification uses the correct authenticator for received
replies, including CoA/Disconnect ACK/NAK and replies to
Status-Server.
- With enforce_ma, clients require a Message-Authenticator in
replies to Access-Request and Status-Server packets.
- The FreeRADIUS dictionary files can be read as they are (#173).
Attributes that pyrad does not support, such as the RFC 6929
extended attributes, attributes of the types vsa, ipv4prefix,
combo-ip, bool, uint16 and uint32, arrays, nested TLVs and
attributes of vendors with a format other than format=1,1 (e.g.
USR, Lucent, Starent, WiMAX, Kineto, Alcatel-ESAM), which pyrad
encoded as format=1,1 before, are skipped with a warning and
listed in Dictionary.skipped_attributes. The flags secret and
virtual and BEGIN-VENDOR with a format= option are accepted.
Attributes with the concat flag, such as EAP-Message, are loaded
as normal attributes instead of being dropped. A VALUE for an
unknown attribute is ignored with a warning instead of raising a
ParseError, and a sub-attribute of an unknown TLV raises a
ParseError instead of a KeyError.
- Fix salt decryption (encrypt=2, e.g. Tunnel-Password) of received
Accounting-, CoA- and Disconnect-Requests, which used the Request
Authenticator instead of zeros, and salt encryption of these
requests after RequestPacket() was called. An Access-Request with
salt encrypted attributes got an all-zero Request Authenticator,
so the User-Password encryption was the same in every request; it
gets a random one now.
- Fix crashes on malformed or unusual packets: a vendor TLV that
was not the first sub-attribute of a Vendor-Specific attribute,
or that appeared in more than one, raised AttributeError while
decoding, which stopped the blocking server with a single
unauthenticated packet. An empty TLV made VerifyReply raise
ValueError instead of rejecting a forged reply, and reading a TLV
with an undefined sub-attribute raised KeyError (undefined
sub-attributes are returned as raw values keyed by their code
now). PwDecrypt raises PacketError for a password that is not a
multiple of 16 octets instead of IndexError.
- The blocking Server (and Proxy) drops and logs packets for which
a handler raises an exception, instead of stopping the main loop,
like ServerAsync does. Unexpected exceptions while decoding a
packet are treated as a broken packet.
- ClientAsync: a request cancelled by the caller, e.g. with
asyncio.wait_for, or a failing retransmission killed the timeout
handler, so no later request on that transport was retried or
timed out and they waited forever. A packet that could not be
encoded was left pending and killed the timeout handler when it
expired. Requests that are still pending when the transport is
closed fail with ConnectionAbortedError instead of waiting
forever.
- ClientAsync and ServerAsync created without a loop use the
running event loop instead of calling asyncio.get_event_loop() in
the constructor, which fails outside of a running loop on Python
3.14. loop is a property that returns the running loop when it is
used.
- Client:
- Timeouts use a monotonic clock, so a step of the system clock
no longer extends the wait for a reply.
- A late reply to an earlier attempt of an Accounting-Request,
whose Request Authenticator changed with Acct-Delay-Time, is
accepted instead of timing out. Retrying an Accounting-Request
no longer fails with KeyError if the dictionary has no
Acct-Delay-Time.
- The EAP-MD5 challenge response only hashes the Value of the
challenge, so challenges with a Name work, and the
Access-Request answering the Access-Challenge has a new
Identifier and Request Authenticator (RFC 2865 section 4.4).
- EAP-MD5 works with FreeRADIUS: the EAP-Identity is the
User-Name instead of the password, which was sent in clear
(#151), and the cleartext User-Password is only used for the
MD5 response instead of being sent in clear with the
EAP-Message, which RFC 3579 section 3.3 doesn't allow.
Challenges without State, EAP packets split over several
EAP-Message attributes and challenges of other EAP types (which
are returned) are handled. An EAP-Identity longer than one
attribute is split over several EAP-Message attributes.
- ClientAsync authenticates with EAP-MD5 like Client for packets
with auth_type='eap-md5'; it sent them as they were, with the
cleartext User-Password and without answering the challenge.
- A Client without a dictionary can send Access-Requests again.
- ClientAsync and ServerAsync:
- initialize_transports can be retried after a transport failed
to open (e.g. a DNS or bind error) or the call was cancelled
(e.g. by asyncio.wait_for); the failed or closed transport
stayed registered.
- ClientAsync doesn't hand out the id of a pending request, so
more than 256 requests over time no longer fail with "Packet
with id N already present"; it raises only if all 256 ids are
in use. CreatePacket accepts the id 0.
- ClientAsync timeouts use a monotonic clock, and the dates in
pending_requests are time.monotonic() values.
- ClientAsync retransmits the bytes encoded for the first attempt
instead of encoding the packet again.
- Transports are opened on platforms without SO_REUSEPORT (e.g.
Windows), and ClientAsync binds to local_addr also without a
local port.
- The ClientAsync retries documentation is corrected (a request
is sent up to retries + 1 times) and the asyncio examples work
on Python 3.14.
- Servers and Proxy:
- IPv4 clients of a dual stack server bound to '::' (source
::ffff:a.b.c.d) are matched against their IPv4 hosts entry, in
Server, Proxy, ServerAsync and the Twisted integration.
- Proxy accepts Access-Challenge, CoA-ACK/NAK and
Disconnect-ACK/NAK replies on the proxy socket instead of
dropping them.
- Twisted integration (pyrad.curved): packets are decoded with
the packet class of RADIUSAccess/RADIUSAccounting (an
overridden createPacket that returns None gets a generic
packet) and get the client's secret, the Message-Authenticator
of Access-Requests (BlastRADIUS) and the Request Authenticator
of Accounting-Requests are verified (new enforce_ma and
enable_pkt_verify arguments), and the default hosts and
dictionary are no longer shared between instances. The hosts
must map to RemoteHost instances or to the secrets; packets of
hosts without a secret, e.g. given as a set or list of
addresses, are dropped and logged.
- Twisted integration: exceptions raised by packet handlers
(including pyrad.packet.PacketError and ServerPacketError) or
by createPacket are now dropped and logged, like in Server.Run
and ServerAsync. Packets that fail to decode are logged with
one line, without a traceback.
- Packets:
- Received packets longer than their Length field are accepted,
the extra octets are ignored as padding (RFC 2865 section 3).
- VerifyReply(reply) without rawreply verifies a received reply
with the bytes it was decoded from, instead of rejecting and
modifying it.
- PwCrypt encrypts an empty password as 16 octets and raises
ValueError for passwords longer than 128 octets (RFC 2865
section 5.2).
- Values too long for an attribute, a Vendor-Specific or TLV
wrapper or salt encryption raise ValueError instead of
struct.error, and a TLV whose first sub-attributes are long is
no longer preceded by an empty TLV.
- Setting a TLV sub-attribute with pkt['Name'] = value stores it
in its TLV; it was sent as a top-level attribute with the
sub-attribute's code. Getting, testing (in) and deleting a
sub-attribute by name use its TLV as well, instead of a
top-level attribute with the same code.
- VerifyChapPasswd returns False without CHAP-Password instead of
raising TypeError, and compares in constant time.
- Status-Server built with AcctPacket gets a random Request
Authenticator and a valid Message-Authenticator, and replies to
it are signed with its Request Authenticator (RFC 5997).
VerifyAcctRequest verifies the Message-Authenticator of
Status-Server packets.
- A packet created without a dictionary has dict set to None
(unless its class defines one), so CreateReply() of such a
received packet works.
- The VerifyAuthRequest documentation says what it checks.
- Attribute values:
- ipaddr values reject IPv6 addresses with ValueError instead of
encoding 16 octets (RFC 8044 section 3.8).
- The 253 octet limit of string values is checked on the UTF-8
encoded value.
- ipv6prefix values given as netaddr.IPNetwork clear the host
bits and reject IPv4 networks, like str values.
- Out of range integer, signed, short, byte, integer64 and date
values raise ValueError instead of struct.error.
- Ascend binary filters raise ValueError if an address doesn't
match the filter family instead of producing a malformed
filter, and terms may be separated by any whitespace.
- The ifid (e.g. Framed-Interface-Id, RFC 3162) and ether types
can be encoded and decoded.
- Dictionaries:
- TLV sub-attributes are no longer attached to a TLV with the
same code of another vendor (the dictionary fails to load with
ParseError), and TLVs defined in one dictionary file are found
by sub-attributes in another.
- Malformed attribute codes, vendor codes and VALUE definitions
raise ParseError with file and line instead of ValueError,
TypeError or struct.error. VALUE definitions for date
attributes work.
- A dictionary file that includes itself raises ParseError
instead of looping forever, and the FreeRADIUS $INCLUDE-
directive (include if the file exists) is supported.
- A redefined attribute or value name is no longer decoded to its
old name (stale BiDict reverse entries). Deleting a BiDict
value removes all keys mapping to it, and deleting one of
several keys of a value keeps the reverse entry of the others.
- The package metadata declares the license as the SPDX expression
BSD-3-Clause (PEP 639); building requires setuptools 77 or later.
The test and docs extras are replaced by the dependency groups of
the same names (uv sync --all-groups or pip install --group
test).
- The FreeRADIUS dictionary of the examples is an attributed
excerpt of the current FreeRADIUS dictionary (CC-BY 4.0), and
names attribute 182 FreeRADIUS-Queue-PPS-Out instead of
FreeRADIUS-Queue-PPS-In.
- Fix an infinite loop when decoding a vendor-specific or TLV
sub-attribute with a length of 0, which let a single
unauthenticated packet hang a server (#234). Truncated TLVs raise
a PacketError instead of struct.error.
- Fix salt decryption of values longer than 16 bytes, such as
MS-MPPE-Send-Key, MS-MPPE-Recv-Key and long Tunnel-Passwords.
- Fix PwDecrypt of the decoded User-Password attribute, which
failed since 2.5 because invalid UTF-8 was decoded with
replacement characters (#232, #192). Values of all string
attributes that are not valid UTF-8 are returned as bytes now.
- Fix ServerAsync dropping all Access-Requests with
enable_pkt_verify=True (#178). enable_pkt_verify no longer
applies to Access-Requests, whose Message-Authenticator is always
verified.
- Fix decoding of tagged attributes (RFC 2868). The tag is stripped
from the values, pkt['Tunnel-Type'] returns the values of all
tags and pkt['Tunnel-Type:1'] the values with tag 1. Decoding a
tagged Tunnel-Password no longer fails, and an untagged
Tunnel-Password is sent with the mandatory tag 0. A
Tunnel-Password without tag, as sent by older pyrad versions, is
still decoded. An untagged string value starting with an octet up
to 0x1F is sent with the tag 0, so that it isn't read as tag.
- Fix ClientAsync decrypting salt encrypted reply attributes, such
as Tunnel-Password and MS-MPPE-Send-Key, with the wrong
authenticator.
- Copy Proxy-State attributes into replies (RFC 2865 section 5.33).
- Decoding an integer, signed, short, byte, date, integer64, ipaddr
or ipv6prefix attribute with a value of the wrong length, or an
ipv6addr attribute with a value longer than 16 octets, raises a
ValueError instead of struct.error or returning a wrong value,
such as an IPv6 address for a 16 byte ipaddr value (#13). Shorter
ipv6addr values are still padded with zeros.
- Replies to Disconnect-Requests created with CreateReply() or the
CreateReplyPacket() of the servers are Disconnect-ACKs instead of
CoA-ACKs (RFC 5176 section 3).
- Fix Host.SendPacket(fd, pkt), which called the missing method
pkt.Packet() and always raised AttributeError; it sends
pkt.RequestPacket() to pkt.source.
- AddAttribute raises a TypeError with a clear message when the key
is not an attribute name, e.g. when the key and value arguments
are swapped (#17).
- Fix encoding of binary octets values starting with b"0x", such as
a CHAP-Password with CHAP ID 48, which failed with "Odd-length
string" or "Non-hexadecimal digit found". Bytes values are only
decoded as hex if the rest of the value is valid hex (#49).
- Fix the length of CoA and Disconnect requests with
Message-Authenticator.
- Fix ClientAsync retrying and timing out requests before the
timeout passed.
- Verify the request authenticator of Accounting, CoA and
Disconnect requests by default. The blocking Server never
verified them and ServerAsync only with enable_pkt_verify=True;
both now default to verification and can opt out with
enable_pkt_verify=False. Server no longer accepts
Accounting-Response packets on the accounting port.
- Drop support for Python 3.8 and 3.9, which are end of life; pyrad
requires Python 3.10 or later.
- Replace deprecated datetime.utcnow() and Logger.warn calls in the
asyncio client and server.
- Fix the examples in the README, the docs and the package
docstring.
- Add a usage guide to the documentation (attributes, tagged and
encrypted attributes, accounting, CoA, Status-Server, EAP-MD5,
servers, asyncio, errors and logging, Proxy and Twisted) and the
API documentation of ClientAsync, ServerAsync, the Twisted
integration and the dictionary Attribute and BiDict classes. The
API documentation shows the constructor parameters, and the
docstrings were corrected and completed (e.g. retries, default
reply codes, what servers verify before calling a handler,
ServerAsync handlers must not be coroutines).
- The dictionary parse error for an attribute definition with a
wrong number of fields now includes the file name.
- Fix wrong and missing parameter types and descriptions in the
docstrings (secrets and raw packets are bytes, AddAttribute only
takes attribute names) and document the asyncio transport and
handler methods.
License-Update: Copyright years and authors updated
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 1.2.3:
- Restored the ability to import
pymysql.converters.escape_bytes_prefixed for compatibility
with aiomysql.
- Use pymysql.converters at your own risk. It's internal functions.
No backward compatibility are guaranteed.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 4.19.0:
- Added support for Python 3.15.
- Dropped support for Python 3.9 and 3.10.
- Removed support for PyPy.
- Removed the deprecated Algorithm.RANGEPREVIEW and
QueryType.RANGEPREVIEW members (PYTHON-6009).
- Added support for running the synchronous and asynchronous
clients in subinterpreters, including inside
concurrent.futures.InterpreterPoolExecutor (Python 3.14+). Only
in subinterpreters, which do not allow daemon threads, the
synchronous client's monitor threads now start as non-daemon
threads and are stopped and joined when the interpreter is torn
down. Monitor threads in the main interpreter remain daemon
threads and shutdown behavior is unchanged. Note that because
these threads are non-daemon, a subinterpreter may block on
teardown until any in-flight monitor work completes.
- Added support for routing Key Management Service (KMS) requests
for Client-Side Field Level Encryption and Queryable Encryption
through an HTTP proxy, using the new kms_connect_callback option
on AutoEncryptionOpts, ClientEncryption, and AsyncClientEncryption.
The callback opens the connection and the driver performs the KMS
TLS handshake over it, so verification still targets the KMS host
rather than the proxy. For an ordinary HTTP proxy, pass
HTTPProxyKMSConnect or AsyncHTTPProxyKMSConnect instead of writing
a callback. Both helpers accept custom CONNECT headers, e.g.
Proxy-Authorization for proxies that require authentication.
- Added the srv_host_validator keyword argument to MongoClient and
AsyncMongoClient, an alternative to srvAllowedHostsSuffix for
deployments whose acceptable SRV hosts cannot be expressed as a
single suffix. The callback is invoked once per SRV-returned host
and must return a boolean: True to accept the host and False to
reject it. During initial DNS discovery a non-boolean return
raises an error; during SRV polling it is treated as a rejection.
It is mutually exclusive with srvAllowedHostsSuffix and, because
it takes a callable, cannot be set in a connection string. See
the MongoClient and AsyncMongoClient documentation for security
considerations.
- srvAllowedHostsSuffix may now be set to a single label reserved
for private or special use, such as localhost, test, or internal.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.15.1:
- Accept trailing Base64URL = padding when decoding JWS segments,
so tokens issued by AWS ALB and similar systems verify instead of
raising DecodeError: Invalid crypto padding. Non-alphabet junk
such as !!!! remains rejected
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 16.0.0:
- BREAKING: Use the Self type introduced in Python 3.11
Error handling improvements:
- Avoid logging callback failures when queued executor handlers
are canceled
Documentation improvements:
- Add Args, Returns and Raises sections to public docstrings
- AGENTS.md file for AI coding assistant guidance
Local development changes:
- Type check with both pyright and mypy by default
- Remove tox test matrix, leaning on Github Actions
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 7.48.0:
- Expose more CURLOPT_SSL_OPTIONS (patch by Scott Talbert)
- Read long description from README.rst instead of duplicating it
in setup.py (patch by Scott Talbert)
- Fix test_redir_protocols_setopt (patch by Scott Talbert)
- Add CURL_LOCK_DATA_HSTS as a CurlShare option (patch by Scott
Talbert)
- Add libpsl support to vcpkg installs for CI and wheel builds
(patch by Scott Talbert)
- Configure nuget repo access as read-only from PRs (patch by Scott
Talbert)
- Officially change project URL to https://pycurl.github.io/ (patch
by Scott Talbert)
- Replace bare except clauses in examples with specific exception
types (patch by Kotesh Kumar Yelamati)
- Add HTTP/3 support in libcurl wheel (patch by Will Noble)
- Fix segfault when calling duphandle() on a closed Curl handle
(patch by Jorge Rocamora)
- Fix abort on non-text string arguments (patch by Jorge Rocamora)
- Fix CurlShare leak when close() detaches attached handles (patch
by Jorge Rocamora)
- Document that views derived from the callback memoryview are not
released (patch by Jorge Rocamora)
- Fix crash when duplicating a handle that uses set_ca_certs()
(patch by Jorge Rocamora)
- Add CurlUrl object wrapping libcurl's URL API, with CURLOPT_CURLU
support (patch by Jorge Rocamora)
- Fix callback exceptions being replaced by SystemError (patch by
Jorge Rocamora)
- Fix test guard silently passing on real libcurl errors (patch by
Jorge Rocamora)
- Update the docstring and manifest source lists (patch by Jorge
Rocamora)
- Refuse pause() from a thread other than the performing one (patch
by Jorge Rocamora)
- Add support for Python 3.15 (patch by Scott Talbert)
- Refuse integers for blob options instead of crashing (patch by
Jorge Rocamora)
- Accept buffer objects for blob options (patch by Jorge Rocamora)
- Release all httppost encoded values and unset the form before
MIMEPOST (patch by Jorge Rocamora)
- Reject callback return values that do not fit in an int (patch by
Jorge Rocamora)
- Clear CurlMulti callbacks before deallocating attached handles
(patch by Eric Buehl)
- Serve the test apps from a threaded WSGI server (patch by Jorge
Rocamora)
- Add support for missing CURL options (patch by Khavish Anshudass
Bhundoo)
- Add CURLOPT_SSL_EC_CURVES & CURLOPT_SSL_SIGNATURE_ALGORITHMS
options (patch by Khavish Anshudass Bhundoo)
- Remove unused variable from do_curl_setopt_httppost (patch by
Scott Talbert)
- test: silence WSGI test server access logging to stderr (patch by
Scott Talbert)
- test: pin down oversized mime data_cb error assertions (patch by
Scott Talbert)
- Give vendored OpenSSL a private OPENSSLDIR on Linux manylinux
wheels (patch by Scott Talbert)
- Enable -Werror for the pycurl build in cibuildwheel without
affecting vcpkg (patch by Scott Talbert)
- Handle libcurl options deprecated in 8.22.0 (patch by Scott
Talbert)
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.15.0:
- Improve performance of module_imports_on_top_of_file.
- Improve performance of python_3000_invalid_escape_sequence.
- Improve performacne of missing_whitespace_after_keyword.
- Drop EOL python 3.9.
- Add support for python 3.15.
- Fix loading unrelated configuration due to commonprefix.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 7.36.2:
- Detects single-crate cross-file symbol collisions and
conditionally emits crate-root re-exports.
- Prepend the file module name to Rust type paths to use canonical
paths.
- Expose generated per-file Rust proto modules as public.
- Include .c files in the source_files glob in upb/port/BUILD
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.6.3:
- IntervalDict.update and __init__ behave like dict.update when the
provided intervals overlap (the last provided value wins).
- IntervalDict.pop accepts None as default value.
- Fix from_string accepting prefix (re.match) instead of full value
(re.fullmatch) for infinities.
- Documentation of iterate explicitly states that base should be
side-effect-free.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 1.22.4:
- Account for the capture groups %z adds to the generated pattern
- Reject out-of-range timezone minutes
- Document the extra_types conversion mapping
- Fix case-sensitive am/pm and Zulu conversion under
case-insensitive matching
- Resolve year-less strftime formats against the current year
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 2.17:
- Added support for DateTimePatternGenerator.getDefaultHourCycle()
and enums
- Added missing wrappers for UDateFormatField
- Added support for ICU 79.1
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.5.3:
- Close the storage connection before forking process workers, this
just simplifies things.
- Run the callback of an empty chord with an empty results list.
Previously it was never enqueued.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 4.3.1:
- Fix type-check failures with ty 0.0.87
- Exclude .DS_Store from release
- Route annotated command help through the application output
stream
- Add example embedding a cmd2 app in a Textual app with
textual-tty
- Add example embedding a cmd2 app in a Textual app with
textual-tty
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 7.2.5:
- Fix @cachedmethod with condition for decorated methods taking a
pending keyword argument (broken since v7.0.0).
- Fix pickling and deep-copying of instances using @cachedmethod
(broken since v7.0.0).
- Fix calling @cachedmethod decorated methods through the class
with the receiver (self) passed as a keyword argument (broken
since v7.2.4).
- Various documentation improvements.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 3.13.0:
- It is now possible to nest ThreadSensitiveContext by providing an
explicit executor for thread-sensitive tasks. This enables moving
a block of such work away from the parent context's shared worker.
The provided executor must run work sequentially and on a single
thread, as per ThreadPoolExecutor(max_workers=1), and the calling
code is responsible for managing the executor's lifecycle.
- Local attribute access is now 2-3x faster. Local(...) now uses one
of two internal specialisations, selected by thread_critical,
instead of checking the mode on every access.
As a result Local is now marked @final and raises TypeError if
subclassed. Subclassing was never supported, and could not have
worked correctly with the specialised implementations.
- asgiref.timeout.timeout is deprecated, and will be removed in a
future release. Move to use asyncio.timeout() instead.
- Added support for Python 3.15.
- Dropped support for EOL Python 3.10.
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
pyproject.toml specifies setuptools.build_meta as the build backend, so
inherit python_setuptools_build_meta instead of setuptools3.
Fixes:
QA Issue: inherits setuptools3 but has pyproject.toml specifying backend
setuptools.build_meta, use the correct class [pep517-backend]
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
- On the mini bar, an overlong filename gets properly clipped.
- The keypad operator keys produce their inscribed characters.
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>