With `fsmonitor` extension enabled most operations fail with `TypeError: can only concatenate str (not "bytes") to str`. This happens even when fsmonitor is the _only_ enabled extension. ``` ** unknown exception encountered, please report by visiting ** https://mercurial-scm.org/wiki/BugTracker ** Python 3.7.7 (default, Mar 12 2020, 05:27:54) [Clang 11.0.0 (clang-1100.0.33.17)] ** Mercurial Distributed SCM (version 5.4) ** Extensions loaded: fsmonitor Traceback (most recent call last): File "/usr/local/bin/hg", line 43, in <module> dispatch.run() File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 112, in run status = dispatch(req) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 298, in dispatch ret = _runcatch(req) or 0 File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 472, in _runcatch return _callcatch(ui, _runcatchfunc) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 481, in _callcatch return scmutil.callcatch(ui, func) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/scmutil.py", line 152, in callcatch return func() File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 462, in _runcatchfunc return _dispatch(req) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 1226, in _dispatch lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 910, in runcommand ret = _runcommand(ui, options, cmd, d) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 1237, in _runcommand return cmdfunc() File "/opt/mercurial/lib/python3.7/site-packages/mercurial/dispatch.py", line 1223, in <lambda> d = lambda: util.checksignature(func)(ui, *args, **strcmdopt) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/util.py", line 1864, in check return func(*args, **kwargs) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/commands.py", line 6859, in status opts.get(b'subrepos'), File "/opt/mercurial/lib/python3.7/site-packages/hgext/fsmonitor/__init__.py", line 950, in status return overridestatus(orig, self, *args, **kwargs) File "/opt/mercurial/lib/python3.7/site-packages/hgext/fsmonitor/__init__.py", line 621, in overridestatus node1, node2, match, listignored, listclean, stateunknown, listsubrepos File "/opt/mercurial/lib/python3.7/site-packages/mercurial/localrepo.py", line 3337, in status node2, match, ignored, clean, unknown, listsubrepos File "/opt/mercurial/lib/python3.7/site-packages/mercurial/context.py", line 427, in status ctx1, r, match, listignored, listclean, listunknown File "/opt/mercurial/lib/python3.7/site-packages/mercurial/context.py", line 1940, in _buildstatus s = self._dirstatestatus(match, listignored, listclean, listunknown) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/context.py", line 1863, in _dirstatestatus self._poststatusfixup(s, fixup) File "/opt/mercurial/lib/python3.7/site-packages/mercurial/context.py", line 1829, in _poststatusfixup ps(self, status) File "/opt/mercurial/lib/python3.7/site-packages/hgext/fsmonitor/__init__.py", line 682, in __call__ wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles) File "/opt/mercurial/lib/python3.7/site-packages/hgext/fsmonitor/state.py", line 132, in set file.write(clock + b'\0') TypeError: can only concatenate str (not "bytes") to str ```
Looks like this is the result of Homebrew updating watchman to run with Python3 in https://github.com/Homebrew/homebrew-core/commit/6248156feffe6adb0ffb8752c76b3dfc9be4ad68, released as watchman 4.9.0_4
Note that AFAIK, the python package on Homebrew was already Python 3. This Homebrew watchman formula change was about migrating from Python 3.7 to Python 3.8.
Posted a patch for this on Phab: https://phab.mercurial-scm.org/D8573
Fixed by https://mercurial-scm.org/repo/hg/rev/017cc5ee537f Connor Sheehan <sheehan@mozilla.com> fsmonitor: coerce `clock` variable to byte-string (issue6321) Callers of `fsmonitor.state.setlastclock` pass their arguments wrapped in `pycompat.sysbytes` to ensure the value is a `bytes` on Python 3. However in `fsmonitor.poststatus.__call__`, if the return value of `getlastclock()` is `None`, we use the value of `fsmonitor.poststatus._startclock` instead, which is not converted to a byte string in the same manner. This commit converts the value of `startclock` to a byte string using `pycompat.sysbytes` in the constructor for `poststatus`, to avoid the "`str` + `bytes`" error from issue 6321. Differential Revision: https://phab.mercurial-scm.org/D8573 (please test the fix)
Bug was set to TESTING for 7 days, resolving