Skip to content

Commit 1103404

Browse files
authored
312 ant 1 (#319)
* #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Save point * #312 - Abstract factory improvements * #312 - Abstract factory improvements
1 parent 90881bf commit 1103404

21 files changed

+996
-287
lines changed

.vscode/cspell.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"FCLASS",
6767
"FELEM",
6868
"felems",
69+
"finalizer",
6970
"FMES",
7071
"fpvs",
7172
"FTYPE",
@@ -196,4 +197,4 @@
196197
"**/__pycache__/**",
197198
"development-requirements.txt"
198199
]
199-
}
200+
}

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning].
77

88
## [Unreleased]
99

10+
## [0.4.0] - 2025-07-19
11+
12+
### Changed in 0.4.0
13+
14+
- Abstract factory improvements
15+
1016
## [0.3.17] - 2025-07-11
1117

1218
### Changed in 0.3.17

Migration.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ print(response)
121121
The separate `WithInfo` methods have been removed in the version 4.0 SDK. The capability is now included in the `add_record`, `delete_record`, `process_redo_record`,`reevaluate_entity`, and `reevaluate_record` methods. Requesting the with info response is achieved with the use of the optional `flags` argument and specifying the `SZ_WITH_INFO` engine flag. The default is not to return the with info response, in which case an empty string is returned:
122122

123123
```python
124-
from senzing import SzError
125124
...
126125
try:
127126
_ = sz_engine.add_record("TEST", "78720B", record_json_str)
@@ -135,6 +134,7 @@ Return the with info response using the `flags` argument:
135134
```python
136135
from senzing import SzEngineFlags, SzError
137136
...
137+
138138
try:
139139
response = sz_engine.add_record("TEST", "78720B", record_json_str, flags=SzEngineFlags.SZ_WITH_INFO)
140140
except SzError as err:
@@ -385,7 +385,7 @@ finally:
385385
In version 4.0, the `SzConfig` module is subordinate to the `SzConfigManager` and literally represents a Senzing configuration as an object. It removes the hassle of dealing with "config handles" that have to be closed as well:
386386

