basilisp 0.5.0.dev2__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/PKG-INFO +22 -19
- basilisp-0.5.1/README.md +45 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/pyproject.toml +9 -5
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/cli.py +35 -5
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/core.lpy +19 -13
- basilisp-0.5.1/src/basilisp/csv.lpy +59 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/generator.py +11 -4
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/interfaces.py +13 -7
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/map.py +2 -2
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/obj.py +3 -2
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/reader.py +1 -1
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/runtime.py +143 -55
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/set.py +1 -1
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/typing.py +2 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/vector.py +20 -0
- basilisp-0.5.1/src/basilisp/reflect.lpy +250 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/test.lpy +1 -1
- basilisp-0.5.0.dev2/README.md +0 -47
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/LICENSE +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/bencode.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/nrepl_server.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/pytest/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/pytest/testrunner.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/sphinx/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/sphinx/autodoc.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/sphinx/domain.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/contrib/sphinx/linkcode.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/core/protocols.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/data.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/edn.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/importer.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/io.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/json.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/atom.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/__init__.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/analyzer.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/constants.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/exception.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/nodes.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/optimizer.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/compiler/utils.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/delay.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/exception.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/futures.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/keyword.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/list.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/multifn.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/numbers.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/promise.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/queue.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/reduced.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/reference.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/seq.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/source.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/symbol.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/tagged.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/util.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/lang/volatile.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/logconfig.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/main.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/pprint.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/process.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/prompt.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/repl.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/set.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/shell.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/sitecustomize.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/stacktrace.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/string.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/template.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/test/fixtures.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/url.lpy +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/util.py +0 -0
- {basilisp-0.5.0.dev2 → basilisp-0.5.1}/src/basilisp/walk.lpy +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basilisp
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary: A Clojure-
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: A Clojure-compatible(-ish) Lisp dialect hosted on Python 3 with seamless Python interop.
|
|
5
5
|
License-Expression: EPL-1.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Author: Christopher Rink
|
|
@@ -28,19 +28,25 @@ Requires-Dist: pygments (>=2.9.0,<3.0.0) ; extra == "pygments"
|
|
|
28
28
|
Requires-Dist: pyrsistent (>=0.18.0,<1.0.0)
|
|
29
29
|
Requires-Dist: pytest (>=7.0.0,<9.0.0) ; extra == "pytest"
|
|
30
30
|
Requires-Dist: typing-extensions (>=4.7.0,<5.0.0)
|
|
31
|
+
Project-URL: Bug Tracker, https://github.com/basilisp-lang/basilisp/issues
|
|
32
|
+
Project-URL: Changelog, https://github.com/basilisp-lang/basilisp/blob/main/CHANGELOG.md
|
|
33
|
+
Project-URL: Documentation, https://docs.basilisp.org
|
|
34
|
+
Project-URL: Homepage, https://github.com/basilisp-lang/basilisp
|
|
35
|
+
Project-URL: Repository, https://github.com/basilisp-lang/basilisp
|
|
31
36
|
Description-Content-Type: text/markdown
|
|
32
37
|
|
|
33
38
|
# 🐍 basilisp 🐍
|
|
34
39
|
|
|
35
|
-
A Clojure-compatible(-ish) Lisp dialect
|
|
40
|
+
A Clojure-compatible(-ish) Lisp dialect hosted on Python 3 with seamless Python
|
|
41
|
+
interop.
|
|
36
42
|
|
|
37
|
-
[](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://basilisp.readthedocs.io/) [](https://github.com/basilisp-lang/basilisp/actions/workflows/run-tests.yml) [](https://coveralls.io/github/basilisp-lang/basilisp) [](https://github.com/basilisp-lang/basilisp/blob/master/LICENSE) [](https://clojurians.slack.com/archives/C071RFV2Z1D)
|
|
43
|
+
[](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://basilisp.readthedocs.io/) [](https://github.com/basilisp-lang/basilisp/actions/workflows/run-tests.yml) [](https://github.com/basilisp-lang/basilisp/actions/workflows/run-clojure-test-suite.yml) [](https://coveralls.io/github/basilisp-lang/basilisp) [](https://github.com/basilisp-lang/basilisp/blob/master/LICENSE) [](https://clojurians.slack.com/archives/C071RFV2Z1D)
|
|
38
44
|
|
|
39
45
|
## Getting Started
|
|
40
46
|
|
|
41
47
|
Basilisp is developed on [GitHub](https://github.com/basilisp-lang/basilisp) and
|
|
42
48
|
hosted on [PyPI](https://pypi.python.org/pypi/basilisp). You can fetch Basilisp
|
|
43
|
-
using `pip
|
|
49
|
+
using `pip` (or any other Python dependency manager which can pull from PyPI):
|
|
44
50
|
|
|
45
51
|
```bash
|
|
46
52
|
pip install basilisp
|
|
@@ -52,27 +58,24 @@ Once Basilisp is installed, you can enter into the REPL using:
|
|
|
52
58
|
basilisp repl
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
Basilisp [documentation](https://docs.basilisp.org) can help guide your
|
|
64
|
+
exploration at the REPL and beyond. Additionally, Basilisp features many of the
|
|
65
|
+
same functions and idioms as [Clojure](https://clojure.org/), so you may find
|
|
66
|
+
guides and documentation there helpful for getting started.
|
|
59
67
|
|
|
60
68
|
For those who prefer a video introduction, feel free to check out this
|
|
61
69
|
[talk](https://youtu.be/ruGRHYpq448?si=0jr2a6uWlq6Vi2_k) hosted by the
|
|
62
70
|
[London Clojurians](https://www.meetup.com/london-clojurians/) group about Basilisp.
|
|
63
71
|
|
|
64
|
-
##
|
|
65
|
-
|
|
66
|
-
Basilisp is a project I (@chrisrink10) created to learn about Python, Clojure,
|
|
67
|
-
hosted languages, and compilers.
|
|
72
|
+
## Contributing
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
standard library implementations. I suspect it could be used to build small
|
|
72
|
-
applications and tools at this point, though I would not recommend it unless you
|
|
73
|
-
like being an early adopter.
|
|
74
|
+
Contributions are welcome, but please review the [contributing guidelines](https://docs.basilisp.org/en/latest/contributing.html)
|
|
75
|
+
before submitting an issue or pull request.
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
If you have a question, please use [Github Discussions](https://github.com/basilisp-lang/basilisp/discussions)
|
|
78
|
+
or post in the [`#basilisp` channel](https://clojurians.slack.com/archives/C0A2CQQQVPB) in the Clojurians Slack.
|
|
76
79
|
|
|
77
80
|
## License
|
|
78
81
|
|
basilisp-0.5.1/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 🐍 basilisp 🐍
|
|
2
|
+
|
|
3
|
+
A Clojure-compatible(-ish) Lisp dialect hosted on Python 3 with seamless Python
|
|
4
|
+
interop.
|
|
5
|
+
|
|
6
|
+
[](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://pypi.org/project/basilisp/) [](https://basilisp.readthedocs.io/) [](https://github.com/basilisp-lang/basilisp/actions/workflows/run-tests.yml) [](https://github.com/basilisp-lang/basilisp/actions/workflows/run-clojure-test-suite.yml) [](https://coveralls.io/github/basilisp-lang/basilisp) [](https://github.com/basilisp-lang/basilisp/blob/master/LICENSE) [](https://clojurians.slack.com/archives/C071RFV2Z1D)
|
|
7
|
+
|
|
8
|
+
## Getting Started
|
|
9
|
+
|
|
10
|
+
Basilisp is developed on [GitHub](https://github.com/basilisp-lang/basilisp) and
|
|
11
|
+
hosted on [PyPI](https://pypi.python.org/pypi/basilisp). You can fetch Basilisp
|
|
12
|
+
using `pip` (or any other Python dependency manager which can pull from PyPI):
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install basilisp
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Once Basilisp is installed, you can enter into the REPL using:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
basilisp repl
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Documentation
|
|
25
|
+
|
|
26
|
+
Basilisp [documentation](https://docs.basilisp.org) can help guide your
|
|
27
|
+
exploration at the REPL and beyond. Additionally, Basilisp features many of the
|
|
28
|
+
same functions and idioms as [Clojure](https://clojure.org/), so you may find
|
|
29
|
+
guides and documentation there helpful for getting started.
|
|
30
|
+
|
|
31
|
+
For those who prefer a video introduction, feel free to check out this
|
|
32
|
+
[talk](https://youtu.be/ruGRHYpq448?si=0jr2a6uWlq6Vi2_k) hosted by the
|
|
33
|
+
[London Clojurians](https://www.meetup.com/london-clojurians/) group about Basilisp.
|
|
34
|
+
|
|
35
|
+
## Contributing
|
|
36
|
+
|
|
37
|
+
Contributions are welcome, but please review the [contributing guidelines](https://docs.basilisp.org/en/latest/contributing.html)
|
|
38
|
+
before submitting an issue or pull request.
|
|
39
|
+
|
|
40
|
+
If you have a question, please use [Github Discussions](https://github.com/basilisp-lang/basilisp/discussions)
|
|
41
|
+
or post in the [`#basilisp` channel](https://clojurians.slack.com/archives/C0A2CQQQVPB) in the Clojurians Slack.
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
Eclipse Public License 1.0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "basilisp"
|
|
3
|
-
version = "0.5.
|
|
4
|
-
description = "A Clojure-
|
|
3
|
+
version = "0.5.1"
|
|
4
|
+
description = "A Clojure-compatible(-ish) Lisp dialect hosted on Python 3 with seamless Python interop."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Christopher Rink", email = "chris@crink.dev" },
|
|
7
7
|
]
|
|
@@ -11,8 +11,6 @@ requires-python = ">=3.10"
|
|
|
11
11
|
packages = [
|
|
12
12
|
{ include = "basilisp", from = "src" },
|
|
13
13
|
]
|
|
14
|
-
repository = "https://github.com/basilisp-lang/basilisp"
|
|
15
|
-
documentation = "https://basilisp.readthedocs.io/"
|
|
16
14
|
classifiers = [
|
|
17
15
|
# Trove classifiers
|
|
18
16
|
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
@@ -38,6 +36,13 @@ dependencies = [
|
|
|
38
36
|
"typing-extensions (>=4.7.0,<5.0.0)",
|
|
39
37
|
]
|
|
40
38
|
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/basilisp-lang/basilisp"
|
|
41
|
+
Documentation = "https://docs.basilisp.org"
|
|
42
|
+
Repository = "https://github.com/basilisp-lang/basilisp"
|
|
43
|
+
"Bug Tracker" = "https://github.com/basilisp-lang/basilisp/issues"
|
|
44
|
+
Changelog = "https://github.com/basilisp-lang/basilisp/blob/main/CHANGELOG.md"
|
|
45
|
+
|
|
41
46
|
[dependency-groups]
|
|
42
47
|
dev = [
|
|
43
48
|
"black >=24.0.0",
|
|
@@ -108,7 +113,6 @@ omit = [
|
|
|
108
113
|
"*/__version__.py",
|
|
109
114
|
"*/basilisp/contrib/sphinx/*",
|
|
110
115
|
]
|
|
111
|
-
patch = ["subprocess"]
|
|
112
116
|
|
|
113
117
|
[tool.coverage.paths]
|
|
114
118
|
source = [
|
|
@@ -324,7 +324,9 @@ def _add_debug_arg_group(parser: argparse.ArgumentParser) -> None:
|
|
|
324
324
|
)
|
|
325
325
|
|
|
326
326
|
|
|
327
|
-
def _add_import_arg_group(
|
|
327
|
+
def _add_import_arg_group(
|
|
328
|
+
parser: argparse.ArgumentParser, include_unsafe_path_default: bool = True
|
|
329
|
+
) -> None:
|
|
328
330
|
group = parser.add_argument_group(
|
|
329
331
|
"path options",
|
|
330
332
|
description=(
|
|
@@ -336,14 +338,16 @@ def _add_import_arg_group(parser: argparse.ArgumentParser) -> None:
|
|
|
336
338
|
"--include-unsafe-path",
|
|
337
339
|
action="store",
|
|
338
340
|
nargs="?",
|
|
339
|
-
const=
|
|
340
|
-
default=os.getenv(
|
|
341
|
+
const=include_unsafe_path_default,
|
|
342
|
+
default=os.getenv(
|
|
343
|
+
"BASILISP_INCLUDE_UNSAFE_PATH", str(include_unsafe_path_default)
|
|
344
|
+
),
|
|
341
345
|
type=_to_bool,
|
|
342
346
|
help=(
|
|
343
347
|
"if true, automatically prepend a potentially unsafe path to `sys.path`; "
|
|
344
348
|
"setting `--include-unsafe-path=false` is the Basilisp equivalent to "
|
|
345
349
|
"setting PYTHONSAFEPATH to a non-empty string for CPython's REPL "
|
|
346
|
-
"(env: BASILISP_INCLUDE_UNSAFE_PATH; default:
|
|
350
|
+
f"(env: BASILISP_INCLUDE_UNSAFE_PATH; default: {str(include_unsafe_path_default).lower()})"
|
|
347
351
|
),
|
|
348
352
|
)
|
|
349
353
|
group.add_argument(
|
|
@@ -732,12 +736,23 @@ def test(
|
|
|
732
736
|
args: argparse.Namespace,
|
|
733
737
|
extra: list[str],
|
|
734
738
|
) -> None: # pragma: no cover
|
|
739
|
+
# Add `test` or `tests` directory to the current working directory
|
|
740
|
+
if args.include_default_test_path:
|
|
741
|
+
if not getattr(args, "include_path", []):
|
|
742
|
+
args.include_path = []
|
|
743
|
+
for d in ("tests", "test"):
|
|
744
|
+
p = Path.cwd() / d
|
|
745
|
+
if p.exists():
|
|
746
|
+
args.include_path.append(str(p))
|
|
747
|
+
|
|
735
748
|
init_path(args)
|
|
736
749
|
basilisp.init(_compiler_opts(args))
|
|
750
|
+
|
|
737
751
|
# parse_known_args leaves the `--` separator as the first element if it is present
|
|
738
752
|
# but retaining that causes PyTest to interpret all the arguments as positional
|
|
739
753
|
if extra and extra[0] == "--":
|
|
740
754
|
extra = extra[1:]
|
|
755
|
+
|
|
741
756
|
try:
|
|
742
757
|
import pytest
|
|
743
758
|
except (ImportError, ModuleNotFoundError):
|
|
@@ -784,8 +799,23 @@ def test(
|
|
|
784
799
|
allows_extra=True,
|
|
785
800
|
)
|
|
786
801
|
def _add_test_subcommand(parser: argparse.ArgumentParser) -> None:
|
|
802
|
+
parser.add_argument(
|
|
803
|
+
"-d",
|
|
804
|
+
"--include-default-test-path",
|
|
805
|
+
action="store",
|
|
806
|
+
nargs="?",
|
|
807
|
+
const=True,
|
|
808
|
+
default=os.getenv("BASILISP_INCLUDE_DEFAULT_TEST_PATH", "true"),
|
|
809
|
+
type=_to_bool,
|
|
810
|
+
help=(
|
|
811
|
+
"if true, automatically prepend a 'test' or 'tests' directory to the "
|
|
812
|
+
"PYTHONPATH enabling discovery and importing of test namespaces "
|
|
813
|
+
"(env: BASILISP_INCLUDE_DEFAULT_TEST_PATH; default: true)"
|
|
814
|
+
),
|
|
815
|
+
)
|
|
816
|
+
|
|
787
817
|
_add_compiler_arg_group(parser)
|
|
788
|
-
_add_import_arg_group(parser)
|
|
818
|
+
_add_import_arg_group(parser, include_unsafe_path_default=False)
|
|
789
819
|
_add_runtime_arg_group(parser)
|
|
790
820
|
_add_debug_arg_group(parser)
|
|
791
821
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
(def ^{:doc "Create a list from the arguments."
|
|
24
24
|
:arglists '([& args])}
|
|
25
25
|
list
|
|
26
|
-
(fn* list [& args] (if args args '())))
|
|
26
|
+
(fn* list [& args] (if args (basilisp.lang.list/list args) '())))
|
|
27
27
|
|
|
28
28
|
(def
|
|
29
29
|
^{:doc "If ``seq`` is a Seq, return the first element from ``seq``. If ``seq``
|
|
@@ -209,11 +209,17 @@
|
|
|
209
209
|
(fn iterator-seq [it]
|
|
210
210
|
(basilisp.lang.runtime/to-iterator-seq it)))
|
|
211
211
|
|
|
212
|
-
|
|
213
212
|
(def ^{:doc "Apply function ``f`` to the arguments provided.
|
|
214
213
|
|
|
215
214
|
The last argument must always be coercible to a Seq. Intermediate
|
|
216
|
-
arguments are not modified.
|
|
215
|
+
arguments are not modified. The Seq in the last argument may be
|
|
216
|
+
infinite if the called function ``f`` is lazy.
|
|
217
|
+
|
|
218
|
+
.. warning::
|
|
219
|
+
|
|
220
|
+
Applying arguments to Python functions (rather than Basilisp
|
|
221
|
+
functions) will consume the argument Seq eagerly. Infinite
|
|
222
|
+
Seqs are **not** supported for Python functions."
|
|
217
223
|
:arglists '([f & args])}
|
|
218
224
|
apply
|
|
219
225
|
(fn apply [f & args]
|
|
@@ -231,7 +237,7 @@
|
|
|
231
237
|
:arglists '([& seqs])}
|
|
232
238
|
concat
|
|
233
239
|
(fn concat [& seqs]
|
|
234
|
-
(
|
|
240
|
+
(basilisp.lang.runtime/concat-from-seq seqs)))
|
|
235
241
|
|
|
236
242
|
(def
|
|
237
243
|
^{:doc "Create a hash map from pairs of input arguments."
|
|
@@ -2840,11 +2846,13 @@
|
|
|
2840
2846
|
(cons (f (first coll)) (map f (rest coll))))))
|
|
2841
2847
|
([f coll & colls]
|
|
2842
2848
|
(lazy-seq
|
|
2843
|
-
(
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2849
|
+
(let [step-elems (fn step-elems [colls]
|
|
2850
|
+
(lazy-seq
|
|
2851
|
+
(let [colls (map seq colls)]
|
|
2852
|
+
(when (every? identity colls)
|
|
2853
|
+
(cons (map first colls)
|
|
2854
|
+
(step-elems (map rest colls)))))))]
|
|
2855
|
+
(map #(apply f %) (step-elems (cons coll colls)))))))
|
|
2848
2856
|
|
|
2849
2857
|
(def ^{:doc "Return a vector of ``(f elem)`` for elements in ``coll``\\. More than one
|
|
2850
2858
|
collection may be supplied. If more than one collection is supplied, the
|
|
@@ -2878,10 +2886,8 @@
|
|
|
2878
2886
|
"Return a lazy sequence of the concatenated results of mapping ``f`` over ``colls``\\."
|
|
2879
2887
|
([f]
|
|
2880
2888
|
(comp (map f) cat))
|
|
2881
|
-
([f
|
|
2882
|
-
(apply concat (map f
|
|
2883
|
-
([f coll & colls]
|
|
2884
|
-
(apply concat (apply map f coll colls))))
|
|
2889
|
+
([f & colls]
|
|
2890
|
+
(apply concat (apply map f colls))))
|
|
2885
2891
|
|
|
2886
2892
|
(defn filter
|
|
2887
2893
|
"Return a lazy sequence of elements from ``coll`` where ``(pred elem)`` returns a
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
(ns basilisp.csv
|
|
2
|
+
"Wrapper functions for :external:py:mod:`csv` which reads and writes CSVs."
|
|
3
|
+
(:require
|
|
4
|
+
[basilisp.io :as bio])
|
|
5
|
+
(:import
|
|
6
|
+
csv))
|
|
7
|
+
|
|
8
|
+
(defn read-csv
|
|
9
|
+
"Returns a lazy sequence of vectors corresponding to the rows of a CSV file.
|
|
10
|
+
|
|
11
|
+
If ``input`` is a string, it will be treated as the contents of a CSV. Otherwise,
|
|
12
|
+
it will be treated as a :external:py:class:`io.TextIOBase`.
|
|
13
|
+
|
|
14
|
+
The reader function supports the following keyword arguments:
|
|
15
|
+
|
|
16
|
+
:keyword ``:separator``: the character used as the separator for a fields in a row
|
|
17
|
+
default is \",\"
|
|
18
|
+
:keyword ``:quote``: the quote character used on quoted fields; default is ``true``"
|
|
19
|
+
[input & {:keys [separator quote] :or {separator "," quote "\""}}]
|
|
20
|
+
(let [f (if (string? input)
|
|
21
|
+
(io/StringIO input)
|
|
22
|
+
input)
|
|
23
|
+
reader (csv/reader f ** :delimiter separator :quotechar quote)
|
|
24
|
+
do-read (fn read-csv*
|
|
25
|
+
[]
|
|
26
|
+
(when-some [row (python/next reader nil)]
|
|
27
|
+
(cons (vec row) (lazy-seq (read-csv*)))))]
|
|
28
|
+
(lazy-seq (do-read))))
|
|
29
|
+
|
|
30
|
+
(defn rows->maps
|
|
31
|
+
"Returns a lazy sequence mapping over a sequence of CSV data (as vectors)
|
|
32
|
+
converting them to maps.
|
|
33
|
+
|
|
34
|
+
The first row will be used as the headers. The ``:key-fn`` keyword argument
|
|
35
|
+
names a function which will be used to map over the keys."
|
|
36
|
+
[rows & {:keys [key-fn] :or {key-fn keyword}}]
|
|
37
|
+
(let [header (mapv key-fn (first rows))]
|
|
38
|
+
(map #(zipmap header %) (rest rows))))
|
|
39
|
+
|
|
40
|
+
(defn write-csv
|
|
41
|
+
"Write a sequence of rows in CSV format to ``writer``, which should be an
|
|
42
|
+
:external:py:class:`io.TextIOBase`.
|
|
43
|
+
|
|
44
|
+
The writing function supports the following keyword arguments:
|
|
45
|
+
|
|
46
|
+
:keyword ``:separator``: the character used as the separator for a fields in a row
|
|
47
|
+
default is \",\"
|
|
48
|
+
:keyword ``:quote``: the quote character used on quoted fields; default is ``true``
|
|
49
|
+
:keyword ``:newline``: the newline character to use between rows (``:lf`` or
|
|
50
|
+
``:cr+lf``)"
|
|
51
|
+
[writer data & {:keys [separator quote newline] :or {separator "," quote "\"" newline :lf}}]
|
|
52
|
+
(let [nl (cond
|
|
53
|
+
(= newline :lf) "\n"
|
|
54
|
+
(= newline :cr+lf) "\r\n"
|
|
55
|
+
:else (throw
|
|
56
|
+
(ex-info "newline must be one of: :lf or :cr+lf"
|
|
57
|
+
{:newline newline})))
|
|
58
|
+
w (csv/writer writer ** :delimiter separator :quotechar quote :lineterminator nl)]
|
|
59
|
+
(.writerows w (map #(mapv str %) data))))
|
|
@@ -799,6 +799,7 @@ _ATTR_FROZEN_DECORATOR_NAME = _load_attr(f"{_ATTR_ALIAS}.frozen")
|
|
|
799
799
|
_ATTRIB_FIELD_FN_NAME = _load_attr(f"{_ATTR_ALIAS}.field")
|
|
800
800
|
_BASILISP_LOAD_CONSTANT_NAME = _load_attr(f"{_RUNTIME_ALIAS}._load_constant")
|
|
801
801
|
_COERCE_SEQ_FN_NAME = _load_attr(f"{_RUNTIME_ALIAS}.to_seq")
|
|
802
|
+
_UNWRAP_REST_ARGS_FN_NAME = _load_attr(f"{_RUNTIME_ALIAS}._unwrap_rest_args")
|
|
802
803
|
_BASILISP_FN_FN_NAME = _load_attr(f"{_RUNTIME_ALIAS}._basilisp_fn")
|
|
803
804
|
_FN_WITH_ATTRS_FN_NAME = _load_attr(f"{_RUNTIME_ALIAS}._with_attrs")
|
|
804
805
|
_BASILISP_TYPE_FN_NAME = _load_attr(f"{_RUNTIME_ALIAS}._basilisp_type")
|
|
@@ -1707,7 +1708,7 @@ def __fn_args_to_py_ast(
|
|
|
1707
1708
|
value=ast.IfExp(
|
|
1708
1709
|
test=ast.Name(id=arg_name, ctx=ast.Load()),
|
|
1709
1710
|
body=ast.Call(
|
|
1710
|
-
func=
|
|
1711
|
+
func=_UNWRAP_REST_ARGS_FN_NAME,
|
|
1711
1712
|
args=[ast.Name(id=arg_name, ctx=ast.Load())],
|
|
1712
1713
|
keywords=[],
|
|
1713
1714
|
),
|
|
@@ -1738,6 +1739,8 @@ def __fn_args_to_py_ast(
|
|
|
1738
1739
|
def __fn_decorator(
|
|
1739
1740
|
arities: Iterable[int],
|
|
1740
1741
|
has_rest_arg: bool = False,
|
|
1742
|
+
*,
|
|
1743
|
+
max_fixed_arity: int,
|
|
1741
1744
|
) -> ast.Call:
|
|
1742
1745
|
return ast.Call(
|
|
1743
1746
|
func=_BASILISP_FN_FN_NAME,
|
|
@@ -1767,7 +1770,8 @@ def __fn_decorator(
|
|
|
1767
1770
|
),
|
|
1768
1771
|
ctx=ast.Load(),
|
|
1769
1772
|
),
|
|
1770
|
-
)
|
|
1773
|
+
),
|
|
1774
|
+
ast.keyword(arg="max_fixed_arity", value=ast.Constant(max_fixed_arity)),
|
|
1771
1775
|
],
|
|
1772
1776
|
)
|
|
1773
1777
|
|
|
@@ -1875,6 +1879,7 @@ def __single_arity_fn_to_py_ast( # pylint: disable=too-many-locals
|
|
|
1875
1879
|
__fn_decorator(
|
|
1876
1880
|
(len(fn_args),),
|
|
1877
1881
|
has_rest_arg=method.is_variadic,
|
|
1882
|
+
max_fixed_arity=node.max_fixed_arity,
|
|
1878
1883
|
)
|
|
1879
1884
|
],
|
|
1880
1885
|
(
|
|
@@ -1905,10 +1910,11 @@ def __multi_arity_dispatch_fn( # pylint: disable=too-many-arguments,too-many-lo
|
|
|
1905
1910
|
ctx: GeneratorContext,
|
|
1906
1911
|
name: str,
|
|
1907
1912
|
arity_map: Mapping[int, str],
|
|
1913
|
+
*,
|
|
1908
1914
|
return_tags: Iterable[Node | None],
|
|
1909
1915
|
default_name: str | None = None,
|
|
1910
1916
|
rest_arity_fixed_arity: int | None = None,
|
|
1911
|
-
max_fixed_arity: int
|
|
1917
|
+
max_fixed_arity: int,
|
|
1912
1918
|
meta_node: MetaNode | None = None,
|
|
1913
1919
|
is_async: bool = False,
|
|
1914
1920
|
) -> GeneratedPyAST[ast.expr]:
|
|
@@ -2085,6 +2091,7 @@ def __multi_arity_dispatch_fn( # pylint: disable=too-many-arguments,too-many-lo
|
|
|
2085
2091
|
)
|
|
2086
2092
|
),
|
|
2087
2093
|
has_rest_arg=default_name is not None,
|
|
2094
|
+
max_fixed_arity=max_fixed_arity,
|
|
2088
2095
|
)
|
|
2089
2096
|
],
|
|
2090
2097
|
)
|
|
@@ -3688,7 +3695,7 @@ def _const_val_to_py_ast(
|
|
|
3688
3695
|
`_const_node_to_py_ast`."""
|
|
3689
3696
|
try:
|
|
3690
3697
|
serialized = pickle.dumps(form)
|
|
3691
|
-
except (pickle.PicklingError, RecursionError) as e:
|
|
3698
|
+
except (pickle.PicklingError, RecursionError) as e: # pragma: no cover
|
|
3692
3699
|
# For types without custom "constant" handling code, we defer to pickle
|
|
3693
3700
|
# to generate a representation that can be reloaded from the generated
|
|
3694
3701
|
# byte code. There are a few cases where that may not be possible for one
|
|
@@ -76,18 +76,28 @@ class ICounted(Sized, ABC):
|
|
|
76
76
|
__slots__ = ()
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
K = TypeVar("K")
|
|
80
|
+
V = TypeVar("V")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class IIndexed(ICounted, Generic[V], ABC):
|
|
84
|
+
"""``IIndexed`` is an interface for types can be accessed by index.
|
|
81
85
|
|
|
82
86
|
Of the builtin collections, only Vectors are ``IIndexed`` . ``IIndexed`` types
|
|
83
87
|
respond ``True`` to the :lpy:fn:`indexed?` predicate.
|
|
84
88
|
|
|
85
89
|
.. seealso::
|
|
86
90
|
|
|
87
|
-
:lpy:fn:`indexed
|
|
91
|
+
:lpy:fn:`indexed?`, :lpy:fn:`nth`"""
|
|
88
92
|
|
|
89
93
|
__slots__ = ()
|
|
90
94
|
|
|
95
|
+
NTH_SENTINEL = object()
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def nth(self, k: int, notfound: V | None = NTH_SENTINEL) -> V | None: # type: ignore[assignment]
|
|
99
|
+
raise NotImplementedError()
|
|
100
|
+
|
|
91
101
|
|
|
92
102
|
T_ExceptionInfo = TypeVar("T_ExceptionInfo", bound="IPersistentMap")
|
|
93
103
|
|
|
@@ -109,10 +119,6 @@ class IExceptionInfo(Exception, Generic[T_ExceptionInfo], ABC):
|
|
|
109
119
|
raise NotImplementedError()
|
|
110
120
|
|
|
111
121
|
|
|
112
|
-
K = TypeVar("K")
|
|
113
|
-
V = TypeVar("V")
|
|
114
|
-
|
|
115
|
-
|
|
116
122
|
class IMapEntry(Generic[K, V], ABC):
|
|
117
123
|
"""``IMapEntry`` values are produced :lpy:fn:`seq` ing over any
|
|
118
124
|
:py:class:`IAssociative` (such as a Basilisp map).
|
|
@@ -21,7 +21,7 @@ from basilisp.lang.interfaces import (
|
|
|
21
21
|
ReduceKVFunction,
|
|
22
22
|
)
|
|
23
23
|
from basilisp.lang.obj import (
|
|
24
|
-
|
|
24
|
+
MAP_PRINT_SEPARATOR,
|
|
25
25
|
SURPASSED_PRINT_LENGTH,
|
|
26
26
|
SURPASSED_PRINT_LEVEL,
|
|
27
27
|
PrintSettings,
|
|
@@ -194,7 +194,7 @@ def map_lrepr( # pylint: disable=too-many-locals
|
|
|
194
194
|
else:
|
|
195
195
|
items = list(entry_reprs())
|
|
196
196
|
|
|
197
|
-
seq_lrepr =
|
|
197
|
+
seq_lrepr = MAP_PRINT_SEPARATOR.join(items + trailer)
|
|
198
198
|
|
|
199
199
|
ns_prefix = ("#:" + ns_name_shared) if ns_name_shared else ""
|
|
200
200
|
if kwargs["print_meta"] and meta:
|
|
@@ -26,7 +26,8 @@ PRINT_LEVEL: PrintCountSetting = None
|
|
|
26
26
|
PRINT_META = False
|
|
27
27
|
PRINT_NAMESPACE_MAPS = False
|
|
28
28
|
PRINT_READABLY = True
|
|
29
|
-
|
|
29
|
+
SEQ_PRINT_SEPARATOR = " "
|
|
30
|
+
MAP_PRINT_SEPARATOR = ", "
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
class PrintSettings(TypedDict, total=False):
|
|
@@ -115,7 +116,7 @@ def seq_lrepr(
|
|
|
115
116
|
kw_items = kwargs.copy()
|
|
116
117
|
kw_items["human_readable"] = False
|
|
117
118
|
items = list(map(lambda o: lrepr(o, **kw_items), items))
|
|
118
|
-
seq_lrepr =
|
|
119
|
+
seq_lrepr = SEQ_PRINT_SEPARATOR.join(items + trailer)
|
|
119
120
|
|
|
120
121
|
print_meta = kwargs["print_meta"]
|
|
121
122
|
if print_meta and meta:
|
|
@@ -1797,7 +1797,7 @@ def _read_next_consuming_comment(ctx: ReaderContext) -> RawReaderForm:
|
|
|
1797
1797
|
while True:
|
|
1798
1798
|
v = _read_next(ctx)
|
|
1799
1799
|
if v is ctx.eof:
|
|
1800
|
-
return ctx.eof
|
|
1800
|
+
return cast(RawReaderForm, ctx.eof)
|
|
1801
1801
|
if v is COMMENT or isinstance(v, Comment):
|
|
1802
1802
|
continue
|
|
1803
1803
|
return v
|