def parser(self):
        """
        Get a function for parsing a datagram read from a I{tap} device.

        @return: A function which accepts a datagram exactly as might be read
            from a I{tap} device.  The datagram is expected to ultimately carry
            a UDP datagram.  When called, it returns a L{list} of L{tuple}s.
            Each tuple has the UDP application data as the first element and
            the sender address as the second element.
        """
        datagrams = []
        receiver = DatagramProtocol()

        def capture(*args):
            datagrams.append(args)

        receiver.datagramReceived = capture

        udp = RawUDPProtocol()
        udp.addProto(12345, receiver)

        ip = IPProtocol()
        ip.addProto(17, udp)

        ether = EthernetProtocol()
        ether.addProto(0x800, ip)

        def parser(datagram):
            # TAP devices might include a PI header.  Strip that off if we
            # expect it to be there.
            if self.pi:
                datagram = datagram[_PI_SIZE:]

            # TAP devices include ethernet framing so start parsing at the
            # ethernet layer.
            ether.datagramReceived(datagram)
            return datagrams

        return parser

        Get a function for parsing a datagram read from a I{tap} device.

        @return: A function which accepts a datagram exactly as might be read
            from a I{tap} device.  The datagram is expected to ultimately carry
            a UDP datagram.  When called, it returns a L{list} of L{tuple}s.
            Each tuple has the UDP application data as the first element and
            the sender address as the second element.
        
stackoverflow/venv/lib/python3.6/site-packages/twisted/pair/test/test_tuntap.py