[HN Gopher] Reloadr - Hot code reloading tool for Python
       ___________________________________________________________________
        
       Reloadr - Hot code reloading tool for Python
        
       Author : albertzeyer
       Score  : 147 points
       Date   : 2021-02-05 12:33 UTC (10 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | hikarudo wrote:
       | Any pointers on hot code reloading for C++?
        
         | wozer wrote:
         | I think Visual C++ supports it for a subset of the language:
         | https://docs.microsoft.com/de-de/visualstudio/debugger/suppo...
        
         | namibj wrote:
         | Check out the Julia interop with C++.
         | 
         | In general, though, it's going to be hard.
        
         | maccard wrote:
         | Live++ [0] is an excellent tool, I use it daily.
         | 
         | [0] https://liveplusplus.tech/
        
         | jheruty wrote:
         | There is
         | https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledC...
         | 
         | The idea is to use virtual functions, and recompile new classes
         | into a shared library. The shared lib is linked into the
         | running program, and old instances of the classes are deleted
         | and replaced by new instances constructed from the shared
         | library.
         | 
         | I am working on a library called hscpp using the same (stolen)
         | idea here:
         | 
         | https://github.com/jheruty/hscpp
         | 
         | Proof of concept demo:
         | 
         | https://m.youtube.com/watch?v=pjGngeKgni8
         | 
         | hscpp is still very alpha, and I'm sure I'll find lots of bugs
         | as I work on a "real" demo. In contrast, Runtime Compiled C++
         | is quite mature and is used in real game projects.
         | 
         | Note that this approach very much limits your architecture. For
         | example, you won't be able to use statics, as the newly
         | compiled shared libraries won't see them.
         | 
         | It's a finicky thing, worth it to me, but not something you can
         | just plop in to an established project.
        
       | neves wrote:
       | I use IPython that already have this feature. Just type in a
       | prompt:
       | 
       | %load_ext autoreload %autoreload 2
       | 
       | now every run automatically reload your modules.
        
       | mmerickel wrote:
       | My project, hupper [1], isn't hot reloading but it's worth
       | mentioning in this thread alongside other code reloaders. It is a
       | general purpose tool to monitor python code and reload the
       | process when code changes. You can use it with any script that
       | you're working on via `hupper -m foo` and your `foo.py` is then
       | reloaded/re-executed everytime you change it. It's used under the
       | hood in other tools to implement things like `pserve --reload` in
       | Pyramid and is used in Warehouse (the codebase for PyPI) to ease
       | development workflows.
       | 
       | It's an improvement on some previous attempts at the solution
       | that would crash when reloading invalid code. Hupper does not
       | have this problem due to its multi process design.
       | 
       | [1] https://docs.pylonsproject.org/projects/hupper/en/latest/
        
       | satya71 wrote:
       | Last commit in Jan 2020. Is this project still active? Also
       | ideally, not needing to decorate would be nice.
        
         | breuleux wrote:
         | For what it's worth, I'm working on my own reloader which does
         | not require decorating anything:
         | https://github.com/breuleux/jurigged (still a WIP, but it works
         | well enough).
        
           | satya71 wrote:
           | Thanks for the good work. I'll give it a try.
        
       | julvo wrote:
       | Wrote a similar thing [1]. It can also load loop bodies from
       | source before each iteration. Can be helpful for long running
       | loops like when downloading or training deep learning models.
       | 
       | [1] https://github.com/julvo/reloading
        
       | jorshman wrote:
       | What are some simple use cases for this?
        
         | agumonkey wrote:
         | shorter iteration times when exploring things live
        
         | magicalhippo wrote:
         | I imagine it can be very useful if you want to debug and fix a
         | problem in a contained area of the code where it can take a
         | significant effort to get the program in a state which can
         | trigger the bug, but once in that state it's easy to trigger
         | repeatedly.
         | 
         | Say you have to load a lot of data, but once loaded you can
         | trigger the issue by just hitting a button.
         | 
         | With hot code reloading you could incrementally add debugging
         | code and try your fix, without having to restart the program
         | and wait for the data to reload each time.
        
         | conjectures wrote:
         | The use case is making it take less time to build stuff I
         | imagine.
        
         | brunocvcunha wrote:
         | Not a user of Reloadr, but hot code reloading is a big thing on
         | my Java development process. There are servers and use cases
         | that take a long time to start or setup, and having the
         | possibility to debug -> edit code -> re-execute a specific
         | method using the same context goes a long way.
         | 
         | For production usage, maybe that wouldn't be considered safe,
         | but there are companies that provide services with this purpose
         | (e.g. JRebel).
        
         | fouric wrote:
         | Well, the main benefit is going to be for complex things where
         | you don't want to restart a large program in order to test a
         | small change, but in terms of simple things, programs with
         | event loops (like games or interactive tools) are a good
         | candidate.
        
         | the_jeremy wrote:
         | I wrote a (worse) version of this at my first job, because
         | loading and initial manipulation of the data I was doing
         | analysis on took tens of minutes, and I kept wanting to make
         | changes to what I was doing. Saved me a couple hours.
        
       | sitkack wrote:
       | For reloading from within the repl                   from
       | importlib import reload as r
       | 
       | Then in the ipython shell you can type r(module) to reload the
       | entire thing.
       | 
       | So I'll often have the editor in one terminal window, and ipython
       | in the other one, save the code and switch back the repl, and
       | type r(t)                   import mymodule as t
       | 
       | Now tie in some ipdb [1] and you have a pretty sweet setup. Also
       | depending on your serving framework it might also have hot
       | reloading as well, tornado, flask, etc.
       | 
       | [1] https://github.com/gotcha/ipdb
       | 
       | [2] https://www.tornadoweb.org/en/stable/autoreload.html
       | https://werkzeug.palletsprojects.com/en/0.14.x/serving/
        
         | rcfox wrote:
         | Why not just use ipython's built-in autoreload?
         | https://ipython.readthedocs.io/en/stable/config/extensions/a...
        
       | williamsmj wrote:
       | You can get this behavior in ipython and any other jupyter tool
       | (notebook, lab) without adding a python dependency by putting
       | this:                   %load_ext autoreload         %autoreload
       | 2
       | 
       | in ~/.ipython/profile_default/startup/autoreload.ipy
        
       | huijzer wrote:
       | In Julia, this can be done with even less efforts on the user-
       | side by loading Revise (https://github.com/timholy/Revise.jl)
       | before any other package you load.
        
       | fouric wrote:
       | I'm slightly confused by this wording in the docs: "This allows
       | it to reload code that is followed by blocking instructions such
       | as the infinite loops you can find in the examples."
       | 
       | The examples just have loops where the reloaded function is
       | called in a loop. Is this just updating the definition of the
       | function between calls?
        
       | Waterluvian wrote:
       | Having a hot reloaded set up for both my django (It's built in)
       | environment and Web app environment is such a force multiplier.
       | 
       | It's not about simply saving time doing it manually. It
       | fundamentally changes my dev-test/experiment workflow.
       | 
       | I love being able to tab to a server file, make a change, tab to
       | a client file, make another change, and instantly test it in a
       | browser.
        
         | speg wrote:
         | Have you tried PHP? :)
         | 
         | I jest, but really I feel like we've made things so complicated
         | it just gets in our way. Our Javascript pipeline is huge,
         | complicated, and requires you to sit down and wrap your head
         | around it every time you want to modify it.
         | 
         | If I get to greenfield another project, it's going to be so
         | bloody simple.
        
           | folkrav wrote:
           | > If I get to greenfield another project, it's going to be so
           | bloody simple.
           | 
           | It's always simple when it starts up. It's after months/years
           | of iterating without having a decent battle plan that it
           | becomes complicated.
        
             | OJFord wrote:
             | I agree things grow to be complicated, and that's somewhat
             | unavoidable (accepting usual constraints), but they don't
             | have to start out com _plex_. I think that 's the same
             | point GP is making.
        
               | folkrav wrote:
               | Fair enough.
        
           | whalesalad wrote:
           | PHP has to bootstrap everything on every single request. It
           | is definitely great for reloadability and local development
           | but terrible for production performance. Most teams that do
           | not _need_ PHP or love it (Laravel is great I know) have
           | moved to using languages and frameworks that provide a long
           | running application server.
        
             | mjburgess wrote:
             | The "run once and die" model of php applications however,
             | it extremely clarifying and simplifying.
             | 
             | It is a bit like the unix philosophy of "simple apps, in
             | sequence" -- in the sense that it clarifies what
             | development should be.
             | 
             | PHP apps, at their best, were multiple "run once and die"
             | endpoints -- the drive to "Front Controller" and "run long"
             | apps throws away much of the value of this paradigm.
             | 
             | Part of the community problem, id say, is that this
             | paradigm was never well-articulated; and always associated
             | with "a mess".
             | 
             | People like rasmus tried: yes have your long-running apps
             | (eg., in Java), but your front-end should be die-quickly.
        
             | toast0 wrote:
             | PHP isn't that bad for production performance, if you have
             | the right mindset.
             | 
             | Another way of saying PHP has to bootstrap everything on
             | each request (which is a bit of an overreach; it doesn't
             | reload C libraries, and you can do opcode caching and data
             | caching, etc), is that PHP throws away everything you've
             | done after each request.
             | 
             | That means everything that you build that isn't output
             | somewhere is garbage.
             | 
             | If you spend a lot of time making a sculpture out of
             | garbage, only to throw it away, you'll have poor
             | performance. If you use the minimum of scaffolding to send
             | out the bytes you want to send, you can get pages (or api
             | responses, whatever) with a few ms of overhead in addition
             | to your underlying data fetches. You could certainly go
             | faster with something else, but PHP can be decently fast.
             | 
             | On the other hand, your code won't look at all like what
             | people think of as 'modern' PHP.
        
           | Waterluvian wrote:
           | I'm writing applications for people to manage fleets of
           | thousands of robots in real-time from the other side of the
           | planet. There's no room for "bloody simple" =D
           | 
           | They don't resemble traditional websites/CRUD apps a whole
           | lot. Much closer to Sim City + Factorio.
           | 
           | When it comes to making your standard issue website/webapp, I
           | think some of them could stand to be simpler.
        
       | teajunky wrote:
       | I am developing my own reloader in spirit of jrebel and how
       | hotswapping works in javascript bundlers.
       | 
       | While investigating the topic I found a lot of projects: -
       | https://github.com/yiblet/inquest -
       | https://github.com/mpolney/hotpatch -
       | https://pypi.org/project/patchy/ -
       | https://pypi.org/project/plone.reload/ -
       | http://svn.python.org/projects/sandbox/trunk/xreload/ -
       | https://pypi.org/project/hot_reload/ -
       | https://pypi.org/project/Reloadr/ -
       | https://pypi.org/project/hotswap/ -
       | https://pypi.org/project/reloading/ -
       | https://pypi.org/project/hotreload/ -
       | https://pypi.org/project/livereload/ -
       | https://pypi.org/project/reimport/ -
       | https://pypi.org/project/livecoding/ -
       | https://pypi.org/project/pylivecoding/ -
       | https://pypi.org/project/nameko-hot-reload/ -
       | https://github.com/albertz/PythonHotswap -
       | https://github.com/mikr/pyqtboiler/blob/master/baseapp/utils... -
       | https://github.com/narfdotpl/hottie with decorator -
       | https://github.com/ipython/ipython/blob/f8c9ea7db42d9830f163... -
       | https://github.com/breuleux/jurigged
       | 
       | I thing that xreload from Guido and the code inside ipython both
       | provide the best hot-patching. But both projects miss the feature
       | to watch for changed files.
        
       | gamesbrainiac wrote:
       | Made a short video on it ->
       | https://twitter.com/gamesbrainiac/status/1357697930258448384...
       | 
       | It's pretty darn neat. I'm going to play around with it a little
       | more over the weekend.
        
       | bambam3000 wrote:
       | does this patch existing class instances, if you modify a method
       | for example?
       | 
       | I cobbled together something similar a few years back using the
       | reload stuff from ipython and a script I think GuidoVR wrote that
       | I stumbled on. I like to debug on the cli (pdb++), I made it
       | autodetect changed modules and reload those whenever i entered
       | the 'reload' command. For me having to decorate things first
       | would be a no-no.
       | 
       | My helper worked really nicely for some projects but broke with
       | others. Well done on getting something out there.
        
       | ericol wrote:
       | Few years back, I did something similar to this with PHP.
       | 
       | I was always marveled at the capacities of xDebug, and never
       | stopped using it since I found it (Some 10+ years), and honestly,
       | coupling it with PHPStorm is another level.
       | 
       | But still, hitting reload on the browser, or running a script
       | from the CLI gets tiring after the 20th time; so I made this
       | little class where you would call a method, and the method will
       | reload the script where the code was located continuously until I
       | managed to get it to do what I wanted.
       | 
       | It was very Johnny Mnemonic, but it worked.
        
       | fabioz wrote:
       | Ha, I'm just working on integrating the `pydev.debugger` code
       | reloading into `debugpy` (so that the code reloading from the
       | PyDev debugger will be available for Python-VSCode debugger users
       | too).
       | 
       | The in-memory reloading (which may be seen at:
       | https://github.com/fabioz/PyDev.Debugger/blob/main/_pydevd_b...)
       | unfortunately doesn't work all the time (fixing the references at
       | runtime in Python is difficult), but it works well enough for the
       | cases where you have a simple function and change it (that file
       | does explain some of the issues that the reloading faces).
       | 
       | One major issue is that after doing the reload, you need to get
       | out of the function and then back into it to see the difference
       | -- so, if you're stopped in the function in a breakpoint, it's
       | not possible to simply drop the function and restart it as Python
       | itself doesn't support that... maybe that's a good idea for a PEP
       | ;)
       | 
       | Anyways, when it works, it's pretty nice in that you don't have
       | to restart your whole debug session to see changes (the other
       | approach, which webservers use in general is just restart the
       | whole process, so, for instance, Django has an initial process
       | just monitoring for changes and a 2nd process which is actually
       | serving requests which is restarted when something changes -- not
       | as good if you have a heavy startup or are working with something
       | where you have to click through multiple things to get to the
       | state which you want).
        
       | breuleux wrote:
       | That's a bit awkward, I'm currently working on a package[1] that
       | does more or less the same thing in more or less the same way (I
       | think), except you don't need to decorate anything. Just run
       | `python -m jurigged script.py` or `jurigged script.py` instead of
       | `python script.py` and it will watch everything in the current
       | working directory.
       | 
       | There's still some bugs I have to iron out, though, it should be
       | better in a month or so. Still, you can pip install it if you
       | want.
       | 
       | [1] https://github.com/breuleux/jurigged
        
         | ArchOversight wrote:
         | Have you looked at `hupper` from the Pylons Project?
         | 
         | The author posted here:
         | https://news.ycombinator.com/item?id=26039366
        
           | breuleux wrote:
           | Seems fairly different. My tool does not restart the process,
           | it hot patches functions and methods whenever they are
           | modified in the source, like the OP.
        
       | albertzeyer wrote:
       | I stumbled upon this because there seems to be a FOSDEM talk
       | which talks about it:
       | https://fosdem.org/2021/schedule/event/python_reloading/
       | 
       | (https://news.ycombinator.com/item?id=26034851)
       | 
       | I wonder if this is used seriously by someone.
       | 
       | I always thought that this has a potential to greatly improve the
       | development productivity.
       | 
       | I remember I saw live coding videos from Notch (Minecraft) on
       | some gamejam where he intensively used hot code reloading for
       | Java. About 90% of his development time, he had the game running,
       | and tuned the logic of some game elements live, and immediately
       | saw the result.
       | 
       | I know that Erlang also has such a feature, such that you don't
       | need to shut down your production system, and that you can update
       | it live while it keeps running.
        
       | junke wrote:
       | Lisp - hot code reloading for Lisp
       | 
       | (just kidding)
        
       | sllabres wrote:
       | Cool feature.
       | 
       | Visual Studio seems to have "edit and continue" which I only knew
       | from VB, but seems to be available in C# and C++ too. Not the
       | same, but it shortens the development cycle in a similar fashion.
       | 
       | The feature in Python reminds me on hot code loading in Erlang
       | which I found quite interesting when i first read (never used)
       | about the feature. I wondered which other languages provides (or
       | didn't) an equivalent solution. Back then it felt a bit scary,
       | with not much more than RCS as VCS around :) But I think Erlang
       | implemented it for increased up-time, not for increased
       | development cycle?
       | 
       | To keep the up-time high, today even parts or entire operating
       | systems are patched 'live' (ksplice, kpatch, kgraft, AIX live
       | update) (https://ksplice.oracle.com/) (https://www.ibm.com/suppor
       | t/knowledgecenter/ssw_aix_72/insta...). Here too to prevent
       | downtime and technologically completely different from what is
       | presented here.
        
         | sgh1 wrote:
         | I've never had any success at all with VS's edit and continue,
         | even after tinkering some project settings to try to get it to
         | work better.
         | 
         | To be fair, this was a few years ago now, maybe worth another
         | look?
        
       | jC6fhrfHRLM9b3 wrote:
       | Here's an alternative way which does not require changing your
       | production code. https://odwyer.software/blog/supercharged-
       | python-testing-wor...
        
       | briggers wrote:
       | I used to love doing this with Clojure, it's an awesome way to
       | increase productivity by a good chunk.
       | 
       | It's less about saving the time to re-run something, and more
       | about removing conceptual overhead (I think).
        
       | [deleted]
        
       ___________________________________________________________________
       (page generated 2021-02-05 23:01 UTC)