387387
```python
388-
sz_factory = SzAbstractFactoryCore(MODULE_NAME, SETTINGS, verbose_logging=False)
388+
sz_factory = SzAbstractFactoryCore(MODULE_NAME, SETTINGS)
389389

390390
try:
391391
# Get the config manager from the abstract factory
@@ -398,7 +398,8 @@ try:
398398
sz_config.register_data_source("CUSTOMERS")
399399

400400
# Register and set the default config in one shot
401-
new_config_id = sz_configmanager.set_default_config(sz_config.export(), "Register data source CUSTOMERS")
401+
new_config = sz_config.export()
402+
new_config_id = sz_configmanager.set_default_config(new_config), "Register data source CUSTOMERS")
402403
except SzError as err:
403404
raise err
404405
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from senzing import SzError
2+
3+
from senzing_core import SzAbstractFactoryCore
4+
5+
instance_name = "Example"
6+
settings = {
7+
"PIPELINE": {
8+
"CONFIGPATH": "/etc/opt/senzing",
9+
"RESOURCEPATH": "/opt/senzing/er/resources",
10+
"SUPPORTPATH": "/opt/senzing/data",
11+
},
12+
"SQL": {"CONNECTION": "sqlite3://na:na@/tmp/sqlite/G2C.db"},
13+
}
14+
15+
try:
16+
sz_abstract_factory = SzAbstractFactoryCore(instance_name, settings)
17+
sz_engine = sz_abstract_factory.create_engine()
18+
sz_diagnostic = sz_abstract_factory.create_diagnostic()
19+
20+
# Do work...
21+
except SzError as err:
22+
print(f"\nERROR: {err}\n")
23+
finally:
24+
# Destroys the abstract factory and all objects it created, such as sz_engine and sz_diagnostic above
25+
# If sz_abstract_factory goes out of scope destroy() is automatically called
26+
sz_abstract_factory.destroy()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// No output from this example.

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
orjson==3.11.0
2-
senzing==0.2.17
2+
senzing==0.2.20

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = senzing_core
3-
version = 0.3.17
3+
version = 0.4.0
44
author = senzing
55
author_email = support@senzing.com
66
description = Senzing Python SDK
@@ -21,7 +21,7 @@ package_dir =
2121
packages = find:
2222
python_requires = >=3.9
2323
install_requires =
24-
senzing >= 0.2.17,<1.0.0
24+
senzing >= 0.2.20,<1.0.0
2525

2626
[options.packages.find]
2727
where = src

src/senzing_core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .szproduct import SzProductCore
1414

1515
sz_product = SzProductCore()
16-
sz_product.initialize("sdk_init_check", "{}")
16+
sz_product._initialize("sdk_init_check", "{}")
1717
version: str = json.loads(sz_product.get_version()).get("VERSION", "0.0.0")
1818
is_senzing_binary_version_supported(version)
1919
except (ImportError, SyntaxError) as err:

src/senzing_core/_helpers.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ def _json_dumps(_obj: Any, *args: Any, **kwargs: Any) -> str:
5858
# NOTE - Using earlier Python version typing to support v3.9 still and not rely on typing_extensions.
5959
# NOTE - F can be changed to use ParamSpec when no longer need to support v3.9.
6060
# NOTE - SelfFreeCResources can be changed to use Self at v3.11.
61-
F = TypeVar("F", bound=Callable[..., Any])
62-
SelfFreeCResources = TypeVar("SelfFreeCResources", bound="FreeCResources")
61+
_F = TypeVar("_F", bound=Callable[..., Any])
62+
_SelfFreeCResources = TypeVar("_SelfFreeCResources", bound="FreeCResources")
63+
_WrappedFunc = TypeVar("_WrappedFunc", bound=Callable[..., Any])
6364

6465
PYTHON_VERSION_MINIMUM = "3.9"
6566
SENZING_VERSION_MINIMUM = "4.0.0"
@@ -85,7 +86,7 @@ def __init__(self, handle: CDLL, resource: _Pointer[c_char]) -> None:
8586
self.handle = handle
8687
self.resource = resource
8788

88-
def __enter__(self: SelfFreeCResources) -> SelfFreeCResources:
89+
def __enter__(self: _SelfFreeCResources) -> _SelfFreeCResources:
8990
return self
9091

9192
def __exit__(
@@ -102,7 +103,7 @@ def __exit__(
102103
# -----------------------------------------------------------------------------
103104

104105

105-
def catch_sdk_exceptions(func_to_decorate: F) -> F:
106+
def catch_sdk_exceptions(func_to_decorate: _F) -> _F:
106107
"""
107108
The Python SDK methods convert Python types to ctypes and utilize helper functions. If incorrect types/values are
108109
used standard library exceptions are raised not SzError exceptions as the Senzing library hasn't been called
@@ -114,9 +115,9 @@ def catch_sdk_exceptions(func_to_decorate: F) -> F:
114115
"""
115116

116117
@wraps(func_to_decorate)
117-
def wrapped_func(*args: Any, **kwargs: Any) -> F:
118+
def wrapped_func(*args: Any, **kwargs: Any) -> _F:
118119
try:
119-
return typing_cast(F, func_to_decorate(*args, **kwargs))
120+
return typing_cast(_F, func_to_decorate(*args, **kwargs))
120121
except (ArgumentError, TypeError, ValueError) as err:
121122
# Get wrapped function annotation, remove unwanted keys
122123
annotations_dict = func_to_decorate.__annotations__
@@ -143,7 +144,24 @@ def wrapped_func(*args: Any, **kwargs: Any) -> F:
143144

144145
raise SzSdkError(err) from err
145146

146-
return typing_cast(F, wrapped_func)
147+
return typing_cast(_F, wrapped_func)
148+
149+
150+
# -----------------------------------------------------------------------------
151+
# Decorators
152+
# -----------------------------------------------------------------------------
153+
154+
155+
def check_is_destroyed(func: _WrappedFunc) -> _WrappedFunc:
156+
"""Check if an engine instance has been destroyed"""
157+
158+
@wraps(func)
159+
def wrapped_check_destroyed(self, *args, **kwargs): # type: ignore
160+
if self._is_destroyed: # pylint: disable=protected-access
161+
raise SzSdkError("engine object has been destroyed and can no longer be used, create a new one")
162+
return func(self, *args, **kwargs)
163+
164+
return typing_cast(_WrappedFunc, wrapped_check_destroyed)
147165

148166

149167
# -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)