unpythonic 0.15.3__tar.gz → 1.0.0__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.
Files changed (79) hide show
  1. {unpythonic-0.15.3 → unpythonic-1.0.0}/PKG-INFO +79 -16
  2. unpythonic-0.15.3/unpythonic.egg-info/PKG-INFO → unpythonic-1.0.0/README.md +72 -38
  3. unpythonic-1.0.0/pyproject.toml +76 -0
  4. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/__init__.py +1 -1
  5. unpythonic-1.0.0/unpythonic/dialects/__init__.py +17 -0
  6. unpythonic-1.0.0/unpythonic/dialects/lispython.py +88 -0
  7. unpythonic-1.0.0/unpythonic/dialects/listhell.py +35 -0
  8. unpythonic-1.0.0/unpythonic/dialects/pytkell.py +51 -0
  9. unpythonic-1.0.0/unpythonic/syntax/00_stuff/letdo.py +980 -0
  10. unpythonic-0.15.3/AUTHORS.md +0 -22
  11. unpythonic-0.15.3/README.md +0 -855
  12. unpythonic-0.15.3/setup.cfg +0 -4
  13. unpythonic-0.15.3/setup.py +0 -104
  14. unpythonic-0.15.3/unpythonic.egg-info/SOURCES.txt +0 -71
  15. unpythonic-0.15.3/unpythonic.egg-info/dependency_links.txt +0 -1
  16. unpythonic-0.15.3/unpythonic.egg-info/not-zip-safe +0 -1
  17. unpythonic-0.15.3/unpythonic.egg-info/top_level.txt +0 -1
  18. {unpythonic-0.15.3 → unpythonic-1.0.0}/LICENSE.md +0 -0
  19. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/amb.py +0 -0
  20. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/arity.py +0 -0
  21. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/assignonce.py +0 -0
  22. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/collections.py +0 -0
  23. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/conditions.py +0 -0
  24. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/dispatch.py +0 -0
  25. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/dynassign.py +0 -0
  26. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/ec.py +0 -0
  27. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/env.py +0 -0
  28. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/excutil.py +0 -0
  29. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/fix.py +0 -0
  30. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/fold.py +0 -0
  31. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/fploop.py +0 -0
  32. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/fun.py +0 -0
  33. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/funutil.py +0 -0
  34. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/fup.py +0 -0
  35. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/gmemo.py +0 -0
  36. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/gtco.py +0 -0
  37. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/it.py +0 -0
  38. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/lazyutil.py +0 -0
  39. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/let.py +0 -0
  40. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/lispylet.py +0 -0
  41. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/llist.py +0 -0
  42. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/mathseq.py +0 -0
  43. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/misc.py +0 -0
  44. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/__init__.py +0 -0
  45. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/client.py +0 -0
  46. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/common.py +0 -0
  47. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/msg.py +0 -0
  48. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/ptyproxy.py +0 -0
  49. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/server.py +0 -0
  50. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/net/util.py +0 -0
  51. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/numutil.py +0 -0
  52. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/regutil.py +0 -0
  53. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/seq.py +0 -0
  54. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/singleton.py +0 -0
  55. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/slicing.py +0 -0
  56. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/symbol.py +0 -0
  57. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/__init__.py +0 -0
  58. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/autocurry.py +0 -0
  59. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/autoref.py +0 -0
  60. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/dbg.py +0 -0
  61. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/forall.py +0 -0
  62. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/ifexprs.py +0 -0
  63. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/lambdatools.py +0 -0
  64. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/lazify.py +0 -0
  65. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/letdo.py +0 -0
  66. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/letdoutil.py +0 -0
  67. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/letsyntax.py +0 -0
  68. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/nameutil.py +0 -0
  69. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/nb.py +0 -0
  70. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/prefix.py +0 -0
  71. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/scopeanalyzer.py +0 -0
  72. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/simplelet.py +0 -0
  73. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/tailtools.py +0 -0
  74. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/testingtools.py +0 -0
  75. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/syntax/util.py +0 -0
  76. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/tco.py +0 -0
  77. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/test/fixtures.py +0 -0
  78. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/timeutil.py +0 -0
  79. {unpythonic-0.15.3 → unpythonic-1.0.0}/unpythonic/typecheck.py +0 -0
