/usr/lib/python3/dist-packages/parallel/parallelutil.py is in python3-parallel 0.2.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | class BitaccessMeta(type):
"""meta class that adds bit access properties to a
parallel port implementation"""
def __new__(self, classname, bases, classdict):
klass = type.__new__(self, classname, bases, classdict)
# status lines
klass.paperOut = property(klass.getInPaperOut, None, "Read the PaperOut signal")
# control lines
klass.dataStrobe = property(None, klass.setDataStrobe, "Set the DataStrobe signal")
# XXX ... other bits
# data bits
for bit in range(8):
mask = (1<<bit)
def getter(self, mask=mask):
return (self.getData() & mask) != 0
def setter(self, b, mask=mask):
if b:
self.setData(self.getData() | mask)
else:
self.setData(self.getData() & ~mask)
setattr(klass, "D%d" % bit, property(getter, setter, "Access databit %d" % bit))
# nibbles
for name, shift, width in [('D0_D3', 0, 4), ('D4_D7', 4, 4)]:
mask = (1<<width) - 1
def getter(self, shift=shift, mask=mask):
return (self.getData() >> shift) & mask
def setter(self, b, shift=shift, mask=mask):
self.setData((self.getData() & ~(mask<<shift)) | ((b&mask) << shift))
setattr(klass, name, property(getter, setter, "Access to %s" % name))
return klass
class VirtualParallelPort:
"""provides a virtual parallel port implementation, useful
for tests and simulations without real hardware"""
__metaclass__ = BitaccessMeta
def __init__(self, port=None):
self._data = 0
def setData(self, value):
self._data = value
def getData(self):
return self._data
# inputs return dummy value
def getInPaperOut(self): return self._dummy
# ...
# outputs just store a tuple with (action, value) pair
def setDataStrobe(self, value): self._last = ('setDataStrobe', value)
# ...
# testing
if __name__ == '__main__':
import unittest, sys
class TestBitaccess(unittest.TestCase):
"""Tests a port with no timeout"""
def setUp(self):
self.p = VirtualParallelPort()
def testDatabits(self):
"""bit by bit D0..D7"""
p = self.p
p.D0 = p.D2 = p.D4 = p.D6 = 1
self.failUnlessEqual(p._data, 0x55)
self.failUnlessEqual(
[p.D7, p.D6, p.D5, p.D4, p.D3, p.D2, p.D1, p.D0],
[0, 1, 0, 1, 0, 1, 0, 1]
)
p._data <<= 1
self.failUnlessEqual(
[p.D7, p.D6, p.D5, p.D4, p.D3, p.D2, p.D1, p.D0],
[1, 0, 1, 0, 1, 0, 1, 0]
)
def testDatabitsGroups(self):
"""nibbles D0..D7"""
p = self.p
p.D0_D3 = 14
self.failUnlessEqual(p._data, 0x0e)
p.D0_D3 = 0
p.D4_D7 = 13
self.failUnlessEqual(p._data, 0xd0)
p.D0_D3 = p.D4_D7 = 0xa
self.failUnlessEqual(p._data, 0xaa)
# test bit patterns
for x in range(256):
# test getting
p._data = x
self.failUnlessEqual((p.D4_D7, p.D0_D3), (((x>>4) & 0xf), (x & 0xf)))
# test setting
p._data = 0
(p.D4_D7, p.D0_D3) = (((x>>4) & 0xf), (x & 0xf))
self.failUnlessEqual(p._data, x)
def testStatusbits(self):
"""bit by bit status lines"""
# read the property:
self.p._dummy = 0
self.failUnlessEqual(self.p.paperOut, 0)
self.p._dummy = 1
self.failUnlessEqual(self.p.paperOut, 1)
# read only, must not be writable:
self.failUnlessRaises(AttributeError, setattr, self.p, 'paperOut', 1)
def testControlbits(self):
"""bit by bit control lines"""
self.p.dataStrobe = 0
self.failUnlessEqual(self.p._last, ('setDataStrobe', 0))
self.p.dataStrobe = 1
self.failUnlessEqual(self.p._last, ('setDataStrobe', 1))
# write only, must not be writable:
self.failUnlessRaises(AttributeError, getattr, self.p, 'dataStrobe')
sys.argv.append('-v')
# When this module is executed from the command-line, it runs all its tests
unittest.main()
|