protocol_alt.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #! python
  2. #
  3. # This module implements a special URL handler that allows selecting an
  4. # alternate implementation provided by some backends.
  5. #
  6. # This file is part of pySerial. https://github.com/pyserial/pyserial
  7. # (C) 2015 Chris Liechti <cliechti@gmx.net>
  8. #
  9. # SPDX-License-Identifier: BSD-3-Clause
  10. #
  11. # URL format: alt://port[?option[=value][&option[=value]]]
  12. # options:
  13. # - class=X used class named X instead of Serial
  14. #
  15. # example:
  16. # use poll based implementation on Posix (Linux):
  17. # python -m serial.tools.miniterm alt:///dev/ttyUSB0?class=PosixPollSerial
  18. from __future__ import absolute_import
  19. try:
  20. import urlparse
  21. except ImportError:
  22. import urllib.parse as urlparse
  23. import serial
  24. def serial_class_for_url(url):
  25. """extract host and port from an URL string"""
  26. parts = urlparse.urlsplit(url)
  27. if parts.scheme != 'alt':
  28. raise serial.SerialException(
  29. 'expected a string in the form "alt://port[?option[=value][&option[=value]]]": '
  30. 'not starting with alt:// ({!r})'.format(parts.scheme))
  31. class_name = 'Serial'
  32. try:
  33. for option, values in urlparse.parse_qs(parts.query, True).items():
  34. if option == 'class':
  35. class_name = values[0]
  36. else:
  37. raise ValueError('unknown option: {!r}'.format(option))
  38. except ValueError as e:
  39. raise serial.SerialException(
  40. 'expected a string in the form '
  41. '"alt://port[?option[=value][&option[=value]]]": {!r}'.format(e))
  42. if not hasattr(serial, class_name):
  43. raise ValueError('unknown class: {!r}'.format(class_name))
  44. cls = getattr(serial, class_name)
  45. if not issubclass(cls, serial.Serial):
  46. raise ValueError('class {!r} is not an instance of Serial'.format(class_name))
  47. return (''.join([parts.netloc, parts.path]), cls)
  48. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  49. if __name__ == '__main__':
  50. s = serial.serial_for_url('alt:///dev/ttyS0?class=PosixPollSerial')
  51. print(s)