PageRenderTime 28ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/site/cl-python/core/exceptions.lisp

https://github.com/vikram/lisplibraries
Lisp | 144 lines | 104 code | 27 blank | 13 comment | 2 complexity | eb72314ec25c75f0ab43dc14b6712df2 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, LGPL-3.0, BSD-3-Clause, GPL-2.0
  1. ;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CLPYTHON; Readtable: PY-AST-USER-READTABLE -*-
  2. ;;
  3. ;; This software is Copyright (c) Franz Inc. and Willem Broekema.
  4. ;; Franz Inc. and Willem Broekema grant you the rights to
  5. ;; distribute and use this software as governed by the terms
  6. ;; of the Lisp Lesser GNU Public License
  7. ;; (http://opensource.franz.com/preamble.html),
  8. ;; known as the LLGPL.
  9. ;;;; Python Exceptions
  10. (in-package :clpython)
  11. (in-syntax *ast-user-readtable*)
  12. ;; Depending on the Lisp implementation, the exceptions are either Python objects with
  13. ;; the appropriate metaclass, or fairly normal Lisp conditions.
  14. #+clpython-exceptions-are-python-objects
  15. (progn
  16. (defun py-raise (exc-type string &rest format-args)
  17. "Raise a Python exception with given format string"
  18. (error exc-type :args (cons string format-args)))
  19. (defclass {Exception} (object error)
  20. ((args :initarg :args :initform nil :documentation "Arguments as Lisp list"
  21. :accessor exception-args))
  22. (:metaclass py-type))
  23. (def-py-method {Exception.__new__} :static (cls &rest args)
  24. (make-instance cls))
  25. (def-py-method {Exception.__init__} (x &rest args)
  26. ;; raise AttributeError("a %s b", 24) => AttributeError: "a 24 b"
  27. (when (and (>= (length args) 2)
  28. (stringp (car args)))
  29. (setf args (py-string.__mod__ (car args) (cdr args))))
  30. (setf (exception-args x) args))
  31. (def-py-method {Exception.__repr__} (x)
  32. (with-output-to-string (s)
  33. (print-object x s)))
  34. (defun define-exception-subclass (exc-name &rest supers)
  35. (dolist (s supers) (check-type s symbol))
  36. (ensure-class exc-name
  37. :direct-superclasses supers
  38. :metaclass 'py-type)))
  39. #-clpython-exceptions-are-python-objects
  40. (progn
  41. (defun py-raise (exc-type string &rest format-args)
  42. "Raise a Python exception with given format string"
  43. (error exc-type :args (cons string format-args)))
  44. (define-condition {Exception} (error)
  45. ((args :initarg :args :initform nil :documentation "Arguments as Lisp list"
  46. :accessor exception-args)))
  47. (defun define-exception-subclass (exc-name &rest supers)
  48. (eval `(define-condition ,exc-name ,supers nil))))
  49. ;; Works in #+/#- either case
  50. (defmethod print-object ((x {Exception}) stream)
  51. (format stream "~A" (class-name (class-of x)))
  52. (whereas ((args (exception-args x)))
  53. (destructuring-bind (string . format-args)
  54. args
  55. (format stream ": ~@<~@;~A~:>" (if format-args (apply #'format nil string format-args) string)))))
  56. (defparameter *exception-tree* ;; XXX CPython has explanation string for every exception
  57. `({SystemExit}
  58. {StopIteration}
  59. {GeneratorExit}
  60. ({StandardError} {KeyboardInterrupt}
  61. {ImportError}
  62. ({EnvironmentError} {IOError}
  63. ({OSError} {WindowsError}
  64. {VMSError} ))
  65. {EOFError}
  66. ({RuntimeError} {NotImplementedError} )
  67. ({NameError} {UnboundLocalError} )
  68. {AttributeError}
  69. ({SyntaxError} ({IndentationError} {TabError})
  70. {UnexpectedEofError}) ;; UnexpectedEof: not std Python
  71. {TypeError}
  72. {AssertionError}
  73. ({LookupError} {IndexError}
  74. {KeyError})
  75. ({ArithmeticError} {OverflowError}
  76. {ZeroDivisionError}
  77. {FloatingPointError} )
  78. ({ValueError} ({UnicodeError} {UnicodeEncodeError}
  79. {UnicodeDecodeError}
  80. {UnicodeTranslateError} ))
  81. {ReferenceError}
  82. {SystemError}
  83. {MemoryError} )
  84. ({Warning} {DeprecationWarning}
  85. {FutureWarning}
  86. {ImportWarning}
  87. {OverflowWarning}
  88. {PendingDeprecationWarning}
  89. {SyntaxWarning}
  90. {RuntimeWarning}
  91. {UserWarning} )))
  92. (defvar *exception-classes* ())
  93. (defun def-python-exceptions-1 (parent child-tree)
  94. (declare (optimize (debug 3))
  95. (notinline def-python-exceptions))
  96. (flet ((def-sub-exc (super exc-name)
  97. (push (define-exception-subclass exc-name super) *exception-classes*)))
  98. (if (symbolp child-tree)
  99. (def-sub-exc parent child-tree)
  100. (progn
  101. (def-sub-exc parent (car child-tree))
  102. (loop for subchild in (cdr child-tree)
  103. do (def-python-exceptions-1 (car child-tree) subchild))))))
  104. (defun def-python-exceptions ()
  105. (setf *exception-classes* (list (find-class '{Exception})))
  106. (loop for branch in *exception-tree*
  107. do (def-python-exceptions-1 '{Exception} branch)))
  108. (def-python-exceptions)
  109. (defparameter *cached-StopIteration*
  110. #+clpython-exceptions-are-python-objects
  111. (make-instance '{StopIteration} :args (list "Iterator has finished"))
  112. #-clpython-exceptions-are-python-objects
  113. (make-condition '{StopIteration})
  114. "Shared instance of this commonly used exception")
  115. (defun raise-StopIteration ()
  116. (error *cached-StopIteration*))
  117. (setf *exceptions-loaded* t)