question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Errno 1 Operation not permitted

See original GitHub issue

This may not be an issue with periphery itself, but I’m hoping for some help in diagnosing a problem that currently has me stumped.

If I strip my code down the basics, I end up with the follow, that works:

from periphery import GPIO
import multiprocessing as mproc
from time import sleep

def proc1():
  p2=GPIO("/dev/gpiochip0", 2, "in")
  p1=GPIO("/dev/gpiochip0", 1, "out")
  p1.write(True)
  sleep(2)
  p1.write(False)
  p1.close()
  p2.close():

mproc.Process(target=proc).start()

My actual program is more complicated obviously, but at its core I have the same thing happening. A process forked from the main process accessing multiple pins. I can open the pins no problem, I can read all of them no problem, but I get errors when I try to call write on the GPIO instance.

Test and program run using sudo python3 so permissions shouldn’t be an issue. I also tried running python3 directly as root using sudo -i but no change.

I have different results on different hardware, currently I have an RPi3B and an Orange Pi Zero LTS.

  • RPi throws err 22 Invalid argument.
  • OPi thorws err 1 Operation not permitted.

Any pointers on where to look or how to get more debug information would be most appreciated. For reference, I am working on switching MQTTany over to cdev gpio access and found this library to be the best option. The branch is private, but if you are willing to dig that deep into it, I can publish it.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
vsergeevcommented, Oct 23, 2020

It is actually behaving as you think – the PermissionError is getting caught in that except block – but you’re also seeing Python 3’s more thorough chained exception trackback reporting. You can prove to yourself that the PermissionError is getting caught in the except block by adding print(e) or print(isinstance(e, PermissionError)) before the raise GPIOError(...), or by forcing it to cause another known OSError, like setting self._line_fd to a bogus file descriptor, e.g. 99, before the fcntl.ioctl(), to see that the reporting is similar.

As for the reporting, there’s three ways of handling this in Python 3:

Current/do nothing way:

try:
    fcntl.ioctl(self._line_fd, CdevGPIO._GPIOHANDLE_SET_LINE_VALUES_IOCTL, data)
except (OSError, IOError) as e:
    raise GPIOError(e.errno, "Setting line value: " + e.strerror)

Results in what you’ve seen:

Traceback (most recent call last):
  File "/home/alarm/python-periphery/periphery/gpio.py", line 683, in write
    fcntl.ioctl(self._line_fd, CdevGPIO._GPIOHANDLE_SET_LINE_VALUES_IOCTL, data)
PermissionError: [Errno 1] Operation not permitted

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_perm.py", line 10, in <module>
    gpio_in.write(False)
  File "/home/alarm/python-periphery/periphery/gpio.py", line 686, in write
    raise GPIOError(e.errno, "Setting line value: " + e.strerror)

This reports both exceptions involved, but is somewhat confusing as you’ve pointed out, because it seems like two unrelated exceptions occurred.

Explicit exception chaining:

try:
    fcntl.ioctl(self._line_fd, CdevGPIO._GPIOHANDLE_SET_LINE_VALUES_IOCTL, data)
except (OSError, IOError) as e:
    raise GPIOError(e.errno, "Setting line value: " + e.strerror) from e

Results in:

Traceback (most recent call last):
  File "/home/alarm/python-periphery/periphery/gpio.py", line 683, in write
    fcntl.ioctl(self._line_fd, CdevGPIO._GPIOHANDLE_SET_LINE_VALUES_IOCTL, data)
PermissionError: [Errno 1] Operation not permitted

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "test_perm.py", line 10, in <module>
    gpio_in.write(False)
  File "/home/alarm/python-periphery/periphery/gpio.py", line 685, in write
    raise GPIOError(e.errno, "Setting line value: " + e.strerror) from e
periphery.gpio.GPIOError: [Errno 1] Setting line value: Operation not permitted

This provides the same chained exception context as above, but the reporting is not as confusing as the unlinked version. This is the style I would prefer for Python 3.

Exception suppression:

try:
    fcntl.ioctl(self._line_fd, CdevGPIO._GPIOHANDLE_SET_LINE_VALUES_IOCTL, data)
except (OSError, IOError) as e:
    raise GPIOError(e.errno, "Setting line value: " + e.strerror) from None

Results in:

Traceback (most recent call last):
  File "test_perm.py", line 10, in <module>
    gpio_in.write(False)
  File "/home/alarm/python-periphery/periphery/gpio.py", line 685, in write
    raise GPIOError(e.errno, "Setting line value: " + e.strerror) from None
periphery.gpio.GPIOError: [Errno 1] Setting line value: Operation not permitted

This suppresses the underlying exception, and is probably what you were expecting. This is how Python 2 reports an exception traceback, as exception chaining isn’t available in Python 2.


Unfortunately, since it’s still a goal of python-periphery to support both Python 2 and Python 3 seamlessly, we can’t use the from e or from None, as that syntax isn’t available in Python 2. So we have to settle for the slightly confusing reporting under Python 3. Note that it will only be shown when printing a traceback. Programatically, you would just catch GPIOError as usual.

0reactions
CrazyIvan359commented, Oct 23, 2020

Thank you for the detailed explaination! I was not even aware of that syntax in Python 3. I agree with everything. Too bad Python doesn’t have the dynamic includes you can do with C.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[Errno 1] Operation not permitted after macOS Catalina ...
Click the Apple icon in the top left corner of the screen · Go to System settings... · Select Privacy and Security in...
Read more >
[Errno 1] Operation not permitted - Python Forum
Python is asking the OS to complete the lchown(), but the OS said the operation failed. Usually, this means you don't have permission...
Read more >
OSError: [Errno 1] Operation not permitted - pip install
The "OSError: [Errno 1] Operation not permitted" error is often caused by having incompatible versions of packages on a macOS machine. To solve...
Read more >
[Errno 1] Operation not permitted: (on a macOS Catalina ...
The error you are getting is probably because you imported that file from somewhere and its restringed for security. I hope it helps…...
Read more >
What is this error? PermissionError: [Errno 1] Operation not ...
What is this error? PermissionError: [Errno 1] Operation not permitted: '/dev/shm' · For detailed output, run func with --verbose flag. · [2022-02-17T08:48:00.818 ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found