@@ -1,13 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unpythonic
3
- Version: 0.15.3
3
+ Version: 1.0.0
4
4
  Summary: Supercharge your Python with parts of Lisp and Haskell.
5
- Home-page: https://github.com/Technologicat/unpythonic
6
- Author: Juha Jeronen
7
- Author-email: juha.m.jeronen@gmail.com
8
- License: BSD
9
5
  Keywords: functional-programming,language-extension,syntactic-macros,tail-call-optimization,tco,continuations,currying,lazy-evaluation,dynamic-variable,macros,lisp,scheme,racket,haskell
10
- Platform: Linux
6
+ Author-Email: Juha Jeronen <juha.m.jeronen@gmail.com>
7
+ License: BSD
11
8
  Classifier: Development Status :: 4 - Beta
12
9
  Classifier: Environment :: Console
13
10
  Classifier: Intended Audience :: Developers
@@ -24,11 +21,11 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
24
21
  Classifier: Programming Language :: Python :: Implementation :: PyPy
25
22
  Classifier: Topic :: Software Development :: Libraries
26
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
- Provides: unpythonic
28
- Requires-Python: >=3.8,<3.13
24
+ Project-URL: Repository, https://github.com/Technologicat/unpythonic
25
+ Requires-Python: <3.13,>=3.8
26
+ Requires-Dist: mcpyrate>=3.6.4
27
+ Requires-Dist: sympy>=1.13
29
28
  Description-Content-Type: text/markdown
30
- License-File: LICENSE.md
31
- License-File: AUTHORS.md
32
29
 
33
30
  # Unpythonic: Python meets Lisp and Haskell
34
31
 
