Commit 44fd783
authored
* Refactor session destroy to treat character(0) as the root namespace
Pairing-session work with colleague: make character(0) the canonical
user-facing value for the root scope (replacing ""), rename the destroy
`id` argument to `namespace`, fold id validation into invokeDestroyCallbacks
via an `allowRoot` flag, and drop the standalone validateDestroyId helper.
Committed verbatim as a record of the pairing session before applying fixes.
* Fix session destroy regressions from character(0) refactor
- Real ShinySession scope `destroy()` recursed infinitely: the renamed
`namespace` parameter shadowed the scope's own captured namespace, and the
self-destroy branch was replaced by a recursive makeScope() call that never
reached invokeDestroyCallbacks(). Restore the self-vs-child branch and
capture the scope's namespace as `selfNamespace`.
- MockShinySession was left on the old nzchar()/"" logic, so it still crashed
with "argument is of length zero" on callModule(server, character(0)) (the
teal failure path via testServer). Mirror the character(0) handling so mock
and real sessions behave identically.
- Validate the user-supplied destroy `namespace` at the public boundary
(before makeScope) via validateDestroyNamespace(), instead of inside
invokeDestroyCallbacks() which only runs after makeScope() has already
choked on bad input.
- Restore the reserved "..root" namespace guard in real makeScope(), and map
"" to root in destroyNsKey()/getOrCreateDestroyCallbacks() (fastmap can't
key on an empty string).
Full test suite passes (0 failures).
* Extract '..root' destroy sentinel into a documented constant
Replace the private ShinySession$destroyNsRoot field and the hardcoded
"..root" literals in MockShinySession with a single package-level
`destroyNsRoot` constant, documenting that it must be a non-zero-length
string because it is used as a fastmap key (fastmap disallows ""/NA keys).
* Apply suggestion from @cpsievert
* Apply suggestion from @cpsievert
* Address PR review feedback
- validateDestroyNamespace(): quote/coerce the offending value in the error
(clear output for "", numeric, NA, and multi-element inputs).
- MockShinySession$onDestroy(): use getOrCreateDestroyCallbacks() instead of
hand-managing the callback map, keeping root-key handling consistent.
- Align the mock's root-teardown error messages with ShinySession (direct
callers to close(), add call. = FALSE).
- Restore the original two-line formatting of the exportTestValues guard.
* Use a single root-detection criterion (length 0) for destroy keys
Drop the `|| !nzchar(ns)` folding I had added to destroyNsKey() and the
mock's getOrCreateDestroyCallbacks(). It made registration treat "" as root
while invokeDestroyCallbacks() (length-0) did not, so an ""-namespaced scope
would register onDestroy callbacks under the root key that teardown could
never find. character(0) is now the sole root spelling everywhere.
* Reject empty-string namespaces at makeScope()
Addresses Copilot feedback: with character(0) as the sole root spelling,
an empty-string `id` (e.g. callModule(server, "")) would otherwise fall
through to an empty-string fastmap key and error cryptically. Reject ""
early with a clear message in both the real and mock makeScope(); root
(character(0)) is still accepted. NS("") also yields a stray "-" prefix,
so "" was never a valid namespace.
* Forbid NA namespaces too, and document allowed namespace values
Widen the makeScope() guard (real + mock) to reject NA as well as "", since
both are unusable as fastmap keys. Document the contract in the destroy()
docstrings: a module namespace must be a non-empty, non-NA string, and the
root scope is identified by character(0).
* Promote NULL as the documented root-scope sentinel
Default the public destroy()/onDestroy() entry points and the internal
invokeDestroyCallbacks() to NULL instead of character(0), and lead with NULL
in the docstrings and guard messages. NULL is the idiomatic R 'absence' value
and was the original #4372 public default. character(0) remains accepted (both
are length 0, which is how root is detected everywhere), so callers like teal
that pass character(0) are unaffected; '' and NA are still rejected.
* Extract makeScope() namespace validation into a shared helper
The reserved-sentinel and empty/NA guards were duplicated byte-for-byte in
ShinySession$makeScope() and MockShinySession$makeScope(). Pull them into a
package-level validateScopeNamespace(), mirroring the existing
validateDestroyNamespace() helper. Behavior-preserving.
* Merge namespace validators into one validateNamespace(allow_root=)
validateScopeNamespace and validateDestroyNamespace differed only in whether
the root (length-0) namespace is allowed -- the apparent leniency of the scope
validator was illusory (numeric/multi-element namespaces crashed cryptically
downstream rather than being permitted). Collapse them into a single
validateNamespace(namespace, allow_root) helper: makeScope() passes
allow_root = TRUE, the destroy paths use the default. As a side benefit,
malformed makeScope() namespaces now get the clean validation error instead of
a cryptic fastmap/if-length crash.
* Use ASCII hyphens in destroy() docstring to fix R CMD check
R6 method docstrings are string literals (unlike #' roxygen comments), so the
em-dashes I used tripped 'checking code files for non-ASCII characters', which
CI runs with error_on = 'warning'. Replace them with '--'.
* Handle the root scope in makeScope() bookmark/restore helpers
With character(0)/NULL now a valid root namespace, the bookmark/restore
helpers' scalar-string assumptions broke for root scopes: filterNamespace()
treated the prefix as "-" (dropping all root-level names), and the save/restore
dir handling did file.path(dir, character(0)) -> dir.exists(character(0)) ->
"argument is of length zero". Treat a length-0 namespace as the root: all names
in scope, identity unNamespace(), and share the top-level bookmark dir (no
subdir). Pre-existing in v1.13.0; re-exposed by re-enabling root scopes.
Verified the root vs named behavior in isolation; full test suite passes.
1 parent 7d50304 commit 44fd783
4 files changed
Lines changed: 208 additions & 97 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
321 | 321 | | |
322 | 322 | | |
323 | 323 | | |
324 | | - | |
325 | | - | |
326 | | - | |
327 | | - | |
328 | | - | |
329 | | - | |
330 | | - | |
331 | | - | |
332 | | - | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
339 | 339 | | |
340 | | - | |
341 | | - | |
| 340 | + | |
| 341 | + | |
342 | 342 | | |
343 | 343 | | |
344 | 344 | | |
| |||
353 | 353 | | |
354 | 354 | | |
355 | 355 | | |
356 | | - | |
| 356 | + | |
357 | 357 | | |
358 | 358 | | |
359 | 359 | | |
| |||
554 | 554 | | |
555 | 555 | | |
556 | 556 | | |
557 | | - | |
558 | | - | |
559 | | - | |
560 | | - | |
561 | | - | |
562 | | - | |
| 557 | + | |
563 | 558 | | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
564 | 562 | | |
565 | 563 | | |
566 | 564 | | |
| |||
582 | 580 | | |
583 | 581 | | |
584 | 582 | | |
585 | | - | |
586 | | - | |
587 | | - | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
588 | 587 | | |
589 | | - | |
590 | | - | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
591 | 591 | | |
592 | 592 | | |
593 | 593 | | |
| |||
763 | 763 | | |
764 | 764 | | |
765 | 765 | | |
766 | | - | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
767 | 769 | | |
768 | 770 | | |
769 | 771 | | |
770 | 772 | | |
771 | 773 | | |
772 | 774 | | |
773 | | - | |
774 | | - | |
775 | | - | |
776 | | - | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
777 | 791 | | |
778 | | - | |
779 | 792 | | |
780 | 793 | | |
781 | 794 | | |
| |||
787 | 800 | | |
788 | 801 | | |
789 | 802 | | |
790 | | - | |
| 803 | + | |
791 | 804 | | |
792 | 805 | | |
793 | 806 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
438 | 438 | | |
439 | 439 | | |
440 | 440 | | |
441 | | - | |
442 | | - | |
443 | | - | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
448 | 464 | | |
449 | | - | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
450 | 473 | | |
451 | 474 | | |
452 | 475 | | |
| |||
808 | 831 | | |
809 | 832 | | |
810 | 833 | | |
811 | | - | |
812 | | - | |
813 | | - | |
814 | 834 | | |
815 | | - | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
816 | 838 | | |
817 | 839 | | |
818 | 840 | | |
| |||
822 | 844 | | |
823 | 845 | | |
824 | 846 | | |
825 | | - | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
826 | 858 | | |
827 | | - | |
828 | 859 | | |
829 | 860 | | |
830 | 861 | | |
| |||
837 | 868 | | |
838 | 869 | | |
839 | 870 | | |
840 | | - | |
| 871 | + | |
841 | 872 | | |
842 | 873 | | |
843 | 874 | | |
| |||
1005 | 1036 | | |
1006 | 1037 | | |
1007 | 1038 | | |
1008 | | - | |
1009 | | - | |
1010 | | - | |
1011 | | - | |
1012 | | - | |
1013 | | - | |
1014 | | - | |
| 1039 | + | |
1015 | 1040 | | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
1016 | 1044 | | |
1017 | 1045 | | |
1018 | 1046 | | |
| |||
1084 | 1112 | | |
1085 | 1113 | | |
1086 | 1114 | | |
1087 | | - | |
1088 | | - | |
1089 | | - | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
1090 | 1119 | | |
1091 | | - | |
1092 | | - | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
1093 | 1123 | | |
1094 | 1124 | | |
1095 | 1125 | | |
1096 | 1126 | | |
1097 | 1127 | | |
1098 | | - | |
| 1128 | + | |
| 1129 | + | |
1099 | 1130 | | |
| 1131 | + | |
1100 | 1132 | | |
1101 | 1133 | | |
1102 | 1134 | | |
1103 | 1135 | | |
1104 | 1136 | | |
1105 | | - | |
| 1137 | + | |
1106 | 1138 | | |
1107 | 1139 | | |
1108 | 1140 | | |
1109 | 1141 | | |
| 1142 | + | |
1110 | 1143 | | |
1111 | 1144 | | |
1112 | 1145 | | |
| |||
1134 | 1167 | | |
1135 | 1168 | | |
1136 | 1169 | | |
1137 | | - | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
1138 | 1173 | | |
1139 | 1174 | | |
1140 | 1175 | | |
| |||
1153 | 1188 | | |
1154 | 1189 | | |
1155 | 1190 | | |
1156 | | - | |
| 1191 | + | |
| 1192 | + | |
1157 | 1193 | | |
1158 | | - | |
1159 | | - | |
1160 | | - | |
1161 | | - | |
1162 | | - | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
1163 | 1203 | | |
1164 | 1204 | | |
1165 | 1205 | | |
| |||
1280 | 1320 | | |
1281 | 1321 | | |
1282 | 1322 | | |
1283 | | - | |
| 1323 | + | |
1284 | 1324 | | |
1285 | | - | |
| 1325 | + | |
1286 | 1326 | | |
1287 | | - | |
1288 | | - | |
1289 | | - | |
1290 | | - | |
1291 | | - | |
1292 | | - | |
1293 | | - | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
1294 | 1338 | | |
1295 | | - | |
1296 | | - | |
| 1339 | + | |
| 1340 | + | |
1297 | 1341 | | |
1298 | 1342 | | |
1299 | 1343 | | |
| |||
1345 | 1389 | | |
1346 | 1390 | | |
1347 | 1391 | | |
1348 | | - | |
| 1392 | + | |
1349 | 1393 | | |
1350 | 1394 | | |
1351 | 1395 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments