Show HN: Localscope–Limit scope of Python functions for reproducible execution
21 comments
·March 17, 2025mpeg
I wrote myself a similar decorator for a completely different purpose – ensuring a function I'm going to serialise over the network doesn't have any outside dependencies
This is actually a cleaner API so might switch my code to it, amazing work
simonw
I was curious how this works - it's using the Python standard library disassembler: https://docs.python.org/3/library/dis.html
for instruction in dis.get_instructions(code):
...
Code here: https://github.com/tillahoffmann/localscope/blob/092392d5bdb...nine_k
Nice! This approach can be used to implement coeffects (as e.g. seen in Hack [1]), by only passing explicit effect-producing objects. Imagine a function that's guaranteed to not write to any files, because it can't access `open()`, or can only access a version of `open()` that only accepts read-only access.
[1]: https://docs.hhvm.com/hack/contexts-and-capabilities/introdu...
dleeftink
> Everything works nicely, and you package the code in a function for later use but forget about the scale factor introduced earlier in the notebook.
You see a problem, you fix it with library, and I applaud that. You have to wonder though, how many years does it take for a reproducible notebook environment to implement out of scope variable guards..
jampekka
Jupyter-style notebooks are a good example of a deep architectural mistake that needs hacks on hacks on hacks to remain barely serviceable.
Luckily there are new approaches, e.g. Marimo and Pluto, that don't have the same root issue.
tillahoffmann
Yes, Jupyter notebooks are flawed (there's a great talk at https://www.youtube.com/watch?v=7jiPeIFXb6U). But they are also very convenient for scrappy work and exploratory data analysis.
jampekka
Notebooks can be convenient and have a consistent state at the same time, as done in e.g. Marimo.
nerdponx
This is for people who don't want to switch notebook environments, because Jupyter(lab) is getting better faster than alternatives (which support things like reactive cell execution) are becoming usable for day-to-day work.
It's just a safeguard for well-intentioned people to prevent themselves from making mistakes with their existing tools, instead of changing to a completely different set of tools.
escapecharacter
Since I've started using Jupyter notebooks, I've wanted a feature to "undo" running a cell. This feels so important to for spontaneous exploration. This work feels like an important building block for this!
olejorgenb
A crazy, but cool idea to implement this is using fork: https://github.com/thomasballinger/rlundo
mythrowaway49
agree! I feel like there must be a good workaround. Currently, I just need to go back and run a bunch of cells again..
matt3210
If you don't want pyhton flavored scope and lifetime rules, use another language :emothonless-face:
serial_dev
But how can you make sure that people annotate their functions with localscope?
igorguerrero
Same question people have with hinting, what makes Python cool is how loose it is... You could also make a lint rule for that and make fail CI if that rule failed, or... Write your own compiler you know?
nathan_compton
I have this idea of tools which help you do the right thing and tools that let you do the wrong thing longer. Jupyter is already the latter sort of tool, and this is the bad kind of tool on top of the bad kind of tool.
pkaodev
Maybe I'm being naive, but it feels like if this is a problem for people they should be looking at how they write their code, not reaching for a library.
disgruntledphd2
This bug basically hits people who run long lived code sessions with large objects (i.e. data people).
I've hit it in both R and Python in interactive sessions. Otherwise it's generally a non issue.
I can definitely see this being helpful, particularly for the intended context. It would also be useful when you need to move notebook code to a different environment.
RadiozRadioz
Completely. I interact with data people sometimes at work. There are bespoke one-of-a-kind venvs and giant notebooks everywhere. But that's okay. They don't have our job, it is not their job to build robust & properly deployed software. They know how to do their thing and we shouldn't lecture them on how to do it the "proper" way. Because I sure don't know how to do what they do - Pandas & matplotlib take me hours of googling to do anything.
I completely see the value in this tool for a particular style of programming.
dleeftink
I don't think the issue is telling someone how to do their jobs, but that when it comes to it, we are not properly communicating our stack preferences at all. Online we do, sure, but let's not shy away from having these discussions in the open. There is much to learn from each other's best and worst practices.
aiono
Software is complex and our memory is bottleneck to create software. We can only remember so many things therefore anything that we can make computer to "think" instead of us we have more memory to use for other work. In this case, instead of worrying if you are accessing some random global variable by accident is unnecessary cognitive work you. Why not just let computer do it while you think for actual things?
null
localscope is a small Python package that disassembles functions to check if they access global variables they shouldn't. I wrote this a few years ago to detect scope bugs which are common in Jupyter notebooks. It's recently come in handy writing jax code (https://github.com/jax-ml/jax) because it requires pure functions. Thought I'd share.