2
\$\begingroup\$

I implemented a virtual file system library with POSIX file mode representation.
Any suggestions regarding optimization are welcome.

"""POSIX file system library."""
from collections import namedtuple
__all__ = ['PosixPermission', 'PosixMode']
MIN_PERM = 0b000
MAX_PERM = 0b111
DEF_PERM = 0b110 # rw-
MIN_MODE = 0o000
MAX_MODE = 0o777
DEF_MODE = 0o640
class PosixPermission(namedtuple('PosixPermission', 'read write execute')):
 """POSIX file permissions."""
 @classmethod
 def from_int(cls, perm=DEF_PERM):
 """Creates the file permissions from the respective integer value."""
 if MIN_PERM <= perm <= MAX_PERM:
 return cls(bool(perm & 4), bool(perm & 2), bool(perm & 1))
 raise ValueError('Permission value must be between {} and {}.'.format(
 MIN_PERM, MAX_PERM))
 def __int__(self):
 """Returns the integer value of the file permission."""
 return (self.read and 4) + (self.write and 2) + (self.execute and 1)
 def __str__(self):
 """Returns binary representation of the file permission."""
 return ''.join(map(
 lambda perm: perm or '-',
 (self.read and 'r', self.write and 'w', self.execute and 'x')))
class PosixMode(namedtuple('PosixMode', 'user group other')):
 """POSIX file mode."""
 @classmethod
 def from_int(cls, mode=DEF_MODE):
 """Creates the file mode from the respective integer value."""
 if MIN_MODE <= mode <= MAX_MODE:
 return cls(
 PosixPermission.from_int(mode >> 6 & 7),
 PosixPermission.from_int(mode >> 3 & 7),
 PosixPermission.from_int(mode & 7))
 raise ValueError('File mode must be between {} and {}.'.format(
 oct(MIN_MODE), oct(MAX_MODE)))
 def __int__(self):
 """Returns the integer value of the file mode."""
 return (int(self.user) << 6) + (int(self.group) << 3) + int(self.other)
 def __str__(self):
 """Returns the octal representation of the file mode."""
 return ''.join((str(self.user), str(self.group), str(self.other)))
asked Nov 22, 2017 at 9:04
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I'm confused why you're using a named tuple for PosixPermission. To me an Enum would be a better choice:

class PosixPermission(Flag):
 READ = 4
 WRITE = 2
 EXECUTE = 1
 NONE = 0
 @property
 def perms(self):
 return ''.join(
 name if self & val else '-'
 for name, val in zip('rwx', PosixPermission)
 )
>>> PosixPermission(0)
<PosixPermission.NONE: 0>
>>> PosixPermission(7)
<PosixPermission.READ|WRITE|EXECUTE: 7>
>>> PosixPermission(5)
<PosixPermission.READ|EXECUTE: 5>
>>> PosixPermission(5).perms
'r-x'
>>> PosixPermission(5) & PosixPermission.READ
<PosixPermission.READ: 4>
>>> PosixPermission(5) & PosixPermission.WRITE
<PosixPermission.NONE: 0>
>>> PosixPermission(8)
Traceback (most recent call last):
ValueError: 8 is not a valid PosixPermission

Honestly PosixMode looks pretty good, I think it's reasonable to assume it to be a namedtuple, rather than an object with __slots__. I however wouldn't use __int__ and __str__, and would instead use properties for these.

answered Nov 22, 2017 at 10:01
\$\endgroup\$
7
  • \$\begingroup\$ I do not understand your enum approach. How would I get a permission instance of, let's say r-x (read, not write, execute) with it? \$\endgroup\$ Commented Nov 22, 2017 at 10:05
  • \$\begingroup\$ @RichardNeumann As demonstrated above, PosixPermission(5). \$\endgroup\$ Commented Nov 22, 2017 at 10:07
  • \$\begingroup\$ Ah. Got it. But then I could not do if posix_mode.user.write without adding the write property, which I already have on the namedtuple. \$\endgroup\$ Commented Nov 22, 2017 at 10:09
  • 2
    \$\begingroup\$ @RichardNeumann You can however use if posix_mode.user & PosixPermission.WRITE. If you don't like the length of it, you can just make PosixPermission.WRITE a variable, and use if posix_mode.user&WRITE. \$\endgroup\$ Commented Nov 22, 2017 at 10:09
  • \$\begingroup\$ @MaartenFabré That's exactly what I meant to say in my last comment. \$\endgroup\$ Commented Nov 22, 2017 at 11:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.