A Weird Imagination

Eliminating Control.Monad.Error

The problem

Compiling the Haskell package language-python (a dependency of xcffib), I got the following warning stating that the typeclass Error is deprecated:

language-python/src/Language/Python/Common/ParseError.hs:25:10: warning: [-Wdeprecations]
    In the use of type constructor or class ‘Error’
    (imported from Control.Monad.Error.Class, but defined in Control.Monad.Trans.Error):
    Deprecated: "Use Control.Monad.Trans.Except instead"
   |                                 
25 | instance Error ParseError where 
   |          ^^^^^                  

I wasn't sure how to "Use Control.Monad.Trans.Except instead", as Except is not a drop-in replacement for Error.

The solution

As this StackOverflow answer recommended,

Short answer is: Replace Error by nothing at all

The code used throwError, which I replaced with

throwError = lift . Left

Other than that, I just removed the imports of Control.Monad.Error and the typeclass instance of Error. The full diff is in this pull request.

The details

Read more…

Troubleshooting python-xcffib

The problem

The monitor-lock.py script in my previous blog post uses python-xlib, which currently mainly relies on manually porting Xlib functions to Python. This is why it is missing the barrier-related functions I needed in that post. There is work on automating this process, but it appears to be abandoned. I started trying to pick up where they had left off before finding the python-xcffib project which provides auto-generated bindings for libxcb and therefore gives full support for interacting with X at a low level from Python.

python-xcffib (named after the cffi library it uses for binding to the C XCB library) gives a slightly lower-level API than python-xlib, but they are both fairly thin wrappers over the X protocol, so the differences are minor. It was fairly straightforward to port my script from the previous post to use python-xcffib, available as monitor-lock-xcb.py.

Unfortunately, I ran into a bug in python-xcffib:

Traceback (most recent call last):
...
  File "./monitor-lock-xcb.py", line 38, in main
    devices = conn.xinput.XIQueryDevice(xcffib.xinput.Device.AllMaster).reply().infos
...
  File "/usr/lib/python3/dist-packages/xcffib/__init__.py", line 139, in _resize
    assert self.size + increment <= self.known_max
AssertionError

The solution

I've submitted the fix upstream, so most likely you will not encounter this error. Updating to the latest version (after v0.8.1) should be sufficient to fix the problem.

The fix I applied was to modify the module's __init__.py (the location, which may be different on your machine, is in the stack trace). Specifically, on line 108 in the function Unpacker.unpack(), in the call to struct.calcsize(), change fmt to "=" + fmt.

The details

Read more…