From ed60b27276446388036aebdea7064839839eb6a9 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 18 Sep 2026 13:04:30 -0700 Subject: [PATCH] Fix three latent bugs in samples/explore_workbook.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fresh-eyes review on #1843 (2026-09-17) surfaced three pre-existing bugs that the samples/_shared.py migration in that PR did not introduce but did make more visible: 1. Line 127 used a bare type annotation `changed: TSC.CustomViewItem( id=c.id, name=...)` instead of an assignment, so `changed` was never bound and the following `server.custom_views.update(changed)` would NameError. 2. `c` was defined inside the custom-views loop and then referenced outside it. On a site with zero custom views the loop never runs and every subsequent reference NameErrors. 3. `if args.delete:` at line 145 referred to a flag that was never defined in the sample's argparse, so any invocation reaching that line raised AttributeError. Fixes: - Add `=` on line 127 to bind `changed`. - Collect the custom-views iterator into a list, wrap the update/ export block in `if custom_views:`, and pick the last entry explicitly (`c = custom_views[-1]`) — matches the intent of the original "for the last custom view in the list" comment. - Add a `--delete` argparse flag with `action="store_true"` and a clear help string. Guard the delete block so it prints a clear no-op message when the site has no custom views. No other behavior change. Sample compiles and imports cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) --- samples/explore_workbook.py | 43 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/samples/explore_workbook.py b/samples/explore_workbook.py index 033dbe594..6bd82e811 100644 --- a/samples/explore_workbook.py +++ b/samples/explore_workbook.py @@ -30,6 +30,11 @@ def main(): parser.add_argument( "--powerpoint", "-ppt", metavar="FILENAME", help="filename (a .ppt file) to save the powerpoint deck" ) + parser.add_argument( + "--delete", + action="store_true", + help="delete the last custom view on the site after the update/export demo", + ) args = parser.parse_args() @@ -117,23 +122,26 @@ def main(): # Get custom views. `.get()` only returns the first page; # use TSC.Pager to iterate every custom view on the site. - for c in TSC.Pager(server.custom_views): + custom_views = list(TSC.Pager(server.custom_views)) + for c in custom_views: print(c) - # for the last custom view in the list + if custom_views: + # For the last custom view in the list. + c = custom_views[-1] - # update the name - # note that this will fail if the name is already changed to this value - changed: TSC.CustomViewItem(id=c.id, name="I was updated by tsc") - verified_change = server.custom_views.update(changed) - print(verified_change) + # update the name + # note that this will fail if the name is already changed to this value + changed = TSC.CustomViewItem(id=c.id, name="I was updated by tsc") + verified_change = server.custom_views.update(changed) + print(verified_change) - # export as image. Filters etc could be added here as usual - server.custom_views.populate_image(c) - filename = c.id + "-image-export.png" - with open(filename, "wb") as f: - f.write(c.image) - print("saved to " + filename) + # export as image. Filters etc could be added here as usual + server.custom_views.populate_image(c) + filename = c.id + "-image-export.png" + with open(filename, "wb") as f: + f.write(c.image) + print("saved to " + filename) if args.powerpoint: # Populate workbook preview image @@ -143,9 +151,12 @@ def main(): print(f"\nDownloaded powerpoint of workbook to {os.path.abspath(args.powerpoint)}") if args.delete: - print(f"deleting {c.id}") - unlucky = TSC.CustomViewItem(c.id) - server.custom_views.delete(unlucky.id) + if not custom_views: + print("--delete requested but no custom views on this site; nothing to delete.") + else: + print(f"deleting {c.id}") + unlucky = TSC.CustomViewItem(c.id) + server.custom_views.delete(unlucky.id) if __name__ == "__main__":