bendudson / py4cl

Call python from Common Lisp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

String literals with newlines throw errors

gregcman opened this issue · comments

(python-call "len" "foo
")
Python error: "EOL while scanning string literal (<string>, line 1)"
   [Condition of type PYTHON-ERROR]

Possible workaround:

(defun pystr (obj)
  (remote-objects
    (python-eval
     (format nil "\"\"\"~a\"\"\""
	     (let ((seq (write-to-string obj
					 :escape t
					 :readably t)))
	       (subseq seq 1 (1- (length seq))))))))
 (python-call "len" (pystr "foo
"))
=>
4

Perhaps this could be incorporated into (pythonize ((obj string))) ?

This... does work in py4cl2. Turns out something like that has been incorporated there:

(defmethod pythonize ((obj string))
  (let ((python-value (cdr (assoc obj *lisp-to-python-alist* :test 'equalp))))
    (cond (python-value python-value)
          ((find-if (lambda (ch) (char= #\newline ch)) obj)
           (with-output-to-string (return-string)
             (write-string "\"\"\"" return-string)
             (write-string
              (let ((escaped-string (write-to-string (coerce obj
                                                             '(vector character))
                                                     :escape t :readably t)))
                (subseq escaped-string 1 (1- (length escaped-string))))
              return-string)
             (write-string "\"\"\"" return-string)))
          (t (write-to-string (coerce obj '(vector character))
                              :escape t :readably t)))))

If this qualifies as a non-breaking fix, I (or someone) might issue a PR here.