feat: full type safety pass and logspark 0.12.0 upgrade for 6.2.0#151
feat: full type safety pass and logspark 0.12.0 upgrade for 6.2.0#151Kydoimos97 wants to merge 2 commits into
Conversation
Upgrades logspark to 0.12.0 which removes @SingletonClass from SparkLogger, enabling clean inheritance. WrenchLogger now inherits directly from SparkLogger without the __bases__[0] runtime hack, and logger is typed as WrenchLogger instead of Any — invalid method calls are now caught by static analysis. - Add py.typed marker so consumers get full inline type information (PEP 561) - Make SingletonClass generic (Type[T] -> Type[T]) to preserve class types through decoration - Replace try/except ImportError with importlib.util.find_spec for optional dep detection across Connect, pandas-optional modules - Fix all ty errors across ExceptionSuggestor, JsonParser, JsonSerializer, S3ServiceGateway, AwsClientHub, _boto_cache, Retryable, Deprecated, FileTyper, Image2B64, ProcessingTracker, StandardizeNone, _MockPandas - Update tests to patch importlib.util.find_spec instead of builtins.__import__ for simulating missing optional dependencies
Wrench-Service-Bot
left a comment
There was a problem hiding this comment.
PR Review
Verdict: REQUEST CHANGES
Description
Upgrades the logspark dependency from 0.11.0 to 0.12.0, which removes @SingletonClass from SparkLogger and allows WrenchLogger to inherit from it directly rather than via the __bases__[0] runtime hack. Alongside the dep bump, the PR runs a type-safety pass across 25 files: optional-dep detection switched from try/except ImportError to importlib.util.find_spec, None-default parameters annotated with Optional, cast() added for type-narrower returns, py.typed marker added for PEP 561.
Highlights
WrenchLogger.__bases__[0]hack correctly removed — clean direct inheritance is soundSingletonClassis now generic (Type[T] -> Type[T]) — downstream type checking improvedOptional[str]fixups acrossDeprecated,S3ServiceGateway,ExceptionSuggestor,_internal.pyare all correctimportlib.util.find_specmigration for pandas and AWS dep detection is cleaner than try/except_get_mime_extensionreturn-type corrected toOptional[str]—mimetypes.guess_extensioncan returnNoneImage2B64:binascii.Errorinstead ofbase64.binascii.Error— correct, the latter is an implementation detailJsonSerializer: explicitraise json.JSONDecodeErrorat the end ofsanitize_unescaped_quotes_and_load_json_stris a correctness fix (previously fell through to implicitNonereturn)- Test suite correctly updated to patch
importlib.util.find_specinstead ofbuiltins.__import__
Blocking Finding
WrenchCL/Connect/ProcessingTracker.pylines 163–164 —TTLSet = setfollowed byTTLSet(ttl=600)expands toset(ttl=600), which raisesTypeError: set() got an unexpected keyword argument 'ttl'at class body evaluation time.ProcessingTrackerwill fail to import. The 145-test green pass is consistent with no test directly exercising this class. See inline comment for two fix options.
Style Notes
WrenchCL/Connect/__init__.py— the re-raisedImportErrordrops thefrom echain present in the old code. The new raise loses the original error context, making root-cause debugging harder when an import fails for an unexpected reason. Consider:raise ImportError(...) from Noneat minimum, or preserve the chain by catching inside the guarded block..gitignore— missing newline at end of file (cosmetic).
Overall Assessment
The logspark upgrade and type-safety pass are well-scoped and the majority of changes are sound. One import-time crash in ProcessingTracker blocks merge: set(ttl=600) is not valid Python and will fail before any tests can exercise the class. Fix with a one-class stub or by dropping the ttl kwarg at the usage site, then this is ready to ship.
Sources
- Diff: 25 files, +165/-154
- Prior reviews: none
- Related PRs/issues: logspark 0.12.0 linked in PR body; no cross-repo consumer PRs checked (WrenchCL is a library — consumer upgrade is the caller's responsibility per PR notes)
— Claude
Blocking finding fixed: TTLSet stub now accepts ttl kwarg correctly; error chain suppression added.
Wrench-Service-Bot
left a comment
There was a problem hiding this comment.
PR Review
Verdict: APPROVED
Description
Re-review following REQUEST CHANGES on commit 2b52922. This commit resolves the one blocking issue flagged in that pass and adds a batch of cleanup deletions (legacy _Internal/Logging/Api/ stub files and __pycache__ binaries that should not have been tracked).
Highlights
- TTLSet crash resolved —
TTLSet = setreplaced with a properclass TTLSet(set)stub that acceptsttlas a keyword argument.ProcessingTrackerimports and instantiates cleanly. Thread resolved. - Relative imports in ProcessingTracker.py corrected —
from Connect import AwsClientHubandfrom Decorators import SingletonClassfixed tofrom ..Connect/from ..Decorators. These were absolute-style references that would have failed in a standard package install. raise ImportError(...) from NoneinConnect/__init__.py— the style note from the prior review was acted on;from echain is now explicitly suppressed withfrom None, which is the correct choice for a user-facing error message.JsonSerializer.sanitize_unescaped_quotes_and_load_json_strnow raisesjson.JSONDecodeErroron fallthrough — this was a latent silentNone-return bug, now correct.recur_parse_jsonbranch restructure is logically equivalent and the added terminalreturn dis unreachable but satisfies the type checker cleanly.
Style Notes
AwsClientHub.py,RdsServiceGateway.py,ExceptionSuggestor.py— severalassert x is not Noneguards were added as type-narrowing hints. These are stripped underpython -O. For runtime invariants,if x is None: raise RuntimeError(...)is safer. Given the library context and that these are purely narrowing asserts (the surrounding logic ensures the invariant), this is advisory only — does not block merge..gitignore— still missing a trailing newline at end of file (carried from prior commit, cosmetic).__pycache__/*.pycdeletions in the diff confirm previously tracked binaries are being cleaned up — correct direction, but__pycache__/should be verified as gitignored going forward.
Overall Assessment
The single blocker from review #1 is cleanly resolved. All other changes reviewed in the prior pass remain sound. The type-safety sweep (logspark 0.12.0 upgrade, WrenchLogger direct inheritance, SingletonClass generics, importlib.util.find_spec migration, Optional annotations, py.typed marker) is correct and ready to ship as v6.2.0.
Sources
- Diff: 76 files, +169/-228 (bulk of additions/deletions are stub-file cleanup and .pyc removals)
- Prior reviews: 1 (REQUEST CHANGES, commit 2b52922, review #4511249552 — dismissed by author)
- Related PRs/issues: logspark 0.12.0 linked in PR body; no cross-repo consumer PRs required (WrenchCL is a library — consumer upgrade is caller's responsibility per PR notes)
— Claude
Upgrades logspark to 0.12.0 which removes
@SingletonClassfromSparkLogger, enabling clean inheritance for the first time. This unblocks proper static analysis across WrenchCL and all consumer repos.What changed
WrenchLoggernow inherits directly fromSparkLogger— the__bases__[0]runtime hack is goneloggeris typed asWrenchLoggerinstead ofAny— invalid method calls (e.g.logger.start_time()) are now caught by ty at check timeSingletonClassmade generic (Type[T] -> Type[T]) so the decorator no longer erases the class type through decorationpy.typedmarker added — consumers get full inline type information via PEP 561 without stubstry/except ImportErrortoimportlib.util.find_specacrossConnect/__init__.pyand all pandas-optional modules (StandardizeNone,RdsServiceGateway) — more explicit, easier to test, no swallowed import side effects_MockPandascleaned up — the try/except at module level removed, consuming files own their own conditional import with aTYPE_CHECKINGguardExceptionSuggestor,JsonParser,JsonSerializer,S3ServiceGateway,AwsClientHub,_boto_cache,Retryable,Deprecated,FileTyper,Image2B64,ProcessingTracker,StandardizeNone,_internalTests
test_optional_importsupdated to patchimportlib.util.find_specinstead ofbuiltins.__import__— the old patch target was bypassed by the new dep checktest_62_diffs.py) added to verify all 6.2.0 changes against an installed package — produces 3 expected failures on 6.1.0, 0 on 6.2.0Deployment
Tag
v6.2.0pushed. PyPI publish triggered on merge. Consumer repos should upgrade logspark to~=0.12.0and WrenchCL to~=6.2.0together — the two are a paired release. WrenchCL 6.1.0 + logspark 0.12.0 is a broken combination (the__bases__[0]hack resolves tologging.Loggerinstead ofSparkLogger).References