basilisp
Advanced tools
| import decimal | ||
| import fractions | ||
| import functools | ||
| import math | ||
| from fractions import Fraction | ||
| from typing import Callable, TypeVar | ||
| from basilisp.lang.typing import LispNumber | ||
| T_num = TypeVar("T_num", bound=LispNumber) | ||
| def _normalize_fraction_result( | ||
| f: Callable[[T_num, LispNumber], LispNumber], | ||
| ) -> Callable[[T_num, LispNumber], LispNumber]: | ||
| """ | ||
| Decorator for arithmetic operations to simplify `fractions.Fraction` values with | ||
| a denominator of 1 to an integer. | ||
| """ | ||
| @functools.wraps(f) | ||
| def _normalize(x: T_num, y: LispNumber) -> LispNumber: | ||
| result = f(x, y) | ||
| # fractions.Fraction.is_integer() wasn't added until 3.12 | ||
| return ( | ||
| result.numerator | ||
| if isinstance(result, fractions.Fraction) and result.denominator == 1 | ||
| else result | ||
| ) | ||
| return _normalize | ||
| def _to_decimal(x: LispNumber) -> decimal.Decimal: | ||
| """Coerce the input Lisp number to a `decimal.Decimal`. | ||
| `fractions.Fraction` types are not accepted as direct inputs, so this is a utility | ||
| to simplify that coercion..""" | ||
| if isinstance(x, Fraction): | ||
| numerator, denominator = x.as_integer_ratio() | ||
| return decimal.Decimal(numerator) / decimal.Decimal(denominator) | ||
| return decimal.Decimal(x) | ||
| # All the arithmetic helpers below downcast `decimal.Decimal` values down to floats | ||
| # in any binary arithmetic operation which involves one `float` and one `decimal.Decimal`. | ||
| # This perhaps peculiar behavior, but it is what Clojure does. I suspect that is due | ||
| # to the potential loss of precision with any calculation between these two types, so | ||
| # Clojure errs on the side of returning the less precise type to indicate the potential | ||
| # lossiness of the calculation. | ||
| @functools.singledispatch | ||
| @_normalize_fraction_result | ||
| def add(x: LispNumber, y: LispNumber) -> LispNumber: | ||
| """Add two numbers together and return the result.""" | ||
| return x + y # type: ignore[operator] | ||
| @add.register(float) | ||
| @_normalize_fraction_result | ||
| def _add_float(x: float, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return float(decimal.Decimal(x) + y) | ||
| return x + y | ||
| @add.register(decimal.Decimal) | ||
| @_normalize_fraction_result | ||
| def _add_decimal(x: decimal.Decimal, y: LispNumber) -> LispNumber: | ||
| v = x + _to_decimal(y) | ||
| return float(v) if isinstance(y, float) else v | ||
| @add.register(Fraction) | ||
| @_normalize_fraction_result | ||
| def _add_fraction(x: Fraction, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return _to_decimal(x) + y | ||
| return x + y | ||
| @functools.singledispatch | ||
| @_normalize_fraction_result | ||
| def subtract(x: LispNumber, y: LispNumber) -> LispNumber: | ||
| """Subtract `y` from `x` and return the result.""" | ||
| return x - y # type: ignore[operator] | ||
| @subtract.register(float) | ||
| @_normalize_fraction_result | ||
| def _subtract_float(x: float, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return float(decimal.Decimal(x) - y) | ||
| return x - y | ||
| @subtract.register(decimal.Decimal) | ||
| @_normalize_fraction_result | ||
| def _subtract_decimal(x: decimal.Decimal, y: LispNumber) -> LispNumber: | ||
| v = x - _to_decimal(y) | ||
| return float(v) if isinstance(y, float) else v | ||
| @subtract.register(Fraction) | ||
| @_normalize_fraction_result | ||
| def _subtract_fraction(x: Fraction, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return _to_decimal(x) - y | ||
| return x - y | ||
| @functools.singledispatch | ||
| @_normalize_fraction_result | ||
| def divide(x: LispNumber, y: LispNumber) -> LispNumber: | ||
| """Division reducer. If both arguments are integers, return a Fraction. | ||
| Otherwise, return the true division of x and y.""" | ||
| return x / y # type: ignore[operator] | ||
| @divide.register(int) | ||
| @_normalize_fraction_result | ||
| def _divide_ints(x: int, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, int): | ||
| return Fraction(x, y) | ||
| return x / y | ||
| @divide.register(float) | ||
| @_normalize_fraction_result | ||
| def _divide_float(x: float, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return float(decimal.Decimal(x) / y) | ||
| try: | ||
| return x / y | ||
| except ZeroDivisionError: | ||
| if math.isnan(x): | ||
| return math.nan | ||
| elif x >= 0: | ||
| return math.inf | ||
| else: | ||
| return -math.inf | ||
| @divide.register(decimal.Decimal) | ||
| @_normalize_fraction_result | ||
| def _divide_decimal(x: decimal.Decimal, y: LispNumber) -> LispNumber: | ||
| v = x / _to_decimal(y) | ||
| return float(v) if isinstance(y, float) else v | ||
| @divide.register(Fraction) | ||
| @_normalize_fraction_result | ||
| def _divide_fraction(x: Fraction, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return _to_decimal(x) / y | ||
| return x / y | ||
| @functools.singledispatch | ||
| @_normalize_fraction_result | ||
| def multiply(x: LispNumber, y: LispNumber) -> LispNumber: | ||
| """Multiply two numbers together and return the result.""" | ||
| return x * y # type: ignore[operator] | ||
| @multiply.register(float) | ||
| @_normalize_fraction_result | ||
| def _multiply_float(x: float, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return float(decimal.Decimal(x) * y) | ||
| return x * y | ||
| @multiply.register(decimal.Decimal) | ||
| @_normalize_fraction_result | ||
| def _multiply_decimal(x: decimal.Decimal, y: LispNumber) -> LispNumber: | ||
| v = x * _to_decimal(y) | ||
| return float(v) if isinstance(y, float) else v | ||
| @multiply.register(Fraction) | ||
| @_normalize_fraction_result | ||
| def _multiply_fraction(x: Fraction, y: LispNumber) -> LispNumber: | ||
| if isinstance(y, decimal.Decimal): | ||
| return _to_decimal(x) * y | ||
| return x * y | ||
| @functools.singledispatch | ||
| def trunc(x: LispNumber) -> LispNumber: | ||
| """Truncate any fractional part of the input value, preserving the input type. | ||
| Truncation is effectively rounding towards 0.""" | ||
| return math.trunc(x) | ||
| @trunc.register(float) | ||
| def _trunc_float(x: float) -> LispNumber: | ||
| return float(math.trunc(x)) | ||
| @trunc.register(decimal.Decimal) | ||
| def _trunc_decimal(x: decimal.Decimal) -> LispNumber: | ||
| return decimal.Decimal(math.trunc(x)) | ||
| @trunc.register(Fraction) | ||
| def _trunc_fraction(x: Fraction) -> LispNumber: | ||
| v = fractions.Fraction(math.trunc(x)) | ||
| return v.numerator if v.denominator == 1 else v |
+9
-12
@@ -1,16 +0,14 @@ | ||
| Metadata-Version: 2.3 | ||
| Metadata-Version: 2.4 | ||
| Name: basilisp | ||
| Version: 0.4.0 | ||
| Version: 0.5.0.dev2 | ||
| Summary: A Clojure-like lisp written for Python | ||
| License: Eclipse Public License 1.0 (EPL-1.0) | ||
| License-Expression: EPL-1.0 | ||
| License-File: LICENSE | ||
| Author: Christopher Rink | ||
| Author-email: chrisrink10@gmail.com | ||
| Requires-Python: >=3.9,<4.0 | ||
| Author-email: chris@crink.dev | ||
| Requires-Python: >=3.10 | ||
| Classifier: Development Status :: 4 - Beta | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0) | ||
| Classifier: License :: Other/Proprietary License | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
@@ -20,2 +18,3 @@ Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Programming Language :: Python :: 3.13 | ||
| Classifier: Programming Language :: Python :: 3.14 | ||
| Classifier: Programming Language :: Python :: Implementation :: CPython | ||
@@ -33,4 +32,2 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy | ||
| Requires-Dist: typing-extensions (>=4.7.0,<5.0.0) | ||
| Project-URL: Documentation, https://basilisp.readthedocs.io/ | ||
| Project-URL: Repository, https://github.com/basilisp-lang/basilisp | ||
| Description-Content-Type: text/markdown | ||
@@ -40,5 +37,5 @@ | ||
| A Clojure-compatible(-ish) Lisp dialect targeting Python 3.9+. | ||
| A Clojure-compatible(-ish) Lisp dialect targeting Python 3.10+. | ||
| [](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://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) | ||
@@ -45,0 +42,0 @@ ## Getting Started |
+39
-37
@@ -1,8 +0,11 @@ | ||
| [tool.poetry] | ||
| [project] | ||
| name = "basilisp" | ||
| version = "0.4.0" | ||
| version = "0.5.0.dev2" | ||
| description = "A Clojure-like lisp written for Python" | ||
| authors = ["Christopher Rink <chrisrink10@gmail.com>"] | ||
| license = "Eclipse Public License 1.0 (EPL-1.0)" | ||
| authors = [ | ||
| { name = "Christopher Rink", email = "chris@crink.dev" }, | ||
| ] | ||
| license = "EPL-1.0" | ||
| readme = "README.md" | ||
| requires-python = ">=3.10" | ||
| packages = [ | ||
@@ -18,6 +21,4 @@ { include = "basilisp", from = "src" }, | ||
| "Intended Audience :: Developers", | ||
| "License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0)", | ||
| "Programming Language :: Python", | ||
| "Programming Language :: Python :: 3", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
@@ -27,2 +28,3 @@ "Programming Language :: Python :: 3.11", | ||
| "Programming Language :: Python :: 3.13", | ||
| "Programming Language :: Python :: 3.14", | ||
| "Programming Language :: Python :: Implementation :: CPython", | ||
@@ -33,44 +35,44 @@ "Programming Language :: Python :: Implementation :: PyPy", | ||
| include = ["README.md", "LICENSE"] | ||
| dependencies = [ | ||
| "attrs >=22.2.0", | ||
| "immutables (>=0.20,<1.0.0)", | ||
| "prompt-toolkit (>=3.0.0,<4.0.0)", | ||
| "pyrsistent (>=0.18.0,<1.0.0)", | ||
| "typing-extensions (>=4.7.0,<5.0.0)", | ||
| ] | ||
| [tool.poetry.dependencies] | ||
| python = "^3.9" | ||
| attrs = ">=22.2.0" | ||
| immutables = ">=0.20,<1.0.0" | ||
| prompt-toolkit = ">=3.0.0,<4.0.0" | ||
| pyrsistent = ">=0.18.0,<1.0.0" | ||
| typing-extensions = ">=4.7.0,<5.0.0" | ||
| pytest = { version = ">=7.0.0,<9.0.0", optional = true } | ||
| pygments = { version = ">=2.9.0,<3.0.0", optional = true } | ||
| [tool.poetry.group.dev.dependencies] | ||
| black = ">=24.0.0" | ||
| docutils = "*" | ||
| isort = "*" | ||
| pygments = "*" | ||
| pytest = ">=7.0.0,<9.0.0" | ||
| pytest-pycharm = "*" | ||
| [dependency-groups] | ||
| dev = [ | ||
| "black >=24.0.0", | ||
| "docutils", | ||
| "isort", | ||
| "pygments", | ||
| "pytest (>=7.0.0,<9.0.0)", | ||
| "pytest-pycharm", | ||
| "tox", | ||
| ] | ||
| # Ensure the Sphinx version remains synchronized with docs/requirements.txt | ||
| # to maintain consistent output during both development and publishing on | ||
| # Read The Docs. | ||
| sphinx = "^7.1.0" | ||
| sphinx-autobuild = { version = "^2024.04.16", python = ">=3.9" } | ||
| sphinx-copybutton = "^0.5.2" | ||
| sphinxext-opengraph = "^v0.9.1" | ||
| furo = "^2023.08.19" | ||
| tox = "*" | ||
| docs = [ | ||
| "furo >=2023.08.19", | ||
| "sphinx (>=7.1.0,<8.0.0)", | ||
| "sphinx-autobuild >=2024.04.16", | ||
| "sphinx-copybutton (>=0.5.2,<6.0.0)", | ||
| "sphinxext-opengraph (>=v0.9.1,<1.0.0)", | ||
| ] | ||
| [tool.poetry.extras] | ||
| pygments = ["pygments"] | ||
| pytest = ["pytest"] | ||
| [project.optional-dependencies] | ||
| pygments = ["pygments (>=2.9.0,<3.0.0)"] | ||
| pytest = ["pytest (>=7.0.0,<9.0.0)"] | ||
| [tool.poetry.scripts] | ||
| [project.scripts] | ||
| basilisp = "basilisp.cli:invoke_cli" | ||
| basilisp-run = "basilisp.cli:run_script" | ||
| [tool.poetry.plugins.pytest11] | ||
| [project.entry-points.pytest11] | ||
| basilisp_test_runner = "basilisp.contrib.pytest.testrunner" | ||
| [build-system] | ||
| requires = ["poetry-core>=1.0.0"] | ||
| requires = ["poetry-core>=2.0.0"] | ||
| build-backend = "poetry.core.masonry.api" | ||
@@ -112,2 +114,3 @@ | ||
| ] | ||
| patch = ["subprocess"] | ||
@@ -243,3 +246,2 @@ [tool.coverage.paths] | ||
| module = [ | ||
| "astor.*", | ||
| "prompt_toolkit.*", | ||
@@ -246,0 +248,0 @@ "pygments.*", |
+2
-2
| # 🐍 basilisp 🐍 | ||
| A Clojure-compatible(-ish) Lisp dialect targeting Python 3.9+. | ||
| A Clojure-compatible(-ish) Lisp dialect targeting Python 3.10+. | ||
| [](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://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) | ||
@@ -7,0 +7,0 @@ ## Getting Started |
+18
-10
@@ -9,5 +9,5 @@ import argparse | ||
| import types | ||
| from collections.abc import Sequence | ||
| from collections.abc import Callable, Sequence | ||
| from pathlib import Path | ||
| from typing import Any, Callable, Optional, Union | ||
| from typing import Any, Union | ||
@@ -101,3 +101,3 @@ from basilisp import main as basilisp | ||
| def _to_bool(v: Optional[str]) -> Optional[bool]: | ||
| def _to_bool(v: str | None) -> bool | None: | ||
| """Coerce a string argument to a boolean value, if possible.""" | ||
@@ -394,4 +394,4 @@ if v is None: | ||
| *, | ||
| help: Optional[str] = None, # pylint: disable=redefined-builtin | ||
| description: Optional[str] = None, | ||
| help: str | None = None, # pylint: disable=redefined-builtin | ||
| description: str | None = None, | ||
| handler: Handler, | ||
@@ -751,2 +751,12 @@ allows_extra: bool = False, | ||
| else: | ||
| # `basilisp` declares the testrunner as a pytest plugin, so | ||
| # pytest tries to import it for assertion rewriting. Since | ||
| # it's already imported, pytest emits a warning. As rewriting | ||
| # isn't needed, we ignore it. (Requires pytest >=8.4.0 to take | ||
| # effect) | ||
| extra = [ | ||
| "-W", | ||
| "ignore:Module already imported so cannot be rewritten; basilisp:pytest.PytestAssertRewriteWarning", | ||
| ] + extra | ||
| sys.exit(pytest.main(args=list(extra))) | ||
@@ -758,4 +768,3 @@ | ||
| help="run tests in a Basilisp project", | ||
| description=textwrap.dedent( | ||
| """Run tests in a Basilisp project. | ||
| description=textwrap.dedent("""Run tests in a Basilisp project. | ||
@@ -778,4 +787,3 @@ Any options not recognized by Basilisp and all positional arguments will | ||
| Returns the PyTest exit code as the exit code.""" | ||
| ), | ||
| Returns the PyTest exit code as the exit code."""), | ||
| handler=test, | ||
@@ -819,3 +827,3 @@ allows_extra=True, | ||
| def invoke_cli(args: Optional[Sequence[str]] = None) -> None: | ||
| def invoke_cli(args: Sequence[str] | None = None) -> None: | ||
| """Entrypoint to run the Basilisp CLI.""" | ||
@@ -822,0 +830,0 @@ parser = argparse.ArgumentParser( |
| import importlib.util | ||
| import inspect | ||
| import os | ||
| import re | ||
| import sys | ||
| import traceback | ||
| from collections.abc import Iterable, Iterator | ||
| from collections.abc import Callable, Iterable, Iterator | ||
| from functools import cache | ||
| from pathlib import Path | ||
| from types import GeneratorType | ||
| from typing import Callable, Optional | ||
@@ -61,7 +62,33 @@ import pytest | ||
| @cache | ||
| def _get_test_file_path() -> list[str] | None: | ||
| """Return a list of string paths which should be searched for test files. | ||
| If `None`, use PyTest's normal collection heuristics.""" | ||
| _test_path = os.getenv("BASILISP_TEST_PATH", "").strip() | ||
| return ( | ||
| [str(Path(p).absolute()) for p in _test_path.split(os.pathsep)] | ||
| if _test_path | ||
| else None | ||
| ) | ||
| @cache | ||
| def _get_test_file_pattern() -> re.Pattern: | ||
| """Return a regular expression pattern which can be used to match test files.""" | ||
| _test_file_pattern = os.getenv( | ||
| "BASILISP_TEST_FILE_PATTERN", r"(test_[^.]*|.*_test)\.(lpy|cljc)" | ||
| ) | ||
| return re.compile(_test_file_pattern) | ||
| def pytest_collect_file(file_path: Path, parent): | ||
| """Primary PyTest hook to identify Basilisp test files.""" | ||
| if file_path.suffix == ".lpy": | ||
| if file_path.name.startswith("test_") or file_path.stem.endswith("_test"): | ||
| return BasilispFile.from_parent(parent, path=file_path) | ||
| test_paths = _get_test_file_path() | ||
| if test_paths and not any(str(file_path).startswith(p) for p in test_paths): | ||
| return None | ||
| if _get_test_file_pattern().fullmatch(file_path.name): | ||
| return BasilispFile.from_parent(parent, path=file_path) | ||
| return None | ||
@@ -98,3 +125,3 @@ | ||
| FixtureTeardown = Iterator[None] | ||
| FixtureFunction = Callable[[], Optional[FixtureTeardown]] | ||
| FixtureFunction = Callable[[], FixtureTeardown | None] | ||
@@ -113,3 +140,3 @@ | ||
| @staticmethod | ||
| def _run_fixture(fixture: FixtureFunction) -> Optional[Iterator[None]]: | ||
| def _run_fixture(fixture: FixtureFunction) -> Iterator[None] | None: | ||
| """Run a fixture function. If the fixture is a generator function, return the | ||
@@ -177,3 +204,7 @@ generator/coroutine. Otherwise, simply return the value from the function, if | ||
| for file in files: | ||
| if file in {"__init__.lpy", "__init__.py"} or file.endswith(".lpy"): | ||
| if ( | ||
| file in {"__init__.lpy", "__init__.py"} | ||
| or file.endswith(".lpy") | ||
| or file.endswith(".cljc") | ||
| ): | ||
| return True | ||
@@ -206,3 +237,3 @@ return False | ||
| super().__init__(**kwargs) | ||
| self._fixture_manager: Optional[FixtureManager] = None | ||
| self._fixture_manager: FixtureManager | None = None | ||
@@ -256,3 +287,3 @@ @staticmethod | ||
| exc: Optional[ModuleNotFoundError] = None | ||
| exc: ModuleNotFoundError | None = None | ||
| for modname in modnames: | ||
@@ -369,3 +400,3 @@ try: | ||
| results: lmap.PersistentMap = self._run_test() | ||
| failures: Optional[vec.PersistentVector] = results.val_at(_FAILURES_KW) | ||
| failures: vec.PersistentVector | None = results.val_at(_FAILURES_KW) | ||
| if runtime.to_seq(failures): | ||
@@ -401,3 +432,3 @@ raise TestFailuresInfo("Test failures", lmap.map(results)) | ||
| def _error_msg(self, exc: Exception, line: Optional[int] = None) -> str: | ||
| def _error_msg(self, exc: Exception, line: int | None = None) -> str: | ||
| line_msg = Maybe(line).map(lambda l: f":{l}").or_else_get("") | ||
@@ -404,0 +435,0 @@ messages = [f"ERROR in ({self.name}) ({self._filename}{line_msg})", "\n\n"] |
@@ -6,3 +6,3 @@ import importlib | ||
| import types | ||
| from typing import Any, Optional, cast | ||
| from typing import Any, cast | ||
@@ -55,3 +55,3 @@ from sphinx.ext.autodoc import ( | ||
| def _get_doc(reference: IReference) -> Optional[list[list[str]]]: | ||
| def _get_doc(reference: IReference) -> list[list[str]] | None: | ||
| """Return the docstring of an IReference type (e.g. Namespace or Var).""" | ||
@@ -84,3 +84,3 @@ docstring = reference.meta and reference.meta.val_at(_DOC_KW) | ||
| object: Optional[runtime.Namespace] | ||
| object: runtime.Namespace | None | ||
@@ -128,3 +128,3 @@ @classmethod | ||
| def get_doc(self) -> Optional[list[list[str]]]: | ||
| def get_doc(self) -> list[list[str]] | None: | ||
| assert self.object is not None | ||
@@ -162,3 +162,3 @@ return _get_doc(self.object) | ||
| # Ignore undocumented members unless undoc_members is set | ||
| docstring: Optional[str] = val.meta.val_at(_DOC_KW) | ||
| docstring: str | None = val.meta.val_at(_DOC_KW) | ||
| if docstring is None and not self.options.undoc_members: | ||
@@ -223,3 +223,3 @@ continue | ||
| object: Optional[runtime.Var] | ||
| object: runtime.Var | None | ||
@@ -301,3 +301,3 @@ @classmethod | ||
| def get_doc(self) -> Optional[list[list[str]]]: | ||
| def get_doc(self) -> list[list[str]] | None: | ||
| assert self.object is not None | ||
@@ -304,0 +304,0 @@ return _get_doc(self.object) |
| import logging | ||
| from collections import defaultdict | ||
| from collections.abc import Iterable | ||
| from typing import Any, NamedTuple, Optional, Union, cast | ||
| from typing import Any, NamedTuple, cast | ||
@@ -319,3 +319,3 @@ from docutils import nodes | ||
| def generate( # pylint: disable=too-many-locals | ||
| self, docnames: Optional[Iterable[str]] = None | ||
| self, docnames: Iterable[str] | None = None | ||
| ) -> tuple[list[tuple[str, list[IndexEntry]]], bool]: | ||
@@ -552,6 +552,6 @@ content: dict[str, list[IndexEntry]] = defaultdict(list) | ||
| contnode: Element, | ||
| ) -> Optional[Element]: | ||
| ) -> Element | None: | ||
| nsname = node.get("lpy:namespace") | ||
| maybe_obj: Union[FormEntry, NamespaceEntry, VarEntry, None] | ||
| maybe_obj: FormEntry | NamespaceEntry | VarEntry | None | ||
| reftype = node.get("reftype") | ||
@@ -558,0 +558,0 @@ if reftype == "ns": |
@@ -12,3 +12,3 @@ import importlib.util | ||
| from importlib.machinery import ModuleSpec | ||
| from typing import Any, Optional, cast | ||
| from typing import Any, cast | ||
@@ -148,5 +148,5 @@ from typing_extensions import TypedDict | ||
| fullname: str, | ||
| path: Optional[Sequence[str]], | ||
| target: Optional[types.ModuleType] = None, | ||
| ) -> Optional[ModuleSpec]: | ||
| path: Sequence[str] | None, | ||
| target: types.ModuleType | None = None, | ||
| ) -> ModuleSpec | None: | ||
| """Find the ModuleSpec for the specified Basilisp module. | ||
@@ -239,3 +239,3 @@ | ||
| def get_code(self, fullname: str) -> Optional[types.CodeType]: | ||
| def get_code(self, fullname: str) -> types.CodeType | None: | ||
| """Return code to load a Basilisp module. | ||
@@ -291,4 +291,15 @@ | ||
| def create_module(self, spec: ModuleSpec) -> BasilispModule: | ||
| logger.debug(f"Creating Basilisp module '{spec.name}'") | ||
| mod = BasilispModule(spec.name) | ||
| # If a namespace was created dynamically before being require'd, then | ||
| # a module will already exist for the namespace. References may already | ||
| # have been made to the contents of that module. Reusing it rather than | ||
| # starting new allows both dynamically created namespaces and namespaces | ||
| # defined in files to coexist. | ||
| if (ns := runtime.Namespace.get(sym.symbol(demunge(spec.name)))) is not None: | ||
| logger.debug(f"Reusing existing module for namespace '{ns}'") | ||
| mod = ns.module | ||
| assert isinstance(mod, BasilispModule) | ||
| else: | ||
| logger.debug(f"Creating Basilisp module '{spec.name}'") | ||
| mod = BasilispModule(spec.name) | ||
| mod.__file__ = spec.loader_state["filename"] | ||
@@ -295,0 +306,0 @@ mod.__loader__ = spec.loader |
| import threading | ||
| from typing import Callable, Generic, Optional, TypeVar | ||
| from collections.abc import Callable | ||
| from typing import Concatenate, Generic, TypeVar | ||
| from typing_extensions import Concatenate, ParamSpec | ||
| from typing_extensions import ParamSpec | ||
@@ -20,6 +21,6 @@ from basilisp.lang import map as lmap | ||
| state: T, | ||
| meta: Optional[IPersistentMap] = None, | ||
| validator: Optional[RefValidator] = None, | ||
| meta: IPersistentMap | None = None, | ||
| validator: RefValidator | None = None, | ||
| ) -> None: | ||
| self._meta: Optional[IPersistentMap] = meta | ||
| self._meta: IPersistentMap | None = meta | ||
| self._state = state | ||
@@ -26,0 +27,0 @@ self._lock = threading.RLock() |
@@ -6,5 +6,5 @@ import ast | ||
| from ast import unparse | ||
| from collections.abc import Iterable | ||
| from collections.abc import Callable, Iterable | ||
| from pathlib import Path | ||
| from typing import Any, Callable, Optional | ||
| from typing import Any | ||
@@ -64,3 +64,3 @@ from basilisp.lang import list as llist | ||
| def __init__(self, filename: str, opts: Optional[CompilerOpts] = None): | ||
| def __init__(self, filename: str, opts: CompilerOpts | None = None): | ||
| self._filename = filename | ||
@@ -89,11 +89,11 @@ self._actx = AnalyzerContext(filename=filename, opts=opts) | ||
| def compiler_opts( # pylint: disable=too-many-arguments | ||
| generate_auto_inlines: Optional[bool] = None, | ||
| inline_functions: Optional[bool] = None, | ||
| warn_on_arity_mismatch: Optional[bool] = None, | ||
| warn_on_shadowed_name: Optional[bool] = None, | ||
| warn_on_shadowed_var: Optional[bool] = None, | ||
| warn_on_unused_names: Optional[bool] = None, | ||
| warn_on_non_dynamic_set: Optional[bool] = None, | ||
| use_var_indirection: Optional[bool] = None, | ||
| warn_on_var_indirection: Optional[bool] = None, | ||
| generate_auto_inlines: bool | None = None, | ||
| inline_functions: bool | None = None, | ||
| warn_on_arity_mismatch: bool | None = None, | ||
| warn_on_shadowed_name: bool | None = None, | ||
| warn_on_shadowed_var: bool | None = None, | ||
| warn_on_unused_names: bool | None = None, | ||
| warn_on_non_dynamic_set: bool | None = None, | ||
| use_var_indirection: bool | None = None, | ||
| warn_on_var_indirection: bool | None = None, | ||
| ) -> CompilerOpts: | ||
@@ -154,3 +154,3 @@ """Return a map of compiler options with defaults applied.""" | ||
| wrapped_fn_name: str = _DEFAULT_FN, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> Any: | ||
@@ -211,3 +211,3 @@ """Compile and execute the given form. This function will be most useful | ||
| source_filename: str, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> None: | ||
@@ -240,3 +240,3 @@ """Incrementally compile a stream of AST nodes in module mod. | ||
| module: BasilispModule, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> None: | ||
@@ -258,3 +258,3 @@ """Bootstrap a new module with imports and other boilerplate.""" | ||
| module: BasilispModule, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> None: | ||
@@ -308,3 +308,3 @@ """Compile an entire Basilisp module into Python bytecode which can be | ||
| ns: runtime.Namespace, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> Any: | ||
@@ -322,3 +322,3 @@ """Call :lpy:fn:`basilisp.core/load` with the given ``path``, returning the | ||
| ns: runtime.Namespace, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
| collect_bytecode: BytecodeCollector | None = None, | ||
| ) -> Any: | ||
@@ -325,0 +325,0 @@ """Call :lpy:fn:`basilisp.core/load-file` with the given ``path``, returning the |
@@ -5,3 +5,3 @@ import ast | ||
| from types import TracebackType | ||
| from typing import Any, Optional, Union | ||
| from typing import Any | ||
@@ -46,6 +46,6 @@ import attr | ||
| class _loc: | ||
| line: Optional[int] = None | ||
| col: Optional[int] = None | ||
| end_line: Optional[int] = None | ||
| end_col: Optional[int] = None | ||
| line: int | None = None | ||
| col: int | None = None | ||
| end_line: int | None = None | ||
| end_col: int | None = None | ||
@@ -66,5 +66,5 @@ def __bool__(self): | ||
| filename: str | ||
| form: Union[LispForm, None, ISeq] = None | ||
| lisp_ast: Optional[Node] = None | ||
| py_ast: Optional[Union[ast.expr, ast.stmt]] = None | ||
| form: LispForm | None | ISeq = None | ||
| lisp_ast: Node | None = None | ||
| py_ast: ast.expr | ast.stmt | None = None | ||
@@ -118,5 +118,5 @@ @property | ||
| e: CompilerException, | ||
| tp: Optional[type[Exception]] = None, | ||
| tb: Optional[TracebackType] = None, | ||
| disable_color: Optional[bool] = None, | ||
| tp: type[Exception] | None = None, | ||
| tb: TracebackType | None = None, | ||
| disable_color: bool | None = None, | ||
| ) -> list[str]: | ||
@@ -127,5 +127,5 @@ """Format a compiler exception as a list of newline-terminated strings. | ||
| code.""" | ||
| context_exc: Optional[BaseException] = e.__cause__ | ||
| context_exc: BaseException | None = e.__cause__ | ||
| lines = [os.linesep] | ||
| lines: list[str] = [os.linesep] | ||
| if context_exc is not None: | ||
@@ -132,0 +132,0 @@ lines.append(f" exception: {type(context_exc)} from {type(e)}{os.linesep}") |
| from abc import ABC, abstractmethod | ||
| from collections.abc import Iterable, MutableMapping, Sequence | ||
| from collections.abc import Callable, Iterable, MutableMapping, Sequence | ||
| from enum import Enum | ||
| from typing import Any, Callable, Generic, Optional, TypeVar, Union | ||
| from typing import Any, Generic, Optional, TypeVar, Union | ||
@@ -189,3 +189,3 @@ import attr | ||
| def fix_missing_locations( | ||
| self, form_loc: Optional[tuple[int, int, int, int]] = None | ||
| self, form_loc: tuple[int, int, int, int] | None = None | ||
| ) -> "Node[T]": | ||
@@ -211,3 +211,3 @@ """Return a transformed copy of this node with location in this node's | ||
| new_attrs: MutableMapping[str, Union[NodeEnv, Node, Iterable[Node]]] = { | ||
| new_attrs: MutableMapping[str, NodeEnv | Node | Iterable[Node]] = { | ||
| "env": attr.evolve( | ||
@@ -335,8 +335,8 @@ self.env, line=loc[0], col=loc[1], end_line=loc[2], end_col=loc[3] | ||
| file: str | ||
| line: Optional[int] = None | ||
| col: Optional[int] = None | ||
| end_line: Optional[int] = None | ||
| end_col: Optional[int] = None | ||
| pos: Optional[NodeSyntacticPosition] = None | ||
| func_ctx: Optional[FunctionContext] = None | ||
| line: int | None = None | ||
| col: int | None = None | ||
| end_line: int | None = None | ||
| end_col: int | None = None | ||
| pos: NodeSyntacticPosition | None = None | ||
| func_ctx: FunctionContext | None = None | ||
@@ -361,7 +361,7 @@ | ||
| env: NodeEnv = attr.field(hash=False) | ||
| tag: Optional[Node] = None | ||
| arg_id: Optional[int] = None | ||
| tag: Node | None = None | ||
| arg_id: int | None = None | ||
| is_variadic: bool = False | ||
| is_assignable: bool = False | ||
| init: Optional[Node] = None | ||
| init: Node | None = None | ||
| meta: NodeMeta = None | ||
@@ -406,6 +406,6 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| var: Var | ||
| init: Optional[Node] | ||
| doc: Optional[str] | ||
| init: Node | None | ||
| doc: str | None | ||
| env: NodeEnv = attr.field(hash=False) | ||
| tag: Optional[Node] = None | ||
| tag: Node | None = None | ||
| meta: NodeMeta = None | ||
@@ -463,3 +463,3 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| is_variadic: bool = False | ||
| kwarg_support: Optional[KeywordArgSupport] = None | ||
| kwarg_support: KeywordArgSupport | None = None | ||
| children: Sequence[kw.Keyword] = vec.v(CLASS_LOCAL, PARAMS, BODY) | ||
@@ -493,3 +493,3 @@ op: NodeOp = NodeOp.DEFTYPE_CLASSMETHOD | ||
| is_variadic: bool = False | ||
| kwarg_support: Optional[KeywordArgSupport] = None | ||
| kwarg_support: KeywordArgSupport | None = None | ||
| children: Sequence[kw.Keyword] = vec.v(THIS_LOCAL, PARAMS, BODY) | ||
@@ -522,3 +522,3 @@ op: NodeOp = NodeOp.DEFTYPE_METHOD_ARITY | ||
| is_variadic: bool = False | ||
| kwarg_support: Optional[KeywordArgSupport] = None | ||
| kwarg_support: KeywordArgSupport | None = None | ||
| children: Sequence[kw.Keyword] = vec.v(PARAMS, BODY) | ||
@@ -553,6 +553,6 @@ op: NodeOp = NodeOp.DEFTYPE_STATICMETHOD | ||
| env: NodeEnv = attr.field(hash=False) | ||
| local: Optional[Binding] = None | ||
| local: Binding | None = None | ||
| is_variadic: bool = False | ||
| is_async: bool = False | ||
| kwarg_support: Optional[KeywordArgSupport] = None | ||
| kwarg_support: KeywordArgSupport | None = None | ||
| inline_fn: Optional["Fn"] = None | ||
@@ -573,3 +573,3 @@ children: Sequence[kw.Keyword] = vec.v(ARITIES) | ||
| env: NodeEnv = attr.field(hash=False) | ||
| tag: Optional[Node] = None | ||
| tag: Node | None = None | ||
| is_variadic: bool = False | ||
@@ -598,3 +598,3 @@ children: Sequence[kw.Keyword] = vec.v(PARAMS, BODY) | ||
| class HostField(Node[Union[SpecialForm, sym.Symbol]], Assignable): | ||
| form: Union[SpecialForm, sym.Symbol] | ||
| form: SpecialForm | sym.Symbol | ||
| field: str | ||
@@ -627,4 +627,2 @@ target: Node | ||
| aliases: Iterable["ImportAlias"] | ||
| refers: Iterable[str] | ||
| refer_all: bool | ||
| env: NodeEnv = attr.field(hash=False) | ||
@@ -639,5 +637,7 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| class ImportAlias(Node[Union[sym.Symbol, vec.PersistentVector]]): | ||
| form: Union[sym.Symbol, vec.PersistentVector] | ||
| form: sym.Symbol | vec.PersistentVector | ||
| name: str | ||
| alias: Optional[str] | ||
| alias: str | None | ||
| refers: Iterable[str] | ||
| refer_all: bool | ||
| env: NodeEnv = attr.field(hash=False) | ||
@@ -694,3 +694,3 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| is_assignable: bool = False | ||
| arg_id: Optional[int] = None | ||
| arg_id: int | None = None | ||
| is_variadic: bool = False | ||
@@ -778,3 +778,3 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| class PySet(Node[Union[frozenset, set]]): | ||
| form: Union[frozenset, set] | ||
| form: frozenset | set | ||
| items: Iterable[Node] | ||
@@ -857,5 +857,5 @@ env: NodeEnv = attr.field(hash=False) | ||
| class RequireAlias(Node[Union[sym.Symbol, vec.PersistentVector]]): | ||
| form: Union[sym.Symbol, vec.PersistentVector] | ||
| form: sym.Symbol | vec.PersistentVector | ||
| name: str | ||
| alias: Optional[str] | ||
| alias: str | None | ||
| env: NodeEnv = attr.field(hash=False) | ||
@@ -893,3 +893,3 @@ children: Sequence[kw.Keyword] = vec.EMPTY | ||
| form: SpecialForm | ||
| target: Union[Assignable, Node] | ||
| target: Assignable | Node | ||
| val: Node | ||
@@ -907,3 +907,3 @@ env: NodeEnv = attr.field(hash=False) | ||
| exception: Node | ||
| cause: Optional[Node] | ||
| cause: Node | None | ||
| env: NodeEnv = attr.field(hash=False) | ||
@@ -923,3 +923,3 @@ children: Sequence[kw.Keyword] = vec.v(EXCEPTION) | ||
| env: NodeEnv = attr.field(hash=False) | ||
| finally_: Optional[Do] = None | ||
| finally_: Do | None = None | ||
| op: NodeOp = NodeOp.TRY | ||
@@ -932,3 +932,3 @@ top_level: bool = False | ||
| class VarRef(Node[Union[sym.Symbol, ISeq]], Assignable): | ||
| form: Union[sym.Symbol, ISeq] | ||
| form: sym.Symbol | ISeq | ||
| var: Var | ||
@@ -962,3 +962,3 @@ env: NodeEnv = attr.field(hash=False) | ||
| form: LispForm | ||
| meta: Union[Const, Map] | ||
| meta: Const | Map | ||
| expr: T_withmeta | ||
@@ -975,3 +975,3 @@ env: NodeEnv = attr.field(hash=False) | ||
| form: SpecialForm | ||
| expr: Optional[Node] | ||
| expr: Node | None | ||
| env: NodeEnv = attr.field(hash=False) | ||
@@ -978,0 +978,0 @@ children: Sequence[kw.Keyword] = vec.v(EXPR) |
@@ -6,3 +6,3 @@ import ast | ||
| from contextlib import contextmanager | ||
| from typing import Deque, Optional | ||
| from typing import Deque | ||
@@ -154,3 +154,3 @@ from basilisp.lang.compiler.constants import OPERATOR_ALIAS | ||
| def visit_ExceptHandler(self, node: ast.ExceptHandler) -> Optional[ast.AST]: | ||
| def visit_ExceptHandler(self, node: ast.ExceptHandler) -> ast.AST | None: | ||
| """Eliminate dead code from except handler bodies.""" | ||
@@ -168,3 +168,3 @@ new_node = self.generic_visit(node) | ||
| def visit_Expr(self, node: ast.Expr) -> Optional[ast.Expr]: | ||
| def visit_Expr(self, node: ast.Expr) -> ast.Expr | None: | ||
| """Eliminate no-op constant expressions which are in the tree | ||
@@ -176,3 +176,3 @@ as standalone statements.""" | ||
| def visit_FunctionDef(self, node: ast.FunctionDef) -> Optional[ast.AST]: | ||
| def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.AST | None: | ||
| """Eliminate dead code from function bodies.""" | ||
@@ -193,3 +193,3 @@ with self._new_global_context(): | ||
| def visit_Global(self, node: ast.Global) -> Optional[ast.Global]: | ||
| def visit_Global(self, node: ast.Global) -> ast.Global | None: | ||
| """Eliminate redundant name declarations inside a Python `global` statement. | ||
@@ -209,3 +209,3 @@ | ||
| def visit_If(self, node: ast.If) -> Optional[ast.AST]: | ||
| def visit_If(self, node: ast.If) -> ast.AST | None: | ||
| """Eliminate dead code from if/elif bodies. | ||
@@ -241,3 +241,3 @@ | ||
| def visit_While(self, node: ast.While) -> Optional[ast.AST]: | ||
| def visit_While(self, node: ast.While) -> ast.AST | None: | ||
| """Eliminate dead code from while bodies.""" | ||
@@ -255,3 +255,3 @@ new_node = self.generic_visit(node) | ||
| def visit_Try(self, node: ast.Try) -> Optional[ast.AST]: | ||
| def visit_Try(self, node: ast.Try) -> ast.AST | None: | ||
| """Eliminate dead code from except try bodies.""" | ||
@@ -258,0 +258,0 @@ new_node = self.generic_visit(node) |
@@ -1,2 +0,3 @@ | ||
| from typing import Callable, Generic, Optional, TypeVar | ||
| from collections.abc import Callable | ||
| from typing import Generic, TypeVar | ||
@@ -14,3 +15,3 @@ import attr | ||
| f: Callable[[], T] | ||
| value: Optional[T] | ||
| value: T | None | ||
| computed: bool = False | ||
@@ -32,3 +33,3 @@ | ||
| def deref(self) -> Optional[T]: | ||
| def deref(self) -> T | None: | ||
| return self._state.swap(self.__deref).value | ||
@@ -35,0 +36,0 @@ |
@@ -5,3 +5,2 @@ import functools | ||
| from types import TracebackType | ||
| from typing import Optional | ||
@@ -30,6 +29,6 @@ import attr | ||
| def format_exception( # pylint: disable=unused-argument | ||
| e: Optional[BaseException], | ||
| tp: Optional[type[BaseException]] = None, | ||
| tb: Optional[TracebackType] = None, | ||
| disable_color: Optional[bool] = None, | ||
| e: BaseException | None, | ||
| tp: type[BaseException] | None = None, | ||
| tb: TracebackType | None = None, | ||
| disable_color: bool | None = None, | ||
| ) -> list[str]: | ||
@@ -54,5 +53,5 @@ """Format an exception into something readable, returning a list of newline | ||
| def print_exception( | ||
| e: Optional[BaseException], | ||
| tp: Optional[type[BaseException]] = None, | ||
| tb: Optional[TracebackType] = None, | ||
| e: BaseException | None, | ||
| tp: type[BaseException] | None = None, | ||
| tb: TracebackType | None = None, | ||
| ) -> None: | ||
@@ -59,0 +58,0 @@ """Print the given exception `e` using Basilisp's own exception formatting. |
@@ -0,1 +1,2 @@ | ||
| from collections.abc import Callable | ||
| from concurrent.futures import Future as _Future # noqa # pylint: disable=unused-import | ||
@@ -5,3 +6,3 @@ from concurrent.futures import ProcessPoolExecutor as _ProcessPoolExecutor | ||
| from concurrent.futures import TimeoutError as _TimeoutError | ||
| from typing import Callable, Optional, TypeVar | ||
| from typing import TypeVar | ||
@@ -31,4 +32,4 @@ import attr | ||
| def deref( | ||
| self, timeout: Optional[float] = None, timeout_val: Optional[T] = None | ||
| ) -> Optional[T]: | ||
| self, timeout: float | None = None, timeout_val: T | None = None | ||
| ) -> T | None: | ||
| try: | ||
@@ -48,3 +49,3 @@ return self._future.result(timeout=timeout) | ||
| # still work with this Future wrapper. | ||
| def result(self, timeout: Optional[float] = None) -> T: | ||
| def result(self, timeout: float | None = None) -> T: | ||
| return self._future.result(timeout=timeout) | ||
@@ -59,3 +60,3 @@ | ||
| class ProcessPoolExecutor(_ProcessPoolExecutor): # pragma: no cover | ||
| def __init__(self, max_workers: Optional[int] = None): | ||
| def __init__(self, max_workers: int | None = None): | ||
| super().__init__(max_workers=max_workers) | ||
@@ -73,3 +74,3 @@ | ||
| self, | ||
| max_workers: Optional[int] = None, | ||
| max_workers: int | None = None, | ||
| thread_name_prefix: str = "basilisp-futures", | ||
@@ -76,0 +77,0 @@ ): |
| import itertools | ||
| from abc import ABC, abstractmethod | ||
| from collections.abc import Hashable, Iterable, Iterator, Mapping, Sequence, Sized | ||
| from collections.abc import ( | ||
| Callable, | ||
| Hashable, | ||
| Iterable, | ||
| Iterator, | ||
| Mapping, | ||
| Sequence, | ||
| Sized, | ||
| ) | ||
| from typing import ( | ||
| AbstractSet, | ||
| Any, | ||
| Callable, | ||
| Final, | ||
@@ -36,3 +43,3 @@ Generic, | ||
| @abstractmethod | ||
| def deref(self) -> Optional[T]: | ||
| def deref(self) -> T | None: | ||
| raise NotImplementedError() | ||
@@ -54,4 +61,4 @@ | ||
| def deref( | ||
| self, timeout: Optional[float] = None, timeout_val: Optional[T] = None | ||
| ) -> Optional[T]: | ||
| self, timeout: float | None = None, timeout_val: T | None = None | ||
| ) -> T | None: | ||
| raise NotImplementedError() | ||
@@ -183,3 +190,3 @@ | ||
| @abstractmethod | ||
| def ns(self) -> Optional[str]: | ||
| def ns(self) -> str | None: | ||
| raise NotImplementedError() | ||
@@ -189,3 +196,3 @@ | ||
| @abstractmethod | ||
| def with_name(cls, name: str, ns: Optional[str] = None) -> Self: | ||
| def with_name(cls, name: str, ns: str | None = None) -> Self: | ||
| """Create a new instance of this INamed with `name` and optional `ns`.""" | ||
@@ -246,7 +253,7 @@ raise NotImplementedError() | ||
| @abstractmethod | ||
| def get_validator(self) -> Optional[RefValidator[T]]: | ||
| def get_validator(self) -> RefValidator[T] | None: | ||
| raise NotImplementedError() | ||
| @abstractmethod | ||
| def set_validator(self, vf: Optional[RefValidator[T]] = None) -> None: | ||
| def set_validator(self, vf: RefValidator[T] | None = None) -> None: | ||
| raise NotImplementedError() | ||
@@ -312,3 +319,3 @@ | ||
| @abstractmethod | ||
| def val_at(self, k: K, default: Optional[V] = None) -> Optional[V]: | ||
| def val_at(self, k: K, default: V | None = None) -> V | None: | ||
| raise NotImplementedError() | ||
@@ -373,3 +380,3 @@ | ||
| @abstractmethod | ||
| def entry(self, k: K) -> Optional[IMapEntry[K, V]]: | ||
| def entry(self, k: K) -> IMapEntry[K, V] | None: | ||
| raise NotImplementedError() | ||
@@ -390,3 +397,3 @@ | ||
| @abstractmethod | ||
| def peek(self) -> Optional[T]: | ||
| def peek(self) -> T | None: | ||
| raise NotImplementedError() | ||
@@ -560,7 +567,7 @@ | ||
| T_tcoll_co = TypeVar("T_tcoll_co", bound="ITransientCollection", covariant=True) | ||
| T_tcoll = TypeVar("T_tcoll", bound="ITransientCollection") | ||
| # Including ABC as a base seems to cause catastrophic meltdown. | ||
| class IEvolveableCollection(Generic[T_tcoll_co]): | ||
| class IEvolveableCollection(Generic[T_tcoll]): | ||
| """``IEvolveableCollection`` types support creating transient variants of persistent | ||
@@ -575,3 +582,3 @@ data structures which can be modified efficiently and then returned back into | ||
| @abstractmethod | ||
| def to_transient(self) -> T_tcoll_co: | ||
| def to_transient(self) -> T_tcoll: | ||
| raise NotImplementedError() | ||
@@ -591,7 +598,7 @@ | ||
| @abstractmethod | ||
| def cons_transient(self: T_tcoll_co, *elems: T) -> "T_tcoll_co": | ||
| def cons_transient(self: T_tcoll, *elems: T) -> "T_tcoll": | ||
| raise NotImplementedError() | ||
| @abstractmethod | ||
| def to_persistent(self: T_tcoll_co) -> "IPersistentCollection[T]": | ||
| def to_persistent(self: T_tcoll) -> "IPersistentCollection[T]": | ||
| raise NotImplementedError() | ||
@@ -619,3 +626,3 @@ | ||
| @abstractmethod | ||
| def entry_transient(self, k: K) -> Optional[IMapEntry[K, V]]: | ||
| def entry_transient(self, k: K) -> IMapEntry[K, V] | None: | ||
| raise NotImplementedError() | ||
@@ -735,2 +742,5 @@ | ||
| T_inner = TypeVar("T_inner") | ||
| class ISeq(ILispObject, IPersistentCollection[T]): | ||
@@ -749,3 +759,3 @@ """``ISeq`` types represent a potentially infinite sequence of elements. | ||
| class _SeqIter(Iterator[T]): | ||
| class _SeqIter(Iterator[T_inner]): | ||
| """Stateful iterator for sequence types. | ||
@@ -759,3 +769,3 @@ | ||
| def __init__(self, seq: "ISeq[T]"): | ||
| def __init__(self, seq: "ISeq[T_inner]"): | ||
| self._cur = seq | ||
@@ -782,3 +792,3 @@ | ||
| @abstractmethod | ||
| def first(self) -> Optional[T]: | ||
| def first(self) -> T | None: | ||
| raise NotImplementedError() | ||
@@ -785,0 +795,0 @@ |
| import threading | ||
| from collections.abc import Iterable | ||
| from functools import total_ordering | ||
| from typing import Optional, Union | ||
@@ -26,3 +25,3 @@ from typing_extensions import Unpack | ||
| def __init__(self, name: str, ns: Optional[str] = None) -> None: | ||
| def __init__(self, name: str, ns: str | None = None) -> None: | ||
| self._name = name | ||
@@ -37,7 +36,7 @@ self._ns = ns | ||
| @property | ||
| def ns(self) -> Optional[str]: | ||
| def ns(self) -> str | None: | ||
| return self._ns | ||
| @classmethod | ||
| def with_name(cls, name: str, ns: Optional[str] = None) -> "Keyword": | ||
| def with_name(cls, name: str, ns: str | None = None) -> "Keyword": | ||
| return keyword(name, ns=ns) | ||
@@ -72,3 +71,3 @@ | ||
| def __call__(self, m: Union[IAssociative, IPersistentSet], default=None): | ||
| def __call__(self, m: IAssociative | IPersistentSet, default=None): | ||
| if isinstance(m, IPersistentSet): | ||
@@ -87,3 +86,3 @@ return self if self in m else default | ||
| text: str, | ||
| kw_cache: Optional[IPersistentMap[int, Keyword]] = None, | ||
| kw_cache: IPersistentMap[int, Keyword] | None = None, | ||
| ) -> Iterable[str]: | ||
@@ -114,3 +113,3 @@ """Return an iterable of possible completions for the given text.""" | ||
| def hash_kw(name: str, ns: Optional[str] = None) -> int: | ||
| def hash_kw(name: str, ns: str | None = None) -> int: | ||
| """Return the hash of a potential Keyword instance by its name and namespace.""" | ||
@@ -120,3 +119,3 @@ return hash((name, ns)) | ||
| def keyword_from_hash(kw_hash: int, name: str, ns: Optional[str] = None) -> Keyword: | ||
| def keyword_from_hash(kw_hash: int, name: str, ns: str | None = None) -> Keyword: | ||
| """Return the interned keyword with the hash `kw_hash` or create and intern a new | ||
@@ -145,3 +144,3 @@ keyword with name `name` and optional namespace `ns`. | ||
| def find_keyword(name: str, ns: Optional[str] = None) -> Optional[Keyword]: | ||
| def find_keyword(name: str, ns: str | None = None) -> Keyword | None: | ||
| """Return the already-interned keyword named by `name` and `ns`, if one exists. | ||
@@ -153,3 +152,3 @@ If the keyword with that name is not interned, return None.""" | ||
| def keyword(name: str, ns: Optional[str] = None) -> Keyword: | ||
| def keyword(name: str, ns: str | None = None) -> Keyword: | ||
| """Return a keyword with name `name` and optional namespace `ns`. | ||
@@ -156,0 +155,0 @@ |
@@ -1,2 +0,2 @@ | ||
| from typing import Optional, TypeVar, cast | ||
| from typing import TypeVar, cast | ||
@@ -45,6 +45,6 @@ from pyrsistent import PList, plist # noqa # pylint: disable=unused-import | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "PersistentList": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "PersistentList": | ||
| return list(self._inner, meta=meta) | ||
@@ -78,3 +78,3 @@ | ||
| def seq(self) -> Optional[ISeq[T]]: | ||
| def seq(self) -> ISeq[T] | None: | ||
| if len(self._inner) == 0: | ||
@@ -81,0 +81,0 @@ return None |
+31
-25
| from builtins import map as pymap | ||
| from collections.abc import Iterable, Mapping | ||
| from collections.abc import Callable, Iterable, Mapping | ||
| from itertools import islice | ||
| from typing import Any, Callable, Optional, TypeVar, Union, cast | ||
| from typing import Any, TypeVar, cast | ||
@@ -66,4 +66,10 @@ from immutables import Map as _Map | ||
| def assoc_transient(self, *kvs) -> "TransientMap": | ||
| for k, v in partition(kvs, 2): | ||
| self._inner[k] = v | ||
| for t in partition(kvs, 2): | ||
| # Clojure allows assoc! to have odd numbers of arguments, setting nil for | ||
| # the missing value. | ||
| if len(t) == 2: | ||
| k, v = t | ||
| self._inner[k] = v | ||
| else: | ||
| self._inner[t[0]] = None # type: ignore[assignment] | ||
| return self | ||
@@ -82,3 +88,3 @@ | ||
| def entry_transient(self, k: K) -> Optional[IMapEntry[K, V]]: | ||
| def entry_transient(self, k: K) -> IMapEntry[K, V] | None: | ||
| v = self._inner.get(k, cast("V", _ENTRY_SENTINEL)) | ||
@@ -94,8 +100,8 @@ if v is _ENTRY_SENTINEL: | ||
| self, | ||
| *elems: Union[ | ||
| IPersistentMap[K, V], | ||
| IMapEntry[K, V], | ||
| IPersistentVector[Union[K, V]], | ||
| Mapping[K, V], | ||
| ], | ||
| *elems: ( | ||
| IPersistentMap[K, V] | ||
| | IMapEntry[K, V] | ||
| | IPersistentVector[K | V] | ||
| | Mapping[K, V] | ||
| ), | ||
| ) -> "TransientMap[K, V]": | ||
@@ -129,3 +135,3 @@ try: | ||
| end: str, | ||
| meta: Optional[IPersistentMap] = None, | ||
| meta: IPersistentMap | None = None, | ||
| **kwargs: Unpack[PrintSettings], | ||
@@ -227,3 +233,3 @@ ) -> str: | ||
| m: "_Map[K, V]", | ||
| meta: Optional[IPersistentMap] = None, | ||
| meta: IPersistentMap | None = None, | ||
| ) -> None: | ||
@@ -236,4 +242,4 @@ self._inner = m | ||
| cls, | ||
| members: Union[Mapping[K, V], Iterable[tuple[K, V]]], | ||
| meta: Optional[IPersistentMap] = None, | ||
| members: Mapping[K, V] | Iterable[tuple[K, V]], | ||
| meta: IPersistentMap | None = None, | ||
| ) -> "PersistentMap[K, V]": | ||
@@ -282,6 +288,6 @@ return PersistentMap(_Map(members), meta=meta) | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "PersistentMap": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "PersistentMap": | ||
| return PersistentMap(self._inner, meta=meta) | ||
@@ -331,8 +337,8 @@ | ||
| self, | ||
| *elems: Union[ | ||
| IPersistentMap[K, V], | ||
| IMapEntry[K, V], | ||
| IPersistentVector[Union[K, V]], | ||
| Mapping[K, V], | ||
| ], | ||
| *elems: ( | ||
| IPersistentMap[K, V] | ||
| | IMapEntry[K, V] | ||
| | IPersistentVector[K | V] | ||
| | Mapping[K, V] | ||
| ), | ||
| ) -> "PersistentMap[K, V]": | ||
@@ -362,3 +368,3 @@ with self._inner.mutate() as m: | ||
| def seq(self) -> Optional[ISeq[IMapEntry[K, V]]]: | ||
| def seq(self) -> ISeq[IMapEntry[K, V]] | None: | ||
| if len(self._inner) == 0: | ||
@@ -383,3 +389,3 @@ return None | ||
| def map( # pylint:disable=redefined-builtin | ||
| kvs: Mapping[K, V], meta: Optional[IPersistentMap] = None | ||
| kvs: Mapping[K, V], meta: IPersistentMap | None = None | ||
| ) -> PersistentMap[K, V]: | ||
@@ -386,0 +392,0 @@ """Creates a new map.""" |
| import threading | ||
| from typing import Any, Callable, Generic, Optional, TypeVar | ||
| from typing import Any, TypeVar | ||
| from typing_extensions import Generic, ParamSpec, Protocol | ||
| from basilisp.lang import map as lmap | ||
@@ -11,6 +13,16 @@ from basilisp.lang import runtime | ||
| T = TypeVar("T") | ||
| DispatchFunction = Callable[..., T] | ||
| Method = Callable[..., Any] | ||
| P = ParamSpec("P") | ||
| class DispatchFunction(Protocol[T, P]): | ||
| def __call__(self, v: T, *args: P.args, **kwargs: P.kwargs) -> T: ... | ||
| T_contra = TypeVar("T_contra", contravariant=True) | ||
| class Method(Protocol[T_contra, P]): | ||
| def __call__(self, v: T_contra, *args: P.args, **kwargs: P.kwargs) -> Any: ... | ||
| _GLOBAL_HIERARCHY_SYM = sym.symbol("global-hierarchy", ns=runtime.CORE_NS) | ||
@@ -20,3 +32,3 @@ _ISA_SYM = sym.symbol("isa?", ns=runtime.CORE_NS) | ||
| class MultiFunction(Generic[T]): | ||
| class MultiFunction(Generic[T, P]): | ||
| __slots__ = ( | ||
@@ -38,5 +50,5 @@ "_name", | ||
| name: sym.Symbol, | ||
| dispatch: DispatchFunction, | ||
| dispatch: DispatchFunction[T, P], | ||
| default: T, | ||
| hierarchy: Optional[IRef] = None, | ||
| hierarchy: IRef | None = None, | ||
| ) -> None: | ||
@@ -69,7 +81,7 @@ self._name = name | ||
| def __call__(self, *args, **kwargs): | ||
| key = self._dispatch(*args, **kwargs) | ||
| def __call__(self, v: T, *args: P.args, **kwargs: P.kwargs) -> Any: | ||
| key = self._dispatch(v, *args, **kwargs) | ||
| method = self.get_method(key) | ||
| if method is not None: | ||
| return method(*args, **kwargs) | ||
| return method(v, *args, **kwargs) | ||
| raise NotImplementedError | ||
@@ -101,3 +113,3 @@ | ||
| def add_method(self, key: T, method: Method) -> None: | ||
| def add_method(self, key: T, method: Method[T, P]) -> None: | ||
| """Add a new method to this function which will respond for key returned from | ||
@@ -109,7 +121,7 @@ the dispatch function.""" | ||
| def _find_and_cache_method(self, key: T) -> Optional[Method]: | ||
| def _find_and_cache_method(self, key: T) -> Method[T, P] | None: | ||
| """Find and cache the best method for dispatch value `key`.""" | ||
| with self._lock: | ||
| best_key: Optional[T] = None | ||
| best_method: Optional[Method] = None | ||
| best_key: T | None = None | ||
| best_method: Method | None = None | ||
| for method_key, method in self._methods.items(): | ||
@@ -134,3 +146,3 @@ if self._is_a(key, method_key): | ||
| def get_method(self, key: T) -> Optional[Method]: | ||
| def get_method(self, key: T) -> Method[T, P] | None: | ||
| """Return the method which would handle this dispatch key or None if no method | ||
@@ -169,3 +181,3 @@ defined for this key and no default.""" | ||
| def remove_method(self, key: T) -> Optional[Method]: | ||
| def remove_method(self, key: T) -> Method[T, P] | None: | ||
| """Remove the method defined for this key and return it.""" | ||
@@ -190,3 +202,3 @@ with self._lock: | ||
| @property | ||
| def methods(self) -> IPersistentMap[T, Method]: | ||
| def methods(self) -> IPersistentMap[T, Method[T, P]]: | ||
| return self._methods |
@@ -281,7 +281,10 @@ import datetime | ||
| @lrepr.register(float) | ||
| def _lrepr_float(o: float, **_) -> str: | ||
| def _lrepr_float(o: float, human_readable: bool = False, **_) -> str: | ||
| if math.isinf(o): | ||
| return "##Inf" if o > 0 else "##-Inf" | ||
| if o > 0: | ||
| return "Infinity" if human_readable else "##Inf" | ||
| else: | ||
| return "-Infinity" if human_readable else "##-Inf" | ||
| if math.isnan(o): | ||
| return "##NaN" | ||
| return "NaN" if human_readable else "##NaN" | ||
| return repr(o) | ||
@@ -288,0 +291,0 @@ |
| import threading | ||
| from typing import Optional, TypeVar | ||
| from typing import TypeVar | ||
@@ -15,3 +15,3 @@ from basilisp.lang.interfaces import IBlockingDeref, IPending | ||
| self._is_delivered = False | ||
| self._value: Optional[T] = None | ||
| self._value: T | None = None | ||
@@ -25,5 +25,7 @@ def deliver(self, value: T) -> None: | ||
| __call__ = deliver | ||
| def deref( | ||
| self, timeout: Optional[float] = None, timeout_val: Optional[T] = None | ||
| ) -> Optional[T]: | ||
| self, timeout: float | None = None, timeout_val: T | None = None | ||
| ) -> T | None: | ||
| with self._condition: | ||
@@ -30,0 +32,0 @@ if self._condition.wait_for(lambda: self._is_delivered, timeout=timeout): |
@@ -1,2 +0,2 @@ | ||
| from typing import Optional, TypeVar | ||
| from typing import TypeVar | ||
@@ -56,6 +56,6 @@ from pyrsistent import PDeque, pdeque # noqa # pylint: disable=unused-import | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "PersistentQueue": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "PersistentQueue": | ||
| return queue(self._inner, meta=meta) | ||
@@ -80,3 +80,3 @@ | ||
| def seq(self) -> Optional[ISeq[T]]: | ||
| def seq(self) -> ISeq[T] | None: | ||
| if len(self._inner) == 0: | ||
@@ -83,0 +83,0 @@ return None |
| import threading | ||
| from typing import Any, Callable, Optional, TypeVar | ||
| from collections.abc import Callable | ||
| from typing import Any, Concatenate, Optional, TypeVar | ||
| from typing_extensions import Concatenate, ParamSpec | ||
| from typing_extensions import ParamSpec | ||
@@ -31,10 +32,10 @@ from basilisp.lang import keyword as kw | ||
| _lock: threading.RLock | ||
| _meta: Optional[IPersistentMap] | ||
| _meta: IPersistentMap | None | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| with self._lock: | ||
| return self._meta | ||
| def alter_meta(self, f: AlterMeta, *args) -> Optional[IPersistentMap]: | ||
| def alter_meta(self, f: AlterMeta, *args) -> IPersistentMap | None: | ||
| with self._lock: | ||
@@ -44,3 +45,3 @@ self._meta = f(self._meta, *args) | ||
| def reset_meta(self, meta: Optional[IPersistentMap]) -> Optional[IPersistentMap]: | ||
| def reset_meta(self, meta: IPersistentMap | None) -> IPersistentMap | None: | ||
| with self._lock: | ||
@@ -64,3 +65,3 @@ self._meta = meta | ||
| _validator: Optional[RefValidator[T]] | ||
| _validator: RefValidator[T] | None | ||
| _watches: IPersistentMap[RefWatchKey, RefWatcher[T]] | ||
@@ -82,6 +83,6 @@ | ||
| def get_validator(self) -> Optional[RefValidator[T]]: | ||
| def get_validator(self) -> RefValidator[T] | None: | ||
| return self._validator | ||
| def set_validator(self, vf: Optional[RefValidator[T]] = None) -> None: | ||
| def set_validator(self, vf: RefValidator[T] | None = None) -> None: | ||
| with self._lock: | ||
@@ -92,3 +93,3 @@ if vf is not None: | ||
| def _validate(self, val: Any, vf: Optional[RefValidator[T]] = None) -> None: | ||
| def _validate(self, val: Any, vf: RefValidator[T] | None = None) -> None: | ||
| vf = vf or self._validator | ||
@@ -95,0 +96,0 @@ if vf is not None: |
+28
-28
| import functools | ||
| import threading | ||
| from collections.abc import Iterable | ||
| from typing import Callable, Optional, TypeVar, overload | ||
| from collections.abc import Callable, Iterable | ||
| from typing import Optional, TypeVar, overload | ||
@@ -21,3 +21,3 @@ from basilisp.lang.interfaces import ( | ||
| def __init__(self, meta: Optional[IPersistentMap] = None): | ||
| def __init__(self, meta: IPersistentMap | None = None): | ||
| self._meta = meta | ||
@@ -31,10 +31,10 @@ | ||
| def seq(self) -> Optional[ISeq[T]]: | ||
| def seq(self) -> ISeq[T] | None: | ||
| return None | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "_EmptySequence[T]": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "_EmptySequence[T]": | ||
| return _EmptySequence(meta=meta) | ||
@@ -47,3 +47,3 @@ | ||
| @property | ||
| def first(self) -> Optional[T]: | ||
| def first(self) -> T | None: | ||
| return None | ||
@@ -74,4 +74,4 @@ | ||
| first: T, | ||
| seq: Optional[ISeq[T]] = None, | ||
| meta: Optional[IPersistentMap] = None, | ||
| seq: ISeq[T] | None = None, | ||
| meta: IPersistentMap | None = None, | ||
| ) -> None: | ||
@@ -87,3 +87,3 @@ self._first = first | ||
| @property | ||
| def first(self) -> Optional[T]: | ||
| def first(self) -> T | None: | ||
| return self._first | ||
@@ -105,6 +105,6 @@ | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "Cons[T]": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "Cons[T]": | ||
| return Cons(self._first, seq=self._rest, meta=meta) | ||
@@ -128,10 +128,10 @@ | ||
| self, | ||
| gen: Optional[LazySeqGenerator], | ||
| seq: Optional[ISeq[T]] = None, | ||
| gen: LazySeqGenerator | None, | ||
| seq: ISeq[T] | None = None, | ||
| *, | ||
| meta: Optional[IPersistentMap] = None, | ||
| meta: IPersistentMap | None = None, | ||
| ) -> None: | ||
| self._gen: Optional[LazySeqGenerator] = gen | ||
| self._obj: Optional[ISeq[T]] = None | ||
| self._seq: Optional[ISeq[T]] = seq | ||
| self._gen: LazySeqGenerator | None = gen | ||
| self._obj: ISeq[T] | None = None | ||
| self._seq: ISeq[T] | None = seq | ||
| self._lock = threading.RLock() | ||
@@ -141,6 +141,6 @@ self._meta = meta | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "LazySeq[T]": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "LazySeq[T]": | ||
| return LazySeq(None, seq=self.seq(), meta=meta) | ||
@@ -157,3 +157,3 @@ | ||
| def _compute_seq(self) -> Optional[ISeq[T]]: | ||
| def _compute_seq(self) -> ISeq[T] | None: | ||
| if self._gen is not None: | ||
@@ -180,3 +180,3 @@ # This local caching of the generator function and clearing of self._gen | ||
| def seq(self) -> Optional[ISeq[T]]: | ||
| def seq(self) -> ISeq[T] | None: | ||
| with self._lock: | ||
@@ -205,3 +205,3 @@ self._compute_seq() | ||
| @property | ||
| def first(self) -> Optional[T]: | ||
| def first(self) -> T | None: | ||
| if self.is_empty: | ||
@@ -267,3 +267,3 @@ return None | ||
| @overload | ||
| def _seq_or_nil(s: ISeq) -> Optional[ISeq]: ... | ||
| def _seq_or_nil(s: ISeq) -> ISeq | None: ... | ||
@@ -279,3 +279,3 @@ | ||
| @functools.singledispatch | ||
| def to_seq(o) -> Optional[ISeq]: | ||
| def to_seq(o) -> ISeq | None: | ||
| """Coerce the argument o to a ISeq. If o is None, return None.""" | ||
@@ -291,3 +291,3 @@ return _seq_or_nil(sequence(o)) | ||
| @to_seq.register(ISeq) | ||
| def _to_seq_iseq(o: ISeq) -> Optional[ISeq]: | ||
| def _to_seq_iseq(o: ISeq) -> ISeq | None: | ||
| return _seq_or_nil(o) | ||
@@ -297,3 +297,3 @@ | ||
| @to_seq.register(LazySeq) | ||
| def _to_seq_lazyseq(o: LazySeq) -> Optional[ISeq]: | ||
| def _to_seq_lazyseq(o: LazySeq) -> ISeq | None: | ||
| # Force evaluation of the LazySeq by calling o.seq() directly. | ||
@@ -304,3 +304,3 @@ return o.seq() | ||
| @to_seq.register(ISeqable) | ||
| def _to_seq_iseqable(o: ISeqable) -> Optional[ISeq]: | ||
| def _to_seq_iseqable(o: ISeqable) -> ISeq | None: | ||
| return _seq_or_nil(o.seq()) |
| from collections.abc import Iterable | ||
| from collections.abc import Set as _PySet | ||
| from typing import AbstractSet, Optional, TypeVar | ||
| from typing import AbstractSet, TypeVar | ||
@@ -78,3 +78,3 @@ from immutables import Map as _Map | ||
| def __init__(self, m: "_Map[T, T]", meta: Optional[IPersistentMap] = None) -> None: | ||
| def __init__(self, m: "_Map[T, T]", meta: IPersistentMap | None = None) -> None: | ||
| self._inner = m | ||
@@ -85,3 +85,3 @@ self._meta = meta | ||
| def from_iterable( | ||
| cls, members: Optional[Iterable[T]], meta: Optional[IPersistentMap] = None | ||
| cls, members: Iterable[T] | None, meta: IPersistentMap | None = None | ||
| ) -> "PersistentSet": | ||
@@ -150,6 +150,6 @@ return PersistentSet(_Map((m, m) for m in (members or ())), meta=meta) | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "PersistentSet[T]": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "PersistentSet[T]": | ||
| return set(self._inner, meta=meta) | ||
@@ -175,3 +175,3 @@ | ||
| def seq(self) -> Optional[ISeq[T]]: | ||
| def seq(self) -> ISeq[T] | None: | ||
| if len(self._inner) == 0: | ||
@@ -189,3 +189,3 @@ return None | ||
| def set( # pylint:disable=redefined-builtin | ||
| members: Iterable[T], meta: Optional[IPersistentMap] = None | ||
| members: Iterable[T], meta: IPersistentMap | None = None | ||
| ) -> PersistentSet[T]: | ||
@@ -196,4 +196,4 @@ """Creates a new set.""" | ||
| def s(*members: T, meta: Optional[IPersistentMap] = None) -> PersistentSet[T]: | ||
| def s(*members: T, meta: IPersistentMap | None = None) -> PersistentSet[T]: | ||
| """Creates a new set from members.""" | ||
| return PersistentSet.from_iterable(members, meta=meta) |
@@ -5,3 +5,2 @@ import itertools | ||
| from collections.abc import Iterable | ||
| from typing import Optional | ||
@@ -15,3 +14,3 @@ try: | ||
| def _format_source( | ||
| s: str, disable_color: Optional[bool] = None # pylint: disable=unused-argument | ||
| s: str, disable_color: bool | None = None # pylint: disable=unused-argument | ||
| ) -> str: | ||
@@ -23,4 +22,4 @@ return f"{s}{os.linesep}" | ||
| def _get_formatter_name( | ||
| disable_color: Optional[bool] = None, | ||
| ) -> Optional[str]: # pragma: no cover | ||
| disable_color: bool | None = None, | ||
| ) -> str | None: # pragma: no cover | ||
| """Get the Pygments formatter name for formatting the source code by | ||
@@ -43,3 +42,3 @@ inspecting various environment variables set by terminals. | ||
| def _format_source( | ||
| s: str, disable_color: Optional[bool] = None | ||
| s: str, disable_color: bool | None = None | ||
| ) -> str: # pragma: no cover | ||
@@ -63,6 +62,6 @@ """Format source code for terminal output. | ||
| line: int, | ||
| end_line: Optional[int] = None, | ||
| end_line: int | None = None, | ||
| num_context_lines: int = 5, | ||
| show_cause_marker: bool = True, | ||
| disable_color: Optional[bool] = None, | ||
| disable_color: bool | None = None, | ||
| ) -> list[str]: | ||
@@ -79,3 +78,3 @@ """Format source code context with line numbers and identifiers for the affected | ||
| if not filename.startswith("<") and not filename.endswith(">"): | ||
| cause_range: Optional[range] | ||
| cause_range: range | None | ||
| if not show_cause_marker: | ||
@@ -82,0 +81,0 @@ cause_range = None |
| from functools import total_ordering | ||
| from typing import Optional, Union | ||
@@ -23,3 +22,3 @@ from typing_extensions import Unpack | ||
| def __init__( | ||
| self, name: str, ns: Optional[str] = None, meta: Optional[IPersistentMap] = None | ||
| self, name: str, ns: str | None = None, meta: IPersistentMap | None = None | ||
| ) -> None: | ||
@@ -48,14 +47,14 @@ self._name = name | ||
| @property | ||
| def ns(self) -> Optional[str]: | ||
| def ns(self) -> str | None: | ||
| return self._ns | ||
| @classmethod | ||
| def with_name(cls, name: str, ns: Optional[str] = None) -> "Symbol": | ||
| def with_name(cls, name: str, ns: str | None = None) -> "Symbol": | ||
| return Symbol(name, ns=ns) | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "Symbol": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "Symbol": | ||
| return Symbol(self._name, self._ns, meta=meta) | ||
@@ -89,3 +88,3 @@ | ||
| def __call__(self, m: Union[IAssociative, IPersistentSet], default=None): | ||
| def __call__(self, m: IAssociative | IPersistentSet, default=None): | ||
| if isinstance(m, IPersistentSet): | ||
@@ -100,5 +99,5 @@ return self if self in m else default | ||
| def symbol( | ||
| name: str, ns: Optional[str] = None, meta: Optional[IPersistentMap] = None | ||
| name: str, ns: str | None = None, meta: IPersistentMap | None = None | ||
| ) -> Symbol: | ||
| """Create a new symbol.""" | ||
| return Symbol(name, ns=ns, meta=meta) |
@@ -1,2 +0,2 @@ | ||
| from typing import Optional, TypeVar, Union | ||
| from typing import TypeVar, Union | ||
@@ -26,3 +26,3 @@ from typing_extensions import Unpack | ||
| self._form = form | ||
| self._hash: Optional[int] = None | ||
| self._hash: int | None = None | ||
@@ -55,3 +55,3 @@ @property | ||
| def val_at(self, k: K, default: Optional[V] = None) -> T: | ||
| def val_at(self, k: K, default: V | None = None) -> T: | ||
| if k == _TAG_KW: | ||
@@ -58,0 +58,0 @@ return self._tag |
@@ -6,3 +6,3 @@ import uuid | ||
| from re import Pattern | ||
| from typing import Optional, Protocol, Union | ||
| from typing import Any, Protocol, Union | ||
@@ -30,3 +30,3 @@ from basilisp.lang import keyword as kw | ||
| ] | ||
| LispNumber = Union[int, float, Fraction] | ||
| LispNumber = Union[int, float, Decimal, Fraction] | ||
| LispForm = Union[ | ||
@@ -58,9 +58,13 @@ bool, | ||
| class Comparable(Protocol): | ||
| def __lt__(self, other: Any, /) -> bool: ... | ||
| class BasilispFunction(Protocol): | ||
| _basilisp_fn: bool | ||
| arities: IPersistentSet[Union[kw.Keyword, int]] | ||
| meta: Optional[IPersistentMap] | ||
| arities: IPersistentSet[kw.Keyword | int] | ||
| meta: IPersistentMap | None | ||
| def __call__(self, *args, **kwargs): ... | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "BasilispFunction": ... | ||
| def with_meta(self, meta: IPersistentMap | None) -> "BasilispFunction": ... |
| from collections.abc import Iterable, Sequence | ||
| from functools import total_ordering | ||
| from typing import Optional, TypeVar, Union, cast, overload | ||
| from typing import Any, TypeVar, Union, cast, overload | ||
@@ -60,4 +60,10 @@ from pyrsistent import PVector, pvector # noqa # pylint: disable=unused-import | ||
| def assoc_transient(self, *kvs: T) -> "TransientVector[T]": | ||
| for i, v in cast("Sequence[tuple[int, T]]", partition(kvs, 2)): | ||
| self._inner.set(i, v) | ||
| for t in cast("Sequence[tuple[int, T] | tuple[int]]", partition(kvs, 2)): | ||
| # Clojure allows assoc! to have odd numbers of arguments, setting nil for | ||
| # the missing value. | ||
| if len(t) == 2: | ||
| i, v = t | ||
| self._inner.set(i, v) | ||
| else: | ||
| self._inner.set(t[0], None) # type: ignore[arg-type] | ||
| return self | ||
@@ -68,3 +74,3 @@ | ||
| def entry_transient(self, k: int) -> Optional[IMapEntry[int, T]]: | ||
| def entry_transient(self, k: int) -> IMapEntry[int, T] | None: | ||
| try: | ||
@@ -107,3 +113,3 @@ return MapEntry.of(k, self._inner[k]) | ||
| def __init__( | ||
| self, wrapped: "PVector[T]", meta: Optional[IPersistentMap] = None | ||
| self, wrapped: "PVector[T]", meta: IPersistentMap | None = None | ||
| ) -> None: | ||
@@ -140,4 +146,4 @@ self._inner = wrapped | ||
| def __call__(self, k: int, default: Optional[T] = None) -> Optional[T]: | ||
| return self.val_at(k, default=default) | ||
| def __call__(self, k: int) -> T | None: | ||
| return self._inner[k] | ||
@@ -171,6 +177,6 @@ def __lt__(self, other): | ||
| @property | ||
| def meta(self) -> Optional[IPersistentMap]: | ||
| def meta(self) -> IPersistentMap | None: | ||
| return self._meta | ||
| def with_meta(self, meta: Optional[IPersistentMap]) -> "PersistentVector[T]": | ||
| def with_meta(self, meta: IPersistentMap | None) -> "PersistentVector[T]": | ||
| return vector(self._inner, meta=meta) | ||
@@ -187,6 +193,8 @@ | ||
| def contains(self, k: int) -> bool: | ||
| def contains(self, k: Any) -> bool: | ||
| if not isinstance(k, int): | ||
| return False | ||
| return 0 <= k < len(self._inner) | ||
| def entry(self, k: int) -> Optional[IMapEntry[int, T]]: | ||
| def entry(self, k: int) -> IMapEntry[int, T] | None: | ||
| try: | ||
@@ -197,3 +205,3 @@ return MapEntry.of(k, self._inner[k]) | ||
| def val_at(self, k: int, default: Optional[T] = None) -> Optional[T]: | ||
| def val_at(self, k: int, default: T | None = None) -> T | None: | ||
| try: | ||
@@ -207,3 +215,3 @@ return self._inner[k] | ||
| def seq(self) -> Optional[ISeq[T]]: # type: ignore[override] | ||
| def seq(self) -> ISeq[T] | None: # type: ignore[override] | ||
| if len(self._inner) == 0: | ||
@@ -213,3 +221,3 @@ return None | ||
| def peek(self) -> Optional[T]: | ||
| def peek(self) -> T | None: | ||
| if len(self) == 0: | ||
@@ -271,8 +279,3 @@ return None | ||
| def __init__(self, wrapped: "PVector[Union[K, V]]") -> None: | ||
| try: | ||
| if not len(wrapped) == 2: | ||
| raise ValueError("Vector arg to map conj must be a pair") | ||
| except TypeError as e: | ||
| raise TypeError(f"Cannot make map entry from {type(wrapped)}") from e | ||
| assert len(wrapped) == 2, "Vector arg to map conj must be a pair" | ||
| super().__init__(wrapped) | ||
@@ -293,3 +296,8 @@ | ||
| @staticmethod | ||
| def from_vec(v: Sequence[Union[K, V]]) -> "MapEntry[K, V]": | ||
| def from_vec(v: Sequence[K | V]) -> "MapEntry[K, V]": | ||
| try: | ||
| if len(v) != 2: | ||
| raise ValueError("Vector arg to map conj must be a pair") | ||
| except TypeError as e: | ||
| raise TypeError(f"Cannot make map entry from {type(v)}") from e | ||
| return MapEntry(pvector(v)) | ||
@@ -302,3 +310,3 @@ | ||
| def vector( | ||
| members: Iterable[T], meta: Optional[IPersistentMap] = None | ||
| members: Iterable[T], meta: IPersistentMap | None = None | ||
| ) -> PersistentVector[T]: | ||
@@ -309,4 +317,4 @@ """Creates a new vector.""" | ||
| def v(*members: T, meta: Optional[IPersistentMap] = None) -> PersistentVector[T]: | ||
| def v(*members: T, meta: IPersistentMap | None = None) -> PersistentVector[T]: | ||
| """Creates a new vector from members.""" | ||
| return PersistentVector(pvector(members), meta=meta) |
@@ -1,5 +0,6 @@ | ||
| from typing import Callable, Optional, TypeVar | ||
| from collections.abc import Callable | ||
| from typing import Concatenate, TypeVar | ||
| import attr | ||
| from typing_extensions import Concatenate, ParamSpec | ||
| from typing_extensions import ParamSpec | ||
@@ -20,3 +21,3 @@ from basilisp.lang.interfaces import IDeref | ||
| def deref(self) -> Optional[T]: | ||
| def deref(self) -> T | None: | ||
| return self.value | ||
@@ -23,0 +24,0 @@ |
| import logging | ||
| import os | ||
| from typing import Optional | ||
@@ -20,5 +19,3 @@ TRACE = 5 | ||
| def get_handler( | ||
| level: Optional[str] = None, fmt: str = DEFAULT_FORMAT | ||
| ) -> logging.Handler: | ||
| def get_handler(level: str | None = None, fmt: str = DEFAULT_FORMAT) -> logging.Handler: | ||
| """Get the default logging handler for Basilisp.""" | ||
@@ -35,5 +32,3 @@ handler = ( | ||
| def configure_root_logger( | ||
| level: Optional[str] = None, fmt: str = DEFAULT_FORMAT | ||
| ) -> None: | ||
| def configure_root_logger(level: str | None = None, fmt: str = DEFAULT_FORMAT) -> None: | ||
| """Configure the Basilisp root logger.""" | ||
@@ -40,0 +35,0 @@ level = level or get_level() |
@@ -6,3 +6,2 @@ import importlib | ||
| from pathlib import Path | ||
| from typing import Optional | ||
@@ -20,3 +19,3 @@ from basilisp import importer as importer | ||
| def init(opts: Optional[CompilerOpts] = None, force_reload: bool = False) -> None: | ||
| def init(opts: CompilerOpts | None = None, force_reload: bool = False) -> None: | ||
| """ | ||
@@ -50,3 +49,3 @@ Initialize the runtime environment for Basilisp code evaluation. | ||
| def bootstrap( | ||
| target: str, opts: Optional[CompilerOpts] = None | ||
| target: str, opts: CompilerOpts | None = None | ||
| ) -> None: # pragma: no cover | ||
@@ -77,3 +76,3 @@ """ | ||
| def bootstrap_python(site_packages: Optional[str] = None) -> str: | ||
| def bootstrap_python(site_packages: str | None = None) -> str: | ||
| """Bootstrap a Python installation by installing a ``.pth`` file | ||
@@ -98,3 +97,3 @@ in ``site-packages`` directory (corresponding to "purelib" in | ||
| def unbootstrap_python(site_packages: Optional[str] = None) -> Optional[str]: | ||
| def unbootstrap_python(site_packages: str | None = None) -> str | None: | ||
| """Remove the `basilispbootstrap.pth` file found in the Python site-packages | ||
@@ -101,0 +100,0 @@ directory (corresponding to "purelib" in :external:py:func:`sysconfig.get_paths`). |
| import contextlib | ||
| import time | ||
| from collections.abc import Iterable, Sequence | ||
| from typing import Callable, Generic, Optional, TypeVar | ||
| from collections.abc import Callable, Iterable, Sequence | ||
| from typing import Generic, TypeVar | ||
| @contextlib.contextmanager | ||
| def timed(f: Optional[Callable[[int], None]] = None): | ||
| def timed(f: Callable[[int], None] | None = None): | ||
| """Time the execution of code in the with-block, calling the function | ||
@@ -26,3 +26,3 @@ f (if it is given) with the resulting time in nanoseconds.""" | ||
| def __init__(self, inner: Optional[T]) -> None: | ||
| def __init__(self, inner: T | None) -> None: | ||
| self._inner = inner | ||
@@ -62,3 +62,3 @@ | ||
| @property | ||
| def value(self) -> Optional[T]: | ||
| def value(self) -> T | None: | ||
| return self._inner | ||
@@ -65,0 +65,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
1238150
1.14%74
1.37%18556
1.62%