Skip to content

Commit 17a6478

Browse files
committed
Release 2.0.1
* Fix: for trace configuration. * Fix: issues with `_decompose`. * Fix: Signature match in `.eventsocket`.
1 parent ae1e4f2 commit 17a6478

File tree

6 files changed

+46
-36
lines changed

6 files changed

+46
-36
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [2.0.1] - 2025-06-02
8+
9+
### Fixed
10+
11+
- Issue with trace configuration.
12+
- Issues with `_decompose`.
13+
- Signature match in `eventsocket`.
14+
715
## [2.0.0] - 2025-04-30
816

917
### Added

docs/changelog.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
Changelog
33
#########
44

5+
Version 2.0.1
6+
=============
7+
8+
* Fix: for trace configuration.
9+
* Fix: issues with `_decompose`.
10+
* Fix: Signature match in `.eventsocket`.
11+
512
Version 2.0.0
613
=============
714

src/firebird/base/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# SPDX-FileCopyrightText: 2020-present The Firebird Projects <www.firebirdsql.org>
22
#
33
# SPDX-License-Identifier: MIT
4-
__version__ = "2.0.0"
4+
__version__ = "2.0.1"

src/firebird/base/config.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,32 +148,25 @@ def _eq(a: Any, b: Any) -> bool:
148148

149149
# --- Internal helpers for FlagOption copied from stdlib enum (pre-Python 3.11) ---
150150
def _decompose(flag, value):
151-
"Extract all members from the value (internal helper for FlagOption)."
151+
"""Extract all members from the value.
152+
"""
152153
# _decompose is only called if the value is not named
153154
not_covered = value
154155
negative = value < 0
155-
# issue29167: wrap accesses to _value2member_map_ in a list to avoid race
156-
# conditions between iterating over it and having more pseudo-
157-
# members added to it
158-
if negative:
159-
# only check for named flags
160-
flags_to_check = [
161-
(m, v)
162-
for v, m in list(flag._value2member_map_.items())
163-
if m.name is not None
164-
]
165-
else:
166-
# check for named flags and powers-of-two flags
167-
flags_to_check = [
168-
(m, v)
169-
for v, m in list(flag._value2member_map_.items())
170-
if m.name is not None or _power_of_two(v)
171-
]
172156
members = []
173-
for member, member_value in flags_to_check:
157+
for member in flag:
158+
member_value = member.value
174159
if member_value and member_value & value == member_value:
175160
members.append(member)
176161
not_covered &= ~member_value
162+
if not negative:
163+
tmp = not_covered
164+
while tmp:
165+
flag_value = 2 ** _high_bit(tmp)
166+
if flag_value in flag._value2member_map_:
167+
members.append(flag._value2member_map_[flag_value])
168+
not_covered &= ~flag_value
169+
tmp &= ~flag_value
177170
if not members and value in flag._value2member_map_:
178171
members.append(flag._value2member_map_[value])
179172
members.sort(key=lambda m: m._value_, reverse=True)
@@ -2608,8 +2601,8 @@ class DataclassOption(Option[Any]):
26082601
@dataclass
26092602
class DBInfo:
26102603
host: str
2611-
port: int = 5432 # Field with default
26122604
user: str
2605+
port: int = 5432 # Field with default
26132606
ssl_mode: bool = field(default=False)
26142607
26152608
class AppSettings(Config):

src/firebird/base/signal.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -331,20 +331,18 @@ def my_handler(data: dict):
331331
"""
332332
_empty: _EventSocket = _EventSocket()
333333
def __init__(self, fget: Callable, doc: str | None=None):
334-
s = Signature.from_callable(fget)
335-
# Remove 'self' from list of parameters
336-
self._sig: Signature = s.replace(parameters=[v for k,v in s.parameters.items()
337-
if k.lower() != 'self'])
334+
# Store callable for later signature inspection
335+
self._callable = fget
338336
# Key: instance of class where this eventsocket instance is used to define a property
339337
# Value: _EventSocket
340338
self._map = WeakKeyDictionary()
341339
if doc is None and fget is not None:
342340
doc = fget.__doc__
343341
self.__doc__ = doc
344-
def _kw_test(self, sig: Signature) -> bool:
345-
p = sig.parameters
342+
def _kw_test(self, given: Signature, expected: Signature) -> bool:
343+
p = given.parameters
346344
result = False
347-
for k in set(p).difference(set(self._sig.parameters)):
345+
for k in set(p).difference(set(expected.parameters)):
348346
result = True
349347
if p[k].default is Signature.empty:
350348
return False
@@ -361,10 +359,15 @@ def __set__(self, obj, value):
361359
if not callable(value):
362360
raise ValueError(f"Connection to non-callable '{value.__class__.__name__}' object failed")
363361
# Verify signatures
364-
sig = Signature.from_callable(value)
365-
if str(sig) != str(self._sig):
362+
expected_sig: Signature = Signature.from_callable(self._callable, eval_str=True)
363+
# Remove 'self' from list of parameters
364+
expected_sig = expected_sig.replace(parameters=[v for k,v in expected_sig.parameters.items()
365+
if k.lower() != 'self'])
366+
367+
given_sig = Signature.from_callable(value, eval_str=True)
368+
if str(given_sig) != str(expected_sig):
366369
# Check if the difference is only in keyword arguments with defaults.
367-
if not self._kw_test(sig):
370+
if not self._kw_test(given_sig, expected_sig):
368371
raise ValueError("Callable signature does not match the event signature")
369372
self._map[obj] = _EventSocket(value)
370373
def __delete__(self, obj):

src/firebird/base/trace.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,8 @@ def __init__(self, name: str):
404404
ListOption('methods', str, "Names of traced class methods")
405405
#: Configuration sections with extended config of traced class methods
406406
self.special: ConfigListOption = \
407-
ConfigListOption('special',
408-
"Configuration sections with extended config of traced class methods",
409-
TracedMethodConfig)
407+
ConfigListOption('special', TracedMethodConfig,
408+
"Configuration sections with extended config of traced class methods")
410409
#: Wherher configuration should be applied also to all registered descendant classes [default: True].
411410
self.apply_to_descendants: BoolOption = \
412411
BoolOption('apply_to_descendants',
@@ -428,9 +427,9 @@ def __init__(self, name: str):
428427
default=True)
429428
#: Configuration sections with traced Python classes [required].
430429
self.classes: ConfigListOption = \
431-
ConfigListOption('classes',
430+
ConfigListOption('classes', TracedClassConfig,
432431
"Configuration sections with traced Python classes",
433-
TracedClassConfig, required=True)
432+
required=True)
434433

435434
class TraceManager:
436435
"""Trace manager.

0 commit comments

Comments
 (0)