Fix stats.countby --by-name sort with mixed value types (SYN-9957) - #5017
Merged
Merged
Conversation
The --by-name sort key returned int() for names which parsed as integers and the original str for names which did not, so a tally containing both handed sorted() a non-orderable mix of types and leaked a TypeError. This happened most often when some nodes did not have the tallied property set, which tallies under the name None. Sort numeric names numerically using s_common.hugenum() and non-numeric names lexicographically after them. Using a hugenum rather than int() also sorts fractional names numerically. Non-finite values such as nan are treated as non-numeric since they cannot be ordered. Claude-Session: https://claude.ai/code/session_013pyj3S8NddfycqDWj9uBUS
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #5017 +/- ##
==========================================
- Coverage 97.89% 97.83% -0.06%
==========================================
Files 308 308
Lines 65689 65690 +1
==========================================
- Hits 64305 64270 -35
- Misses 1384 1420 +36 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
invisig0th
marked this pull request as ready for review
September 21, 2026 16:00
The new assertions created a second getTestCore() rather than reusing the one already stood up by test_stormlib_stats_countby. Append them to the existing context instead to avoid the extra Cortex boot. The added inet:ipv4 nodes are tagged and lifted by tag so the existing chart expectations are unaffected. Claude-Session: https://claude.ai/code/session_013pyj3S8NddfycqDWj9uBUS
MichaelSquires
approved these changes
Sep 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SYN-9957
stats.countby --by-nameleaked a raw pythonTypeErrorwhenever a tally contained a mix of numeric and non-numeric names. Reported by a Sentinel 1 user via epiphyte.The
--by-namesort key returnedint()for names which parsed as integers and the originalstrfor names which did not, so a tally containing both handedsorted()a non-orderable mix of types. The common trigger is nodes which do not have the tallied property set, since those tally under the nameNone.Changes
Numeric names now sort numerically and non-numeric names sort lexicographically after them, via a type-homogeneous sort key.
s_common.hugenum()is used in place ofint(), so fractional names sort numerically too (1,1.5,2,10) with exact decimal comparison and none of thefloat()rounding fuzz. Two cases are handled explicitly:hugenum('0xzz')raisesValueErrorfrom its hex branch rather than aDecimalExceptionhugenum('nan')succeeds, butDecimal('NaN') < Decimal(1)raisesInvalidOperation— the same leak class being fixed — so non-finite values are treated as non-numericThe
coerce(indx)closure factory was only ever called ascoerce(0), so the unusedindxgenerality is dropped.Before / After
Tests
The regression assertions are appended to the existing
test_stormlib_stats_countbyso they reuse the Cortex it already stands up rather than booting a second one. The newinet:ipv4nodes are tagged and lifted by tag, so the existing 15-node fixture and its 18 chart expectations are unaffected.Coverage:
ValueErrorarm, the non-finite arm, and plain stringsPasses plain and under
SYNDEV_NEXUS_REPLAY=1. 100% patch coverage —synapse/lib/stormlib/stats.pyreports 99% with the only miss onStatTally.value(), which is pre-existing and outside this diff.No docs change:
storm_ref_cmd.rstormrendersstats.countby --helpdynamically and no option help text changed.Note on 3.x
synsrc/synapse/lib/stormlib/stats.pyinsynapse-enterprisecarries a byte-identical copy of the buggyif byname:block, and the failure reproduces there asinet:ip | stats.countby :asn --by-name. That needs a separate PR againstmain; the fix transplants verbatim, but the charts differ because v3 renders the percent column unconditionally instead of behind--percent.https://claude.ai/code/session_013pyj3S8NddfycqDWj9uBUS