summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/language/python/compile.scm10
-rw-r--r--modules/language/python/exceptions.scm43
-rw-r--r--modules/language/python/module.scm22
-rw-r--r--modules/language/python/module/io.scm481
-rw-r--r--modules/language/python/module/os.scm7
-rw-r--r--modules/language/python/module/python.scm56
-rw-r--r--modules/language/python/module/subprocess.py5
-rw-r--r--modules/language/python/with.scm2
8 files changed, 538 insertions, 88 deletions
diff --git a/modules/language/python/compile.scm b/modules/language/python/compile.scm
index e5bc219..fe3533b 100644
--- a/modules/language/python/compile.scm
+++ b/modules/language/python/compile.scm
@@ -1407,7 +1407,8 @@
,(C 'clear-warning-data)
(fluid-set! (@@ (system base message) %dont-warn-list) '())
,@(map (lambda (s) `(,(C 'var) ,s)) globs)
- ,@(map (g globs exp) x))))))
+ ,@(map (g globs exp) x)
+ (,(C 'export-all)))))))
(define-syntax-parameter break
(lambda (x) #'(values)))
@@ -1932,3 +1933,10 @@
((_ #t) #t)
((_ #f) #f)
((_ x ) (bool x))))
+
+(define (export-all)
+ (define mod (current-module))
+ (if (module-defined? mod '__all__)
+ (for ((x : (module-ref mod '__all__))) ()
+ (module-export! mod (string->symbol (scm-str x))))))
+
diff --git a/modules/language/python/exceptions.scm b/modules/language/python/exceptions.scm
index 60b850e..99e8b97 100644
--- a/modules/language/python/exceptions.scm
+++ b/modules/language/python/exceptions.scm
@@ -7,28 +7,11 @@
SyntaxError SystemException
OSError ProcessLookupError PermissionError
None NotImplemented NotImplementedError
- RunTimeError AssertionError))
+ RunTimeError AssertionError
+ ModuleNotFoundError BlockingIOError))
(define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
-(define StopIteration 'StopIteration)
-(define GeneratorExit 'GeneratorExit)
-(define SystemException 'SystemException)
-(define RuntimeError 'RuntimeError)
-(define IndexError 'IndexError)
-(define ValueError 'ValueError)
-(define None 'None)
-(define KeyError 'KeyError)
-(define TypeError 'TypeError)
-(define AttributeError 'AttributeError)
-(define SyntaxError 'SyntaxError)
-(define OSError 'OSError)
-(define ProcessLookupError 'ProcessLookupError)
-(define PermissionError 'PermissionError)
-(define NotImplementedError 'NotImplementedError)
-(define RunTimeError 'RunTimeError)
-(define AssertionError 'AssertionError)
-
(define-python-class Exception ()
(define __init__
(case-lambda
@@ -45,6 +28,28 @@
(format #f "~a"
(ref self '__name__))))))
+(define-syntax-rule (define-er nm k)
+ (define-python-class nm (Exception)))
+
+(define StopIteration 'StopIteration)
+(define GeneratorExit 'GeneratorExit)
+(define-er SystemException 'SystemException)
+(define-er RuntimeError 'RuntimeError)
+(define-er IndexError 'IndexError)
+(define-er ValueError 'ValueError)
+(define None 'None)
+(define-er KeyError 'KeyError)
+(define-er TypeError 'TypeError)
+(define-er AttributeError 'AttributeError)
+(define-er SyntaxError 'SyntaxError)
+(define-er OSError 'OSError)
+(define-er ProcessLookupError 'ProcessLookupError)
+(define-er PermissionError 'PermissionError)
+(define-er NotImplementedError 'NotImplementedError)
+(define-er RunTimeError 'RunTimeError)
+(define AssertionError 'AssertionError)
+(define-er ModuleNotFoundError 'ModuleNotFoundError)
+(define-er BlockingIOError 'BlockingIOError)
(define NotImplemented (list 'NotImplemented))
diff --git a/modules/language/python/module.scm b/modules/language/python/module.scm
index 2940a9a..53aa1c2 100644
--- a/modules/language/python/module.scm
+++ b/modules/language/python/module.scm
@@ -44,14 +44,14 @@
(rawset self '_isprivate p)))
(define _cont
- (lambda (self id pre l nm)
+ (lambda (self id pre l nm skip-error?)
(if id
(aif it (rawref self id)
((ref it '__init__) pre l nm)
(begin
(rawset self id (Module pre l nm))
- (_make self pre nm)))
- (_make self pre nm))))
+ (_make self pre nm skip-error?)))
+ (_make self pre nm skip-error?))))
(define _contupdate
(lambda (self id pre l nm)
@@ -67,15 +67,15 @@
(match l
((name)
(set self '_path (reverse (cons name pre)))
- (_cont self #f (cons name pre) #f (cons name nm)))
+ (_cont self #f (cons name pre) #f (cons name nm) #f))
((name . (and l (name2 . _)))
(set self '_path (reverse (cons name pre)))
- (_cont self name2 (cons name pre) l (cons name nm)))))
+ (_cont self name2 (cons name pre) l (cons name nm) #t))))
((self l nm)
- (_cont self #f l #f nm))
+ (_cont self #f l #f nm #f))
((self l)
(if (pair? l)
@@ -117,14 +117,20 @@
(string-split l #\.)))))))
(define _make
- (lambda (self l nm)
+ (lambda (self l nm skip-error?)
(rawset self '_private #f)
(if (not (rawref self '_module))
(begin
(set self '__dict__ self)
(set self '__name__ (string-join
(map symbol->string (reverse nm)) "."))
- (let ((_module (in-scheme (resolve-module (reverse l)))))
+ (let* ((_module (in-scheme (resolve-module (reverse l))))
+ (public-i (and _module (module-public-interface _module))))
+ (if (and (not skip-error?) (not public-i))
+ (raise (ModuleNotFoundError
+ (format #f "No module named ~a"
+ (ref self '__name__)))))
+
(set self '_export (module-public-interface _module))
(set self '_module _module)
(hash-set! _modules l self))))))
diff --git a/modules/language/python/module/io.scm b/modules/language/python/module/io.scm
new file mode 100644
index 0000000..b2f9342
--- /dev/null
+++ b/modules/language/python/module/io.scm
@@ -0,0 +1,481 @@
+(define-module (language python module io)
+ #:use-module (language python module exceptions)
+ #:use-module ((language python module os)
+ #:select (get_blocking))
+ #:re-export (BlockingIOError)
+ #:export (UnsupportedOperation scm-port open DEFAULT_BUFFER_SIZE
+ IOBase RawIOBase BufferedIOBase FileIO
+ BytesIO BufferedReader BufferedWriter
+ BufferedRandom TextIOBase TextIOWrapper
+ StringIO))
+
+
+
+(define (scm-port x)
+ (if (port? x)
+ x
+ (aif it (ref x '_port)
+ it
+ (raise ValueError "no port in scm-port"))))
+
+(define-python-class UnsupportedOperation (OSError ValueError))
+
+(define DEFAULT_BUFFER_SIZE 4096)
+
+(define (path-it path)
+ (aif it (ref path '__fspath__)
+ (it)
+ path))
+
+(def (open- path
+ (= mode "r")
+ (= buffering -1 )
+ (= encoding None)
+ (= errors None)
+ (= newline None)
+ (= closefd #t)
+ (= opener None))
+
+ (define modelist (string->list mode))
+ (define path (path-it path))
+ (define (clean ch l)
+ (filter (lambda (c) (not (eq? ch c))) l))
+ (let ((port (if (number? path)
+ (begin
+ (if (member #\a modelist)
+ (seek path 0 SEEK_END))
+ (if (member #\x modelist)
+ (error "cannot use mode 'x' for fd input"))
+ (cond
+ ((member #\r modelist)
+ (fdes->inport path))
+ ((member #\w modelist)
+ (fdes->outport path))))
+ (begin
+ (if (member #\x modelist)
+ (if (file-exists? path)
+ (raise OSError "mode='x' and file exists")
+ (set mode (list->string
+ (clean #\x modelist)))))
+ ((@ (guile) open-file) (path-it path) mode))))
+
+ (errors (if (bool errors)
+ (scm-str errors)
+ (let ((s (port-conversion-strategy port)))
+ (cond
+ ((eq? s 'error) "strict")
+ ((eq? s 'substitute) "replace")
+ ((eq? s 'escape) "basckslashreplace")))))
+
+ (encoding (if (eq? encoding None)
+ (port-encoding port)
+ encoding)))
+
+
+ ;; encoding
+ (set self 'encoding encoding)
+ (set-port-encoding! port encoding)
+
+ (case buffering
+ ((-1)
+ (setvbuf port 'block DEFAULT_BUFFER_SIZE))
+ ((0)
+ (setvbuf port 'none))
+ ((1)
+ (setvbuf port 'line))
+ (else
+ (setvbuf port 'block buffering)))
+
+ (cond
+ ((equal? errors "strict")
+ (set-port-conversion-strategy! port 'error))
+ ((equal? errors "replace")
+ (set-port-conversion-strategy! port 'substitute))
+ ((equal? errors "basckslashreplace")
+ (set-port-conversion-strategy! port 'escape))
+ (else
+ (set-port-conversion-strategy! port 'escape)))
+
+ port))
+
+
+(def (open path
+ (= mode "r")
+ (= buffering -1 )
+ (= encoding None)
+ (= errors None)
+ (= newline None)
+ (= closefd #t)
+ (= opener None))
+
+ (let ((F
+ (FileIO (cons
+ (open path mode buffering encoding errors
+ newline closefd opener)
+ path)
+ mode)))
+ (if (member #\b (string->list mode))
+ F
+ (TextIOWrapper F encoding errors))))
+
+
+;;ABC
+
+(define-syntax-rule (check self . l)
+ (aif it (ref self 'raw)
+ (let ((self it))
+ (if (ref self 'closed)
+ (raise ValueError "IO operation on closed port"))
+ . l)
+ (begin
+ (if (ref self 'closed)
+ (raise ValueError "IO operation on closed port"))
+ . l)))
+
+(define-python-class IOBase ()
+ (define __init__
+ (lambda (self port)
+ (set self '_port port)
+ (set self 'closed (port-closed? port))))
+
+ (define __getport__
+ (lambda (self)
+ (check self
+ (ref self _port))))
+
+ (define close
+ (lambda (self)
+ (check self
+ (close-port (ref self '_port))
+ (set self 'closed #t))))
+
+ (define __enter__
+ (lambda (self)
+ (check self)
+ self))
+
+ (define __exit__
+ (lambda (self . x)
+ (check self
+ ((ref self 'close)))))
+
+ (define flush
+ (lambda (self)
+ (check self
+ (if ((ref self readable)) (drain-input (ref self '_port)))
+ (if ((ref self writeable)) (force-output (ref self '_port))))))
+
+ (define isatty
+ (lambda (self)
+ (check self
+ (isatty? (ref self '_port)))))
+
+ (define __iter__
+ (lambda (self)
+ (check self)
+ self))
+
+ (define __next__
+ (lambda (self)
+ (check self
+ (raise StopIteration))))
+
+ (define readable
+ (lambda (self)
+ (check self
+ (output-port? (ref self '_port)))))
+
+ (define readline
+ (lam (self (= size -1))
+ (check self
+ (raise UnsupportedOperation))))
+
+ (define readlines
+ (lam (self (= hint -1))
+ (check self
+ (raise UnsupportedOperation))))
+
+ (define seekable
+ (lambda (self)
+ (check self
+ (catch #t
+ (lambda () (seek (ref self '_port) 0 SEEK_CUR) #t)
+ (lambda x #f)))))
+
+ (define seek
+ (lambda* (self offset #:optional (whence SEEK_SET))
+ (check self
+ (if (not ((ref self seekable)))
+ (raise (ValueError "Not seekable")))
+ (seek (ref self '_port) offset whence))))
+
+
+ (define tell
+ (lambda (self)
+ (check self
+ (ftell (ref self '_port)))))
+
+ (define truncate
+ (lam (self (size None))
+ (check self
+ (if (eq? size None)
+ (truncate-file (ref self '_port))
+ (truncate-file (ref self '_port) size)))))
+
+
+ (define writable
+ (lambda (self)
+ (check self
+ (input-port? (ref self '_port)))))
+
+ (define writelines
+ (lambda (self lines)
+ (check self
+ (raise UnsupportedOperation))))
+
+ (define __del__
+ (lambda (self
+ ((ref self 'close))))))
+
+
+
+
+
+
+(define-python-class RawIOBase (IOBase)
+ (define read
+ (lambda (self #:optional (size -1))
+ (check self
+ (bytes
+ (if (< size 0)
+ ((ref self 'readall))
+ (get-bytevector-n (ref self '_port) size))))))
+
+
+ (define readall
+ (lambda (self)
+ (check self
+ (bytes
+ (get-bytevector-all (ref self '_port))))))
+
+ (define readinto
+ (lambda (self b)
+ (check self
+ (let* ((n (len b))
+ (b (scm-bytevector b))
+ (m (get-bytevector-n! (ref self '_port) b 0 n)))
+ (if (eof? m)
+ (if (get_blocking port)
+ 0
+ None))))))
+
+ (define write
+ (lambda (self b)
+ (check self
+ (let ((n (len b))
+ (b (scm-bytevector b)))
+ (put-bytevector (ref self '_port) b 0 n)
+ n)))))
+
+
+(define-python-class BufferedIOBase (RawIOBase)
+ (define detach
+ (lambda (self)
+ (check self
+ (raise UnsupportedOperation "detach"))))
+
+ (define read1
+ (lambda* (self #:optional (size -1))
+ (check self
+ ((ref self 'read) size))))
+
+ (define readinto1
+ (lambda (self b)
+ (check self
+ ((ref self 'readinto) b)))))
+
+(define-python-class FileIO (RawIOBase)
+ (define __init__
+ (lam (self name (= mode 'r') (= closefd #t) (= opener None))
+ (if (pair? name)
+ (set self '_port (car name))
+ (set self '_port
+ (open_ it
+ #:mode mode
+ #:closefd closefd
+ #:opener opener)))
+ (set self 'mode mode)
+ (set self 'name (cdr name)))))
+
+
+(define-python-class BytesIO (BufferedIOBase)
+ (define __init__
+ (lambda* (self #:optional (initial_bytes None))
+ (if (eq? initial_bytes None)
+ (call-with-values open-bytevector-output-port
+ (lambda (port get-bytevector)
+ (set self '_port port)
+ (set self '_gtbv get-bytevector)))
+ (set self '_port
+ (open-bytevector-input-port initial_bytes)))))
+
+ (define getvalue
+ (lambda (self)
+ (check self
+ (bytes ((ref self '_gtbv)))))))
+
+(define-python-class BufferedReader (BufferedIOBase)
+ (define __init__
+ (lambda* (self raw #:optional (buffer_size DEFAULT_BUFFER_SIZE))
+ (let ((port (ref raw '_port)))
+ (case buffer_size
+ ((0)
+ (setvbuf port 'none))
+ ((1)
+ (setvbuf port 'line))
+ (else
+ (setvbuf port 'block buffer_size))))
+ (set self 'raw raw)))
+
+ (define peek
+ (lambda (self)
+ (raise UnsupportedOperation peek))))
+
+(define-python-class BufferedWriter (BufferedIOBase)
+ (define __init__
+ (lambda* (self raw #:optional (buffer_size DEFAULT_BUFFER_SIZE))
+ (let ((port (ref raw '_port)))
+ (case buffer_size
+ ((0)
+ (setvbuf port 'none))
+ ((1)
+ (setvbuf port 'line))
+ (else
+ (setvbuf port 'block buffer_size))))
+ (set self 'raw raw))))
+
+(define-python-class BufferedRandom (BufferedIOBase)
+ (define __init__
+ (lambda* (self raw #:optional (buffer_size DEFAULT_BUFFER_SIZE))
+ (let ((port (ref raw '_port)))
+ (case buffer_size
+ ((0)
+ (setvbuf port 'none))
+ ((1)
+ (setvbuf port 'line))
+ (else
+ (setvbuf port 'block buffer_size))))
+ (set self 'raw raw)))
+
+ (define peek
+ (lambda (self)
+ (raise UnsupportedOperation peek))))
+
+(use-modules (ice-9 textual-ports))
+(use-modules (ice-9 rdelim))
+
+(define-python-class TextIOBase (IOBase)
+ (define read
+ (lambda (self size)
+ (check self
+ (let ((port (ref self '_port)))
+ (get-string-n port size)))))
+
+ (define readline
+ (lam (self (= size -1))
+ (check self
+ (let ((port (ref self '_port)))
+ (read-line port 'concat)))))
+
+ (define write
+ (lambda (self s)
+ (check self
+ (let ((port (ref self '_port)))
+ (put-string port (scm-str s) 0 (len s))
+ (len s))))))
+
+(define (get-port x)
+ (aif it (ref x '_port)
+ it
+ (aif it (ref x 'raw)
+ (get-port it)
+ (raise (ValueError "No port associated to IO wrapper")))))
+
+(define-python-class TextIOWrapper (TextIOBase)
+ (define __init__
+ (lam (self buffer
+ (= encoding None)
+ (= errors None)
+ (= newline None)
+ (= line_buffering #f)
+ (= write_through #f))
+ (set self 'raw buffer)
+ (let* ((port (get-port buffer))
+ (errors (if (bool errors)
+ (scm-str errors)
+ (let ((s (port-conversion-strategy port)))
+ (cond
+ ((eq? s 'error) "strict")
+ ((eq? s 'substitute) "replace")
+ ((eq? s 'escape) "basckslashreplace")))))
+ (encoding (if (eq? encoding None)
+ (port-encoding port)
+ encoding)))
+ ;; encoding
+ (set self 'encoding encoding)
+ (set-port-encoding! port encoding)
+
+ ;; buffering
+ (if line_buffering
+ (setvbuf port 'line))
+
+ (set self 'line_buffering line_buffering)
+
+ ;; errors
+ (set self 'error errors)
+ (cond
+ ((equal? errors "strict")
+ (set-port-conversion-strategy! port 'error))
+ ((equal? errors "replace")
+ (set-port-conversion-strategy! port 'substitute))
+ ((equal? errors "basckslashreplace")
+ (set-port-conversion-strategy! port 'escape))
+ (else
+ (set-port-conversion-strategy! port 'escape)))
+
+ ;; write trough
+ (set self 'write_trough write_trough)))))
+
+(define-python-class StringIO (TextIOBase)
+ (define __init__
+ (lam (self (= initial_value "") (= newline "\n"))
+ (set self 'newline newline)
+ (if (equal? initial_value "")
+ (set self '_port (open-output-str))
+ (set self '_port (open-input-str initial_value)))))
+
+ (define getvalue
+ (lambda (self)
+ (check self
+ (get-output-string (ref self port))))))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(define-python-class TextIOWrapper (TextIOBase))
+(define-python-class StringIO (TextIOBase))
+
diff --git a/modules/language/python/module/os.scm b/modules/language/python/module/os.scm
index 863287d..757d549 100644
--- a/modules/language/python/module/os.scm
+++ b/modules/language/python/module/os.scm
@@ -694,9 +694,10 @@
(rm (fcntl3 fd F_GETFL (logand o (lognot O_NONBLOCK)))))))
(define (get_blocking fd)
- (if (= (logand O_NONBLOCK (rm (fcntl2 fd F_GETFL))) 0)
- #f
- #t))
+ (let ((fd (if (port? fd) (port->fdes fd) fd)))
+ (if (= (logand O_NONBLOCK (rm (fcntl2 fd F_GETFL))) 0)
+ #f
+ #t)))
(define (readv fd buffers) (error "not implemented"))
diff --git a/modules/language/python/module/python.scm b/modules/language/python/module/python.scm
index 30434af..96b0aa7 100644
--- a/modules/language/python/module/python.scm
+++ b/modules/language/python/module/python.scm
@@ -8,6 +8,7 @@
object-method))
#:use-module (language python exceptions )
#:use-module ((language python module string ) #:select ())
+ #:use-module ((language python module io ) #:select (open))
#:use-module (language python def )
#:use-module (language python for )
#:use-module (language python try )
@@ -38,13 +39,13 @@
SyntaxError bool
len dir next dict None property range
tuple bytes bytearray eval locals globals
- compile exec type object
+ compile exec type object open
)
#:export (print repr complex float int str
set all any bin callable reversed
chr classmethod staticmethod objectmethod
- divmod enumerate filter open
+ divmod enumerate filter
getattr hasattr setattr hex isinstance issubclass
iter map sum id input oct ord pow super
sorted zip
@@ -52,11 +53,6 @@
(define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
-(define (path-it path)
- (aif it (ref path '__fspath__)
- (it)
- path))
-
(define print
(case-lambda
(() ((@ (guile) format) #t "~%"))
@@ -263,52 +259,6 @@
(yield (reverse r))
(lp))))))))))
-(define DEFAULT_BUFFER_SIZE 4096)
-(def (open path
- (= mode "r")
- (= buffering -1 )
- (= encoding None)
- (= errors None)
- (= newline None)
- (= closefd #t)
- (= opener None))
-
- (define modelist (string->list mode))
- (define path (path-it path))
- (define (clean ch l)
- (filter (lambda (c) (not (eq? ch c))) l))
- (let ((port (if (number? path)
- (begin
- (if (member #\a modelist)
- (seek path 0 SEEK_END))
- (if (member #\x modelist)
- (error "cannot use mode 'x' for fd input"))
- (cond
- ((member #\r modelist)
- (fdes->inport path))
- ((member #\w modelist)
- (fdes->outport path))))
- (begin
- (if (member #\x modelist)
- (if (file-exists? path)
- (raise OSError "mode='x' and file exists")
- (set mode (list->string
- (clean #\x modelist)))))
- ((@ (guile) open-file) (path-it path) mode)))))
-
- (case buffering
- ((-1)
- (setvbuf port 'block DEFAULT_BUFFER_SIZE))
- ((0)
- (setvbuf port 'none))
- ((1)
- (setvbuf port 'line))
- (else
- (setvbuf port 'block buffering)))
-
- port))
-
-
(define-python-class ClassMethod ())
(define-python-class StaticMethod ())
(define-python-class Funcobj ())
diff --git a/modules/language/python/module/subprocess.py b/modules/language/python/module/subprocess.py
index 0d8ee7e..d4dd259 100644
--- a/modules/language/python/module/subprocess.py
+++ b/modules/language/python/module/subprocess.py
@@ -86,7 +86,6 @@ class CalledProcessError(SubprocessError):
# .stdout is a transparent alias for .output
self.output = value
-
class TimeoutExpired(SubprocessError):
"""This exception is raised when the timeout expires while waiting for a
child process.
@@ -133,12 +132,12 @@ else:
import threading
except ImportError:
import dummy_threading as threading
-
+ pk(1)
# When select or poll has indicated that the file is writable,
# we can write up to _PIPE_BUF bytes without risk of blocking.
# POSIX defines PIPE_BUF as >= 512.
_PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
-
+ pk(2)
# poll/select have the advantage of not requiring any extra file
# descriptor, contrarily to epoll/kqueue (also, they require a single
# syscall).
diff --git a/modules/language/python/with.scm b/modules/language/python/with.scm
index eab5c55..0193189 100644
--- a/modules/language/python/with.scm
+++ b/modules/language/python/with.scm
@@ -25,7 +25,7 @@
(lambda ()
(let ((id (enter))) . code))
(#:except #t =>
- (lambda (tag l)
+ (lambda (tag l)
(set! type (if (pyclass? tag)
tag
(aif it (ref tag '__class__)