- Add support for Python 3.12.
- Fix a blocking issue when shutting down on Windows.
- Fix a race condition closing pipes when restarting the worker process. See #83
- Fix issues with watchman when the server shuts down unexpectedly and when subscriptions are canceled.
- Add
hupper.get_reloader().graceful_shutdown()
which can be used within your own app to trigger a full shutdown of the worker as well as the monitoring. See #88
- When the reloader is stopped, exit with the same code received from the subprocess. See #81
- Drop support for Python 2.7, 3.4, 3.5, and 3.6.
- Add support/testing for Python 3.10, and 3.11.
- Explicitly require
reload_interval
set greater than0
to avoid spinning the CPU needlessly.
- Support Python 3.8 and 3.9.
- Fix an issue with bare
.pyc
files in the source folder causing unhandled exceptions. See #69 - Fix issues with using the Watchman file monitor on versions newer than
Watchman 4.9.0. This fix modifies
hupper
to use Watchman'swatch-project
capabilities which also support reading the.watchmanconfig
file to control certain properties of the monitoring. See #70
- Fix a regression that caused SIGINT to not work properly in some situations. See #67
- Performance improvements when using Watchman.
Handle a
SIGTERM
signal by forwarding it to the child process and gracefully waiting for it to exit. This should enable usinghupper
from within docker containers and other systems that want to control the reloader process.Previously the
SIGTERM
would shutdownhupper
immediately, stranding the worker and relying on it to shutdown on its own.See #65
Avoid acquiring locks in the reloader process's signal handlers. See #65
Fix deprecation warnings caused by using the
imp
module on newer versions of Python. See #65
- Support some scenarios in which user code is symlinked
site-packages
. These were previously being ignored by the file monitor but should now be tracked. See #61
- Support
--shutdown-interval
on thehupper
CLI. See #56 - Support
--reload-interval
on thehupper
CLI. See #59 - Do not choke when stdin is not a TTY while waiting for changes after a crash. For example, when running in Docker Compose. See #58
- Do not show the
KeyboardInterrupt
stacktrace when killinghupper
while waiting for a reload.
- If the worker process crashes,
hupper
can be forced to reload the worker by pressing theENTER
key in the terminal instead of waiting to change a file. See #53
- On Python 3.5+ support recursive glob syntax in
reloader.watch_files
. See #52
- If the worker crashes immediately, sometimes
hupper
would go into a restart loop instead of waiting for a code change. See #50
- On systems that support
SIGKILL
andSIGTERM
(not Windows),hupper
will now send aSIGKILL
to the worker process as a last resort. Normally, aSIGINT
(Ctrl-C) orSIGTERM
(on reload) will kill the worker. If, withinshutdown_interval
seconds, the worker doesn't exit, it will receive aSIGKILL
. See #48 - Support a
logger
argument tohupper.start_reloader
to override the default logger that outputs messages tosys.stderr
. See #49
- Add support for ignoring custom patterns via the new
ignore_files
option onhupper.start_reloader
. Thehupper
cli also supports ignoring files via the-x
option. See #46
- Fix a bug prompting the "ignoring corrupted payload from watchman" message and placing the file monitor in an unrecoverable state when a change triggered a watchman message > 4096 bytes. See #44
- Stop ignoring a few paths that may not be system paths in cases where the virtualenv is the root of your project. See #42
- Ignore changes to any system / installed files. This includes mostly
changes to any files in the stdlib and
site-packages
. Anything that is installed in editable mode or not installed at all will still be monitored. This drastically reduces the number of files thathupper
needs to monitor. See #40
- Support Python 3.7.
- Avoid a restart-loop if the app is failing to restart on certain systems.
There was a race where
hupper
failed to detect that the app was crashing and thus fell into its restart logic when the user manually triggers an immediate reload. See #37 - Ignore corrupted packets coming from watchman that occur in semi-random scenarios. See #38
- Added watchman support via
hupper.watchman.WatchmanFileMonitor
. This is the new preferred file monitor on systems supporting unix sockets. See #32 - The
hupper.watchdog.WatchdogFileMonitor
will now output some info when it receives ulimit or other errors fromwatchdog
. See #33 - Allow
-q
and-v
cli options to control verbosity. See #33 - Pass a
logger
value to thehupper.interfaces.IFileMonitorFactory
. This is an instance ofhupper.interfaces.ILogger
and can be used by file monitors to output errors and debug information. See #33
- Track only Python source files. Previously
hupper
would track all pyc and py files. Now, if a pyc file is found then the equivalent source file is searched and, if found, the pyc file is ignored. See #31 - Allow overriding the default monitor lookup by specifying the
HUPPER_DEFAULT_MONITOR
environment variable as a Python dotted-path to a monitor factory. For example,HUPPER_DEFAULT_MONITOR=hupper.polling.PollingFileMonitor
. See #29 - Backward-incompatible changes to the
hupper.interfaces.IFileMonitorFactory
API to pass arbitrary kwargs to the factory. See #29
- Support
-w
on the CLI to watch custom file paths. See #28
- Copy
sys.path
to the worker process and ensurehupper
is on thePYTHONPATH
so that the subprocess can import it to start the worker. This fixes an issue with howzc.buildout
injects dependencies into a process which is done entirely bysys.path
manipulation. See #27
- On non-windows systems ensure an exec occurs so that the worker does not share the same process space as the reloader causing certain code that is imported in both to not ever be reloaded. Under the hood this was a significant rewrite to use subprocess instead of multiprocessing. See #23
- Fix some versions of Windows which were failing to duplicate stdin to the subprocess and crashing. #16
- Fix pdb and other readline-based programs to operate properly. See #15
- Pause briefly after receiving a SIGINT to allow the worker to kill itself. If it does not die then it is terminated. See #11
- Python 3.6 compatibility.
- Handle errors that may occur when using watchdog to observe non-existent folders.
- Support running any Python module via
hupper -m <module>
. This is equivalent topython -m
except will fully reload the process when files change. See #8
- Read the traceback for unknown files prior to crashing. If an import crashes due to a module-scope exception the file that caused the crash would not be tracked but this should help.
- Attempt to send imported paths to the monitor process before crashing to avoid cases where the master is waiting for changes in files that it never started monitoring.
- Add support for globbing using the stdlib
glob
module. On Python 3.5+ this allows recursive globs using**
. Prior to this, the globbing is more limited.
- Fixed a runtime failure on Windows 32-bit systems.
- Support triggering reloads via SIGHUP when hupper detected a crash and is waiting for a file to change.
- Setup the reloader proxy prior to importing the worker's module. This should allow some work to be done at module-scope instead of in the callable.
- Fix package long description on PyPI.
- Ensure that the stdin file handle is inheritable incase the "spawn" variant of multiprocessing is enabled.
- Disable bytecode compiling of files imported by the worker process. This should not be necessary when developing and it was causing the process to restart twice on Windows due to how it handles pyc timestamps.
- Fix hupper's support for forwarding stdin to the worker processes on Python < 3.5 on Windows.
- Fix some possible file descriptor leakage.
- Simplify the
hupper.interfaces.IFileMonitor
interface by internalizing some of the hupper-specific integrations. They can now focus on just looking for changes. - Add the
hupper.interfaces.IFileMonitorFactory
interface to improve the documentation for thecallback
argument required byhupper.interfaces.IFileMonitor
.
- Windows support!
- Added support for watchdog if it's
installed to do inotify-style file monitoring. This is an optional dependency
and
hupper
will fallback to using polling if it's not available.
- Initial release.