@@ -38,6 +35,8 @@ In the spirit of [toolz](https://github.com/pytoolz/toolz), we provide missing f
38
35
  ![version on PyPI](https://img.shields.io/pypi/v/unpythonic) ![PyPI package format](https://img.shields.io/pypi/format/unpythonic) ![dependency status](https://img.shields.io/librariesio/github/Technologicat/unpythonic)
39
36
  ![license: BSD](https://img.shields.io/pypi/l/unpythonic) ![open issues](https://img.shields.io/github/issues/Technologicat/unpythonic) [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](http://makeapullrequest.com/)
40
37
 
38
+ We use [semantic versioning](https://semver.org/).
39
+
41
40
  *Some hypertext features of this README, such as local links to detailed documentation, and expandable example highlights, are not supported when viewed on PyPI; [view on GitHub](https://github.com/Technologicat/unpythonic) to have those work properly.*
42
41
 
43
42
 
@@ -836,21 +835,85 @@ assert (my_map, double, (q, 1, 2, 3)) == (ll, 2, 4, 6)
836
835
  ```
837
836
  </details>
838
837
 
839
- ## Installation
838
+ ## Install & uninstall
840
839
 
841
- **PyPI**
840
+ ### From PyPI
842
841
 
843
- ``pip install unpythonic``
842
+ ```bash
843
+ pip install unpythonic
844
+ ```
844
845
 
845
- **GitHub**
846
+ ### From source
846
847
 
847
848
  Clone the repo from GitHub. Then, navigate to it in a terminal, and:
848
849
 
849
850
  ```bash
850
- pip install .
851
+ pip install . --no-compile
851
852
  ```
852
853
 
853
- To uninstall:
854
+ If you intend to use the macro layer of `unpythonic`, the `--no-compile` flag is important. It prevents an **incorrect** precompilation, without macro support, that `pip install` would otherwise do at its `bdist_wheel` step.
855
+
856
+ For most Python projects such precompilation is just fine - it's just macro-enabled projects that shouldn't be precompiled with standard tools.
857
+
858
+ If `--no-compile` is NOT used, the precompiled bytecode cache may cause errors such as `ImportError: cannot import name 'macros' from 'mcpyrate.quotes'`, when you try to e.g. `from unpythonic.syntax import macros, let`. In-tree, it might work, but against an installed copy, it will fail. It has happened that my CI setup did not detect this kind of failure.
859
+
860
+ This is a common issue when using macro expanders in Python.
861
+
862
+ ### Development mode (for developing `unpythonic` itself)
863
+
864
+ Starting with v0.15.5, `unpythonic` uses [PDM](https://pdm-project.org/en/latest/) to manage its dependencies. This allows easy installation of a development copy into an isolated venv (virtual environment), allowing you to break things without breaking anything else on your system (including apps and libraries that use an installed copy of `unpythonic`).
865
+
866
+ #### Install PDM in your Python environment
867
+
868
+ To develop `unpythonic`, if your Python environment does not have PDM, you will need to install it first:
869
+
870
+ ```bash
871
+ python -m pip install pdm
872
+ ```
873
+
874
+ Don't worry; it won't break `pip`, `poetry`, or other similar tools.
875
+
876
+ We will also need a Python for PDM venvs. This Python is independent of the Python that PDM itself runs on. It is the version of Python you would like to use for developing `unpythonic`.
877
+
878
+ For example, we can make Python 3.10 available with the command:
879
+
880
+ ```bash
881
+ pdm python install 3.10
882
+ ```
883
+
884
+ Specifying just a version number defaults to CPython (the usual Python implementation). If you want PyPy instead, you can use e.g. `pypy@3.10`.
885
+
886
+ #### Install the isolated venv
887
+
888
+ Now, we will auto-create the development venv, and install `unpythonic`'s dependencies into it. In a terminal that sees your Python environment, navigate to the `unpythonic` folder, and issue the command:
889
+
890
+ ```bash
891
+ pdm install
892
+ ```
893
+
894
+ This creates the development venv into the `.venv` hidden subfolder of the `unpythonic` folder.
895
+
896
+ If you are a seasoned pythonista, note that there is no `requirements.txt`; the dependency list lives in `pyproject.toml`.
897
+
898
+ #### Upgrade dependencies (later)
899
+
900
+ To upgrade dependencies to latest available versions compatible with the specifications in `pyproject.toml`:
901
+
902
+ ```bash
903
+ pdm update
904
+ ```
905
+
906
+ #### Develop
907
+
908
+ To activate the development venv, in a terminal that sees your Python environment, navigate to the `unpythonic` folder, and issue the command:
909
+
910
+ ```bash
911
+ $(pdm venv activate)
912
+ ```
913
+
914
+ Note the Bash exec syntax `$(...)`; the command `pdm venv activate` just prints the actual internal activation command.
915
+
916
+ ### Uninstall
854
917
 
855
918
  ```bash
856
919
  pip uninstall unpythonic
@@ -1,35 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: unpythonic
3
- Version: 0.15.3
4
- Summary: Supercharge your Python with parts of Lisp and Haskell.
5
- Home-page: https://github.com/Technologicat/unpythonic
6
- Author: Juha Jeronen
7
- Author-email: juha.m.jeronen@gmail.com
8
- License: BSD
9
- Keywords: functional-programming,language-extension,syntactic-macros,tail-call-optimization,tco,continuations,currying,lazy-evaluation,dynamic-variable,macros,lisp,scheme,racket,haskell
10
- Platform: Linux
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Environment :: Console
13
- Classifier: Intended Audience :: Developers
14
- Classifier: License :: OSI Approved :: BSD License
15
- Classifier: Operating System :: POSIX :: Linux
16
- Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.8
19
- Classifier: Programming Language :: Python :: 3.9
20
- Classifier: Programming Language :: Python :: 3.10
21
- Classifier: Programming Language :: Python :: 3.11
22
- Classifier: Programming Language :: Python :: 3.12
23
- Classifier: Programming Language :: Python :: Implementation :: CPython
24
- Classifier: Programming Language :: Python :: Implementation :: PyPy
25
- Classifier: Topic :: Software Development :: Libraries
26
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
- Provides: unpythonic
28
- Requires-Python: >=3.8,<3.13
29
- Description-Content-Type: text/markdown
30
- License-File: LICENSE.md
31
- License-File: AUTHORS.md
32
-
33
1
  # Unpythonic: Python meets Lisp and Haskell
34
2
 
35
3
  In the spirit of [toolz](https://github.com/pytoolz/toolz), we provide missing features for Python, mainly from the list processing tradition, but with some Haskellisms mixed in. We extend the language with a set of [syntactic macros](https://en.wikipedia.org/wiki/Macro_(computer_science)#Syntactic_macros). We also provide an in-process, background [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) server for live inspection and hot-patching. The emphasis is on **clear, pythonic syntax**, **making features work together**, and **obsessive correctness**.
@@ -38,6 +6,8 @@ In the spirit of [toolz](https://github.com/pytoolz/toolz), we provide missing f
38
6
  ![version on PyPI](https://img.shields.io/pypi/v/unpythonic) ![PyPI package format](https://img.shields.io/pypi/format/unpythonic) ![dependency status](https://img.shields.io/librariesio/github/Technologicat/unpythonic)
39
7
  ![license: BSD](https://img.shields.io/pypi/l/unpythonic) ![open issues](https://img.shields.io/github/issues/Technologicat/unpythonic) [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](http://makeapullrequest.com/)
40
8
 
9
+ We use [semantic versioning](https://semver.org/).
10
+
41
11
  *Some hypertext features of this README, such as local links to detailed documentation, and expandable example highlights, are not supported when viewed on PyPI; [view on GitHub](https://github.com/Technologicat/unpythonic) to have those work properly.*
42
12
 
43
13
 
@@ -836,21 +806,85 @@ assert (my_map, double, (q, 1, 2, 3)) == (ll, 2, 4, 6)
836
806
  ```
837
807
  </details>
838
808
 
839
- ## Installation
809
+ ## Install & uninstall
840
810
 
841
- **PyPI**
811
+ ### From PyPI
842
812
 
843
- ``pip install unpythonic``
813
+ ```bash
814
+ pip install unpythonic
815
+ ```
844
816
 
845
- **GitHub**
817
+ ### From source
846
818
 
847
819
  Clone the repo from GitHub. Then, navigate to it in a terminal, and:
848
820
 
849
821
  ```bash
850
- pip install .
822
+ pip install . --no-compile
823
+ ```
824
+
825
+ If you intend to use the macro layer of `unpythonic`, the `--no-compile` flag is important. It prevents an **incorrect** precompilation, without macro support, that `pip install` would otherwise do at its `bdist_wheel` step.
826
+
827
+ For most Python projects such precompilation is just fine - it's just macro-enabled projects that shouldn't be precompiled with standard tools.
828
+
829
+ If `--no-compile` is NOT used, the precompiled bytecode cache may cause errors such as `ImportError: cannot import name 'macros' from 'mcpyrate.quotes'`, when you try to e.g. `from unpythonic.syntax import macros, let`. In-tree, it might work, but against an installed copy, it will fail. It has happened that my CI setup did not detect this kind of failure.
830
+
831
+ This is a common issue when using macro expanders in Python.
832
+
833
+ ### Development mode (for developing `unpythonic` itself)
834
+
835
+ Starting with v0.15.5, `unpythonic` uses [PDM](https://pdm-project.org/en/latest/) to manage its dependencies. This allows easy installation of a development copy into an isolated venv (virtual environment), allowing you to break things without breaking anything else on your system (including apps and libraries that use an installed copy of `unpythonic`).
836
+
837
+ #### Install PDM in your Python environment
838
+
839
+ To develop `unpythonic`, if your Python environment does not have PDM, you will need to install it first:
840
+
841
+ ```bash
842
+ python -m pip install pdm
843
+ ```
844
+
845
+ Don't worry; it won't break `pip`, `poetry`, or other similar tools.
846
+
847
+ We will also need a Python for PDM venvs. This Python is independent of the Python that PDM itself runs on. It is the version of Python you would like to use for developing `unpythonic`.
848
+
849
+ For example, we can make Python 3.10 available with the command:
850
+
851
+ ```bash
852
+ pdm python install 3.10
853
+ ```
854
+
855
+ Specifying just a version number defaults to CPython (the usual Python implementation). If you want PyPy instead, you can use e.g. `pypy@3.10`.
856
+
857
+ #### Install the isolated venv
858
+
859
+ Now, we will auto-create the development venv, and install `unpythonic`'s dependencies into it. In a terminal that sees your Python environment, navigate to the `unpythonic` folder, and issue the command:
860
+
861
+ ```bash
862
+ pdm install
863
+ ```
864
+
865
+ This creates the development venv into the `.venv` hidden subfolder of the `unpythonic` folder.
866
+
867
+ If you are a seasoned pythonista, note that there is no `requirements.txt`; the dependency list lives in `pyproject.toml`.
868
+
869
+ #### Upgrade dependencies (later)
870
+
871
+ To upgrade dependencies to latest available versions compatible with the specifications in `pyproject.toml`:
872
+
873
+ ```bash
874
+ pdm update
875
+ ```
876
+
877
+ #### Develop
878
+
879
+ To activate the development venv, in a terminal that sees your Python environment, navigate to the `unpythonic` folder, and issue the command:
880
+
881
+ ```bash
882
+ $(pdm venv activate)
851
883
  ```
852
884
 
853
- To uninstall:
885
+ Note the Bash exec syntax `$(...)`; the command `pdm venv activate` just prints the actual internal activation command.
886
+
887
+ ### Uninstall
854
888
 
855
889
  ```bash
856
890
  pip uninstall unpythonic
@@ -0,0 +1,76 @@
1
+ [project]
2
+ name = "unpythonic"
3
+ description = "Supercharge your Python with parts of Lisp and Haskell."
4
+ authors = [
5
+ { name = "Juha Jeronen", email = "juha.m.jeronen@gmail.com" },
6
+ ]
7
+ requires-python = ">=3.8,<3.13"
8
+ readme = "README.md"
9
+ dynamic = []
10
+ dependencies = [
11
+ "mcpyrate>=3.6.4",
12
+ "sympy>=1.13",
13
+ ]
14
+ keywords = [
15
+ "functional-programming",
16
+ "language-extension",
17
+ "syntactic-macros",
18
+ "tail-call-optimization",
19
+ "tco",
20
+ "continuations",
21
+ "currying",
22
+ "lazy-evaluation",
23
+ "dynamic-variable",
24
+ "macros",
25
+ "lisp",
26
+ "scheme",
27
+ "racket",
28
+ "haskell",
29
+ ]
30
+ classifiers = [
31
+ "Development Status :: 4 - Beta",
32
+ "Environment :: Console",
33
+ "Intended Audience :: Developers",
34
+ "License :: OSI Approved :: BSD License",
35
+ "Operating System :: POSIX :: Linux",
36
+ "Programming Language :: Python",
37
+ "Programming Language :: Python :: 3",
38
+ "Programming Language :: Python :: 3.8",
39
+ "Programming Language :: Python :: 3.9",
40
+ "Programming Language :: Python :: 3.10",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Programming Language :: Python :: 3.12",
43
+ "Programming Language :: Python :: Implementation :: CPython",
44
+ "Programming Language :: Python :: Implementation :: PyPy",
45
+ "Topic :: Software Development :: Libraries",
46
+ "Topic :: Software Development :: Libraries :: Python Modules",
47
+ ]
48
+ version = "1.0.0"
49
+
50
+ [project.license]
51
+ text = "BSD"
52
+
53
+ [project.urls]
54
+ Repository = "https://github.com/Technologicat/unpythonic"
55
+
56
+ [build-system]
57
+ requires = [
58
+ "pdm-backend",
59
+ ]
60
+ build-backend = "pdm.backend"
61
+
62
+ [tool.pdm.version]
63
+ source = "file"
64
+ path = "unpythonic/__init__.py"
65
+
66
+ [tool.pdm.build]
67
+ includes = [
68
+ "unpythonic",
69
+ ]
70
+ excludes = [
71
+ "**/tests",
72
+ "**/__pycache__",
73
+ ]
74
+
75
+ [tool.mypy]
76
+ show_error_codes = true
@@ -7,7 +7,7 @@ If you have ``mcpyrate`` installed, see also ``unpythonic.syntax``
7
7
  for a trip down the rabbit hole.
8
8
  """
9
9
 
10
- __version__ = '0.15.3'
10
+ __version__ = '1.0.0'
11
11
 
12
12
  from .amb import * # noqa: F401, F403
13
13
  from .arity import * # noqa: F401, F403
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Dialects: Python the way you want it.
3
+
4
+ These dialects, i.e. whole-module syntax transformations, are powered by
5
+ `mcpyrate`'s dialect subsystem. The user manual is at:
6
+ https://github.com/Technologicat/mcpyrate/blob/master/doc/dialects.md
7
+
8
+ We provide these dialects mainly to demonstrate how to use that subsystem
9
+ to customize Python beyond what a local macro expander can do.
10
+
11
+ For examples of how to use these particular dialects, see the unit tests.
12
+ """
13
+
14
+ # re-exports
15
+ from .lispython import * # noqa: F401, F403
16
+ from .listhell import * # noqa: F401, F403
17
+ from .pytkell import * # noqa: F401, F403
@@ -0,0 +1,88 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Lispython: The love child of Python and Scheme.
3
+
4
+ Powered by `mcpyrate` and `unpythonic`.
5
+ """
6
+
7
+ __all__ = ["Lispython", "Lispy"]
8
+
9
+ __version__ = '2.0.0'
10
+
11
+ from mcpyrate.quotes import macros, q # noqa: F401
12
+
13
+ from mcpyrate.dialects import Dialect
14
+ from mcpyrate.splicing import splice_dialect
15
+
16
+ class Lispython(Dialect):
17
+ """**Schemers rejoice!**
18
+
19
+ Multiple musings mix in a lambda,
20
+ Lament no longer the lack of let.
21
+ Languish no longer labelless, lambda,
22
+ Linked lists cons and fold.
23
+ Tail-call into recursion divine,
24
+ The final value always provide.
25
+ """
26
+
27
+ def transform_ast(self, tree): # tree is an ast.Module
28
+ with q as template:
29
+ __lang__ = "Lispython" # noqa: F841, just provide it to user code.
30
+ from unpythonic.syntax import (macros, tco, autoreturn, # noqa: F401, F811
31
+ multilambda, quicklambda, namedlambda, fn,
32
+ where,
33
+ let, letseq, letrec,
34
+ dlet, dletseq, dletrec,
35
+ blet, bletseq, bletrec,
36
+ local, delete, do, do0,
37
+ let_syntax, abbrev, block, expr,
38
+ cond)
39
+ from unpythonic import cons, car, cdr, ll, llist, nil, prod, dyn, Values # noqa: F401, F811
40
+ with autoreturn, quicklambda, multilambda, namedlambda, tco:
41
+ __paste_here__ # noqa: F821, just a splicing marker.
42
+
43
+ # Beginning with 3.6.0, `mcpyrate` makes available the source location info
44
+ # of the dialect-import that imported this dialect.
45
+ if hasattr(self, "lineno"): # mcpyrate 3.6.0+
46
+ tree.body = splice_dialect(tree.body, template, "__paste_here__",
47
+ lineno=self.lineno, col_offset=self.col_offset)
48
+ else:
49
+ tree.body = splice_dialect(tree.body, template, "__paste_here__")
50
+
51
+ return tree
52
+
53
+
54
+ class Lispy(Dialect):
55
+ """**Pythonistas rejoice!**
56
+
57
+ O language like Lisp, like Python!
58
+ Semantic changes sensibly carry,
59
+ Python's primary virtue vindicate.
60
+ Ire me not with implicit imports,
61
+ Let my IDE label mistakes.
62
+ """
63
+
64
+ def transform_ast(self, tree): # tree is an ast.Module
65
+ with q as template:
66
+ __lang__ = "Lispy" # noqa: F841, just provide it to user code.
67
+ from unpythonic.syntax import (macros, tco, autoreturn, # noqa: F401, F811
68
+ multilambda, quicklambda, namedlambda)
69
+ # The important point is none of these expect the user code to look like
70
+ # anything but regular Python, so IDEs won't yell about undefined names;
71
+ # just the semantics are slightly different.
72
+ #
73
+ # Even if the user code uses `fn[]` (to make `quicklambda` actually do anything),
74
+ # that macro must be explicitly imported. It works, because `splice_dialect`
75
+ # hoists macro-imports from the top level of the user code into the top level
76
+ # of the template.
77
+ with autoreturn, quicklambda, multilambda, namedlambda, tco:
78
+ __paste_here__ # noqa: F821, just a splicing marker.
79
+
80
+ # Beginning with 3.6.0, `mcpyrate` makes available the source location info
81
+ # of the dialect-import that imported this dialect.
82
+ if hasattr(self, "lineno"): # mcpyrate 3.6.0+
83
+ tree.body = splice_dialect(tree.body, template, "__paste_here__",
84
+ lineno=self.lineno, col_offset=self.col_offset)
85
+ else:
86
+ tree.body = splice_dialect(tree.body, template, "__paste_here__")
87
+
88
+ return tree
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Listhell: It's not Lisp, it's not Python, it's not Haskell.
3
+
4
+ Powered by `mcpyrate` and `unpythonic`.
5
+ """
6
+
7
+ __all__ = ["Listhell"]
8
+
9
+ __version__ = '2.0.0'
10
+
11
+ from mcpyrate.quotes import macros, q # noqa: F401
12
+
13
+ from mcpyrate.dialects import Dialect
14
+ from mcpyrate.splicing import splice_dialect
15
+
16
+ class Listhell(Dialect):
17
+ def transform_ast(self, tree): # tree is an ast.Module
18
+ with q as template:
19
+ __lang__ = "Listhell" # noqa: F841, just provide it to user code.
20
+ from unpythonic.syntax import macros, prefix, q, u, kw, autocurry # noqa: F401, F811
21
+ # Auxiliary syntax elements for the macros
22
+ from unpythonic import apply # noqa: F401
23
+ from unpythonic import composerc as compose # compose from Right, Currying # noqa: F401
24
+ with prefix, autocurry:
25
+ __paste_here__ # noqa: F821, just a splicing marker.
26
+
27
+ # Beginning with 3.6.0, `mcpyrate` makes available the source location info
28
+ # of the dialect-import that imported this dialect.
29
+ if hasattr(self, "lineno"): # mcpyrate 3.6.0+
30
+ tree.body = splice_dialect(tree.body, template, "__paste_here__",
31
+ lineno=self.lineno, col_offset=self.col_offset)
32
+ else:
33
+ tree.body = splice_dialect(tree.body, template, "__paste_here__")
34
+
35
+ return tree
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Pytkell: Because it's good to have a kell.
3
+
4
+ Powered by `mcpyrate` and `unpythonic`.
5
+ """
6
+
7
+ __all__ = ["Pytkell"]
8
+
9
+ __version__ = '2.0.0'
10
+
11
+ from mcpyrate.quotes import macros, q # noqa: F401
12
+
13
+ from mcpyrate.dialects import Dialect
14
+ from mcpyrate.splicing import splice_dialect
15
+
16
+ class Pytkell(Dialect):
17
+ def transform_ast(self, tree): # tree is an ast.Module
18
+ with q as template:
19
+ __lang__ = "Pytkell" # noqa: F841, just provide it to user code.
20
+ from unpythonic.syntax import (macros, lazy, lazyrec, lazify, autocurry, # noqa: F401, F811
21
+ where,
22
+ let, letseq, letrec,
23
+ dlet, dletseq, dletrec,
24
+ blet, bletseq, bletrec,
25
+ local, delete, do, do0,
26
+ cond, forall)
27
+ # Auxiliary syntax elements for the macros.
28
+ from unpythonic.syntax import insist, deny # noqa: F401
29
+ # Functions that have a haskelly feel to them.
30
+ from unpythonic import (foldl, foldr, scanl, scanr, # noqa: F401
31
+ s, imathify, gmathify, frozendict,
32
+ memoize, fupdate, fup,
33
+ gmemoize, imemoize, fimemoize,
34
+ islice, take, drop, split_at, first, second, nth, last,
35
+ flip, rotate)
36
+ from unpythonic import composerc as compose # compose from Right, Currying (Haskell's . operator) # noqa: F401
37
+ # This is a bit lispy, but we're not going out of our way to provide
38
+ # a haskelly surface syntax for these.
39
+ from unpythonic import cons, car, cdr, ll, llist, nil # noqa: F401
40
+ with lazify, autocurry:
41
+ __paste_here__ # noqa: F821, just a splicing marker.
42
+
43
+ # Beginning with 3.6.0, `mcpyrate` makes available the source location info
44
+ # of the dialect-import that imported this dialect.
45
+ if hasattr(self, "lineno"): # mcpyrate 3.6.0+
46
+ tree.body = splice_dialect(tree.body, template, "__paste_here__",
47
+ lineno=self.lineno, col_offset=self.col_offset)
48
+ else:
49
+ tree.body = splice_dialect(tree.body, template, "__paste_here__")
50
+
51
+ return tree