|
1500 | 1500 | (throw
|
1501 | 1501 | (python/ValueError (str "cannot coerce " (python/repr x) " to byte"))))))
|
1502 | 1502 |
|
| 1503 | +(defn byte-string |
| 1504 | + "Coerce x to a byte string (Python `bytes` object). |
| 1505 | + |
| 1506 | + Arguments shall be interpreted exactly as with that object's constructor." |
| 1507 | + ([x] |
| 1508 | + (python/bytes x)) |
| 1509 | + ([x encoding] |
| 1510 | + (python/bytes x encoding)) |
| 1511 | + ([x encoding errors] |
| 1512 | + (python/bytes x encoding errors))) |
| 1513 | + |
1503 | 1514 | (defn char
|
1504 | 1515 | "Coerce x to a string of length 1.
|
1505 | 1516 |
|
|
4937 | 4948 | (vector? parent)
|
4938 | 4949 | (->> (map (partial isa? h) tag parent)
|
4939 | 4950 | (every? identity)))
|
4940 |
| - (contains? (ancestors h tag) parent)))) |
| 4951 | + (contains? (ancestors h tag) parent) |
| 4952 | + ;; in certain cases, in particular with the Python `io` module, the types |
| 4953 | + ;; in a class's MRO are not identical to the types users have access to. |
| 4954 | + ;; this is likely the case due to so-called "virtual" subclasses such as |
| 4955 | + ;; those supported by Python's `abc` module. we need to use `issubclass` |
| 4956 | + ;; to detect those edge cases. |
| 4957 | + (and (instance? python/type tag) |
| 4958 | + (instance? python/type parent) |
| 4959 | + (python/issubclass tag parent))))) |
4941 | 4960 |
|
4942 | 4961 | (defn derive
|
4943 | 4962 | "Derive a parent/child relationship between `tag` and `parent`.
|
|
6425 | 6444 |
|
6426 | 6445 | ~type-name)))
|
6427 | 6446 |
|
| 6447 | +;;;;;;;;;;;;;;;;;; |
| 6448 | +;; IO Utilities ;; |
| 6449 | +;;;;;;;;;;;;;;;;;; |
| 6450 | + |
| 6451 | +;; This is a circular import since namespaces using 'ns will always try to refer all |
| 6452 | +;; symbols from 'basilisp.core. This should be fine since we won't be using anything |
| 6453 | +;; from core defined below this section, but still this is a bad pattern and should |
| 6454 | +;; not be replicated. |
| 6455 | +(require 'basilisp.io) |
| 6456 | + |
| 6457 | +(defn slurp |
| 6458 | + "Open a `basilisp.io/reader` instance on `f` and read the contents of `f` into a |
| 6459 | + string. |
| 6460 | + |
| 6461 | + Options may be provided as key value pairs and will be passed directly to |
| 6462 | + `basilisp.io/reader`. Supported reader options depend on which type of reader is |
| 6463 | + selected for `f`. Most readers support the `:encoding` option. |
| 6464 | + |
| 6465 | + If `f` is a string, it first is resolved as a URL (via `urllib.parse.urlparse`). |
| 6466 | + If the URL is invalid or refers to a filesystem location (via `file://` scheme), |
| 6467 | + then it will be resolved as a local filesystem path. |
| 6468 | + |
| 6469 | + Return the string contents." |
| 6470 | + [f & opts] |
| 6471 | + (with-open [reader (apply basilisp.io/reader f opts)] |
| 6472 | + (.read reader))) |
| 6473 | + |
| 6474 | +(defn spit |
| 6475 | + "Open a `basilisp.io/writer` instance on `f` and write `content` out to `f` before |
| 6476 | + closing the writer. |
| 6477 | + |
| 6478 | + Options may be provided as key value pairs and will be passed directly to |
| 6479 | + `basilisp.io/writer`. Supported writer options depend on which type of writer is |
| 6480 | + selected for `f`. Most writers support the `:encoding` option. |
| 6481 | + |
| 6482 | + If `f` is a string, it first is resolved as a URL (via `urllib.parse.urlparse`). |
| 6483 | + If the URL is invalid or refers to a filesystem location (via `file://` scheme), |
| 6484 | + then it will be resolved as a local filesystem path. |
| 6485 | + |
| 6486 | + `spit` does not support writing to non-file URLs. |
| 6487 | + |
| 6488 | + Return `nil`." |
| 6489 | + [f content & opts] |
| 6490 | + (with-open [writer (apply basilisp.io/writer f opts)] |
| 6491 | + (.write writer content) |
| 6492 | + nil)) |
| 6493 | + |
6428 | 6494 | ;;;;;;;;;;;;;;;;;
|
6429 | 6495 | ;; Transducers ;;
|
6430 | 6496 | ;;;;;;;;;;;;;;;;;
|
|
0 commit comments