From 55aed5200f24069b5561ca7742573cc9aff8855b Mon Sep 17 00:00:00 2001 From: Chris Rink Date: Tue, 28 Oct 2025 23:02:19 -0400 Subject: [PATCH 1/3] Switch to using modern Python union syntax --- src/basilisp/cli.py | 11 +- src/basilisp/contrib/pytest/testrunner.py | 13 +- src/basilisp/contrib/sphinx/autodoc.py | 12 +- src/basilisp/contrib/sphinx/domain.py | 6 +- src/basilisp/importer.py | 8 +- src/basilisp/lang/atom.py | 12 +- src/basilisp/lang/compiler/__init__.py | 35 +++--- src/basilisp/lang/compiler/analyzer.py | 119 ++++++++++--------- src/basilisp/lang/compiler/exception.py | 22 ++-- src/basilisp/lang/compiler/generator.py | 138 +++++++++++----------- src/basilisp/lang/compiler/nodes.py | 69 +++++------ src/basilisp/lang/compiler/optimizer.py | 14 +-- src/basilisp/lang/delay.py | 7 +- src/basilisp/lang/exception.py | 14 +-- src/basilisp/lang/futures.py | 13 +- src/basilisp/lang/interfaces.py | 26 ++-- src/basilisp/lang/keyword.py | 18 +-- src/basilisp/lang/list.py | 6 +- src/basilisp/lang/map.py | 45 +++---- src/basilisp/lang/multifn.py | 15 +-- src/basilisp/lang/promise.py | 6 +- src/basilisp/lang/queue.py | 6 +- src/basilisp/lang/reader.py | 101 ++++++++-------- src/basilisp/lang/reference.py | 22 ++-- src/basilisp/lang/runtime.py | 93 +++++++-------- src/basilisp/lang/seq.py | 55 ++++----- src/basilisp/lang/set.py | 14 +-- src/basilisp/lang/source.py | 14 +-- src/basilisp/lang/symbol.py | 14 +-- src/basilisp/lang/tagged.py | 4 +- src/basilisp/lang/typing.py | 6 +- src/basilisp/lang/vector.py | 24 ++-- src/basilisp/lang/volatile.py | 8 +- src/basilisp/logconfig.py | 4 +- src/basilisp/main.py | 8 +- src/basilisp/util.py | 9 +- tests/basilisp/cli_test.py | 2 +- tests/basilisp/compiler_test.py | 8 +- tests/basilisp/conftest.py | 4 +- tests/basilisp/helpers.py | 3 +- tests/basilisp/importer_test.py | 2 +- tests/basilisp/prompt_test.py | 2 +- tests/basilisp/reader_test.py | 2 +- 43 files changed, 518 insertions(+), 496 deletions(-) diff --git a/src/basilisp/cli.py b/src/basilisp/cli.py index 833f0b90d..2a7ddfea4 100644 --- a/src/basilisp/cli.py +++ b/src/basilisp/cli.py @@ -8,7 +8,8 @@ import types from collections.abc import Sequence from pathlib import Path -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union +from collections.abc import Callable from basilisp import main as basilisp from basilisp.lang import compiler as compiler @@ -97,7 +98,7 @@ def prepend_once(path: str) -> None: prepend_once(unsafe_path) -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.""" if v is None: return v @@ -389,8 +390,8 @@ def _add_runtime_arg_group(parser: argparse.ArgumentParser) -> None: def _subcommand( subcommand: str, *, - 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, allows_extra: bool = False, ) -> Callable[ @@ -820,7 +821,7 @@ def run_script(): os.execvp("basilisp", args) # nosec B606, B607 -def invoke_cli(args: Optional[Sequence[str]] = None) -> None: +def invoke_cli(args: Sequence[str] | None = None) -> None: """Entrypoint to run the Basilisp CLI.""" parser = argparse.ArgumentParser( description="Basilisp is a Lisp dialect inspired by Clojure targeting Python 3." diff --git a/src/basilisp/contrib/pytest/testrunner.py b/src/basilisp/contrib/pytest/testrunner.py index e573f9a34..bb7a24dd3 100644 --- a/src/basilisp/contrib/pytest/testrunner.py +++ b/src/basilisp/contrib/pytest/testrunner.py @@ -6,7 +6,8 @@ from collections.abc import Iterable, Iterator from pathlib import Path from types import GeneratorType -from typing import Callable, Optional +from typing import Optional +from collections.abc import Callable import pytest @@ -108,7 +109,7 @@ def __init__(self, fixtures: Iterable[FixtureFunction]): self._teardowns: Iterable[FixtureTeardown] = () @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 generator/coroutine. Otherwise, simply return the value from the function, if one.""" @@ -199,7 +200,7 @@ class BasilispFile(pytest.File): def __init__(self, **kwargs) -> None: super().__init__(**kwargs) - self._fixture_manager: Optional[FixtureManager] = None + self._fixture_manager: FixtureManager | None = None @staticmethod def _collected_fixtures( @@ -248,7 +249,7 @@ def _import_module(self) -> runtime.BasilispModule: modnames = _get_fully_qualified_module_names(self.path) assert modnames, "Must have at least one module name" - exc: Optional[ModuleNotFoundError] = None + exc: ModuleNotFoundError | None = None for modname in modnames: try: module = importlib.import_module(modname) @@ -360,7 +361,7 @@ def runtest(self): If any tests fail, raise an ExceptionInfo exception with the test failures. PyTest will invoke self.repr_failure to display the failures to the user.""" 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): raise TestFailuresInfo("Test failures", lmap.map(results)) @@ -391,7 +392,7 @@ def repr_failure(self, excinfo, style=None): def reportinfo(self): return self.fspath, 0, self.name - 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("") messages = [f"ERROR in ({self.name}) ({self._filename}{line_msg})", "\n\n"] messages.extend(traceback.format_exception(Exception, exc, exc.__traceback__)) diff --git a/src/basilisp/contrib/sphinx/autodoc.py b/src/basilisp/contrib/sphinx/autodoc.py index cfb4c05da..a897e4caf 100644 --- a/src/basilisp/contrib/sphinx/autodoc.py +++ b/src/basilisp/contrib/sphinx/autodoc.py @@ -51,7 +51,7 @@ _METHODS_KW = kw.keyword("methods") -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).""" docstring = reference.meta and reference.meta.val_at(_DOC_KW) if docstring is None: @@ -79,7 +79,7 @@ class NamespaceDocumenter(Documenter): "deprecated": bool_option, } - object: Optional[runtime.Namespace] + object: runtime.Namespace | None @classmethod def can_document_member( @@ -122,7 +122,7 @@ def import_object(self, raiseerror: bool = False) -> bool: self.module = ns.module return True - def get_doc(self) -> Optional[list[list[str]]]: + def get_doc(self) -> list[list[str]] | None: assert self.object is not None return _get_doc(self.object) @@ -155,7 +155,7 @@ def filter_members( continue if val.meta is not None: # 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: continue # Private members will be excluded unless they are requested @@ -215,7 +215,7 @@ class VarDocumenter(Documenter): "deprecated": bool_option, } - object: Optional[runtime.Var] + object: runtime.Var | None @classmethod def can_document_member( @@ -292,7 +292,7 @@ def add_directive_header(self, sig: str) -> None: if self.object.meta.val_at(_DEPRECATED_KW): self.add_line(" :deprecated:", sourcename) - def get_doc(self) -> Optional[list[list[str]]]: + def get_doc(self) -> list[list[str]] | None: assert self.object is not None return _get_doc(self.object) diff --git a/src/basilisp/contrib/sphinx/domain.py b/src/basilisp/contrib/sphinx/domain.py index 9434ece34..c19dc791c 100644 --- a/src/basilisp/contrib/sphinx/domain.py +++ b/src/basilisp/contrib/sphinx/domain.py @@ -316,7 +316,7 @@ class BasilispNamespaceIndex(Index): shortname = "namespaces" 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]: content: dict[str, list[IndexEntry]] = defaultdict(list) @@ -548,10 +548,10 @@ def resolve_xref( # pylint: disable=too-many-arguments target: str, node: pending_xref, 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") if reftype == "ns": maybe_obj = self.namespaces.get(target) diff --git a/src/basilisp/importer.py b/src/basilisp/importer.py index e9df605f4..0be82d9a0 100644 --- a/src/basilisp/importer.py +++ b/src/basilisp/importer.py @@ -144,9 +144,9 @@ def __init__(self): def find_spec( self, 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. Returns None if the module is not a Basilisp module to allow import processing to continue. @@ -234,7 +234,7 @@ def get_filename(self, fullname: str) -> str: assert spec is not None, "spec must be defined here" return spec.loader_state["filename"] - 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. This function is part of the ABC for `importlib.abc.ExecutionLoader` which is diff --git a/src/basilisp/lang/atom.py b/src/basilisp/lang/atom.py index dbf85306e..41405015b 100644 --- a/src/basilisp/lang/atom.py +++ b/src/basilisp/lang/atom.py @@ -1,7 +1,9 @@ import threading -from typing import Callable, Generic, Optional, TypeVar +from typing import Generic, Optional, TypeVar +from collections.abc import Callable -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import ParamSpec +from typing import Concatenate from basilisp.lang import map as lmap from basilisp.lang.interfaces import IPersistentMap, RefValidator @@ -17,10 +19,10 @@ class Atom(RefBase[T], Generic[T]): def __init__( self, 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 self._lock = threading.RLock() self._watches = lmap.EMPTY diff --git a/src/basilisp/lang/compiler/__init__.py b/src/basilisp/lang/compiler/__init__.py index 1ca6615a7..74f93d9fe 100644 --- a/src/basilisp/lang/compiler/__init__.py +++ b/src/basilisp/lang/compiler/__init__.py @@ -5,7 +5,8 @@ from ast import unparse from collections.abc import Iterable from pathlib import Path -from typing import Any, Callable, Optional +from typing import Any, Optional +from collections.abc import Callable from basilisp.lang import list as llist from basilisp.lang import map as lmap @@ -60,7 +61,7 @@ def to_py_str(t: ast.AST) -> str: class CompilerContext: __slots__ = ("_filename", "_actx", "_gctx", "_optimizer") - def __init__(self, filename: str, opts: Optional[CompilerOpts] = None): + def __init__(self, filename: str, opts: CompilerOpts | None = None): self._filename = filename self._actx = AnalyzerContext(filename=filename, opts=opts) self._gctx = GeneratorContext(filename=filename, opts=opts) @@ -84,15 +85,15 @@ def py_ast_optimizer(self) -> PythonASTOptimizer: 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: """Return a map of compiler options with defaults applied.""" return lmap.map( @@ -148,7 +149,7 @@ def compile_and_exec_form( ctx: CompilerContext, ns: runtime.Namespace, wrapped_fn_name: str = _DEFAULT_FN, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> Any: """Compile and execute the given form. This function will be most useful for the REPL and testing purposes. Returns the result of the executed expression. @@ -204,7 +205,7 @@ def _incremental_compile_module( py_ast: GeneratedPyAST, module: BasilispModule, source_filename: str, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> None: """Incrementally compile a stream of AST nodes in module mod. @@ -232,7 +233,7 @@ def _bootstrap_module( gctx: GeneratorContext, optimizer: PythonASTOptimizer, module: BasilispModule, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> None: """Bootstrap a new module with imports and other boilerplate.""" _incremental_compile_module( @@ -249,7 +250,7 @@ def compile_module( forms: Iterable[ReaderForm], ctx: CompilerContext, module: BasilispModule, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> None: """Compile an entire Basilisp module into Python bytecode which can be executed as a Python module. @@ -298,7 +299,7 @@ def load( path: str, ctx: CompilerContext, ns: runtime.Namespace, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> Any: """Call :lpy:fn:`basilisp.core/load` with the given ``path``, returning the result.""" @@ -311,7 +312,7 @@ def load_file( path: Path, ctx: CompilerContext, ns: runtime.Namespace, - collect_bytecode: Optional[BytecodeCollector] = None, + collect_bytecode: BytecodeCollector | None = None, ) -> Any: """Call :lpy:fn:`basilisp.core/load-file` with the given ``path``, returning the result.""" diff --git a/src/basilisp/lang/compiler/analyzer.py b/src/basilisp/lang/compiler/analyzer.py index a73af115d..30fcd6864 100644 --- a/src/basilisp/lang/compiler/analyzer.py +++ b/src/basilisp/lang/compiler/analyzer.py @@ -23,10 +23,11 @@ from fractions import Fraction from functools import partial, wraps from re import Pattern -from typing import Any, Callable, Optional, TypeVar, Union, cast +from typing import Any, Optional, TypeVar, Union, cast +from collections.abc import Callable import attr -from typing_extensions import Literal +from typing import Literal from basilisp.lang import keyword as kw from basilisp.lang import list as llist @@ -233,7 +234,7 @@ def new_symbol( self._table[s] = SymbolTableEntry(binding, warn_if_unused=warn_if_unused) return self - def find_symbol(self, s: sym.Symbol) -> Optional[SymbolTableEntry]: + def find_symbol(self, s: sym.Symbol) -> SymbolTableEntry | None: if s in self._table: return self._table[s] if self._parent is None: @@ -345,8 +346,8 @@ class AnalyzerContext: def __init__( self, - filename: Optional[str] = None, - opts: Optional[CompilerOpts] = None, + filename: str | None = None, + opts: CompilerOpts | None = None, should_macroexpand: bool = True, allow_unresolved_symbols: bool = False, ) -> None: @@ -441,7 +442,7 @@ def should_macroexpand(self) -> bool: return self._should_macroexpand @property - def func_ctx(self) -> Optional[FunctionContext]: + def func_ctx(self) -> FunctionContext | None: """Return the current function or method context of the current node, if one. Return None otherwise. @@ -479,7 +480,7 @@ def new_func_ctx( self._func_ctx.pop() @property - def recur_point(self) -> Optional[RecurPoint]: + def recur_point(self) -> RecurPoint | None: """Return the current recur point which applies to the current node, if there is one.""" try: @@ -509,7 +510,7 @@ def put_new_symbol( # pylint: disable=too-many-arguments warn_on_shadowed_name: bool = True, warn_on_shadowed_var: bool = True, warn_if_unused: bool = True, - symbol_table: Optional[SymbolTable] = None, + symbol_table: SymbolTable | None = None, ): """Add a new symbol to the symbol table. @@ -624,7 +625,7 @@ def syntax_position(self) -> NodeSyntacticPosition: parent node.""" return self._syntax_pos[-1] - def get_node_env(self, pos: Optional[NodeSyntacticPosition] = None) -> NodeEnv: + def get_node_env(self, pos: NodeSyntacticPosition | None = None) -> NodeEnv: """Return the current Node environment. If a syntax position is given, it will be included in the environment. @@ -636,8 +637,8 @@ def get_node_env(self, pos: Optional[NodeSyntacticPosition] = None) -> NodeEnv: def AnalyzerException( self, msg: str, - form: Union[LispForm, None, ISeq] = None, - lisp_ast: Optional[Node] = None, + form: LispForm | None | ISeq = None, + lisp_ast: Node | None = None, ) -> CompilerException: """Return a CompilerException annotated with the current filename and :analyzer compiler phase set. The remaining keyword arguments are passed @@ -664,7 +665,7 @@ def _bool_meta_getter(meta_kw: kw.Keyword, default: bool = False) -> BoolMetaGet """Return a function which checks an object with metadata for a boolean value by meta_kw.""" - def has_meta_prop(o: Union[IMeta, Var]) -> bool: + def has_meta_prop(o: IMeta | Var) -> bool: return bool( Maybe(o.meta).map(lambda m: m.val_at(meta_kw, None)).or_else_get(default) ) @@ -676,7 +677,7 @@ def _meta_getter(meta_kw: kw.Keyword) -> MetaGetter: """Return a function which checks an object with metadata for a value by meta_kw.""" - def get_meta_prop(o: Union[IMeta, Var]) -> Any: + def get_meta_prop(o: IMeta | Var) -> Any: return Maybe(o.meta).map(lambda m: m.val_at(meta_kw, None)).value return get_meta_prop @@ -703,7 +704,7 @@ def get_meta_prop(o: Union[IMeta, Var]) -> Any: LispAnalyzer = Callable[[T_form, AnalyzerContext], T_node] -def _loc(form: T_form) -> Optional[tuple[int, int, int, int]]: +def _loc(form: T_form) -> tuple[int, int, int, int] | None: """Fetch the location of the form in the original filename from the input form, if it has metadata.""" # Technically, IMeta is sufficient for fetching `form.meta` but the @@ -740,7 +741,7 @@ def _analyze_form(form: T_form, ctx: AnalyzerContext) -> T_node: return _analyze_form -def _clean_meta(meta: Optional[lmap.PersistentMap]) -> Optional[lmap.PersistentMap]: +def _clean_meta(meta: lmap.PersistentMap | None) -> lmap.PersistentMap | None: """Remove reader metadata from the form's meta map.""" if meta is None: return None @@ -755,7 +756,7 @@ def _clean_meta(meta: Optional[lmap.PersistentMap]) -> Optional[lmap.PersistentM def _body_ast( - form: Union[llist.PersistentList, ISeq], ctx: AnalyzerContext + form: llist.PersistentList | ISeq, ctx: AnalyzerContext ) -> tuple[Iterable[Node], Node]: """Analyze the form and produce a body of statement nodes and a single return expression node. @@ -845,7 +846,7 @@ def _call_args_ast( return args, kwargs -def _tag_ast(form: Optional[LispForm], ctx: AnalyzerContext) -> Optional[Node]: +def _tag_ast(form: LispForm | None, ctx: AnalyzerContext) -> Node | None: if form is None: return None return _analyze_form(form, ctx) @@ -893,7 +894,7 @@ def with_meta(form: T_form, ctx: AnalyzerContext) -> T_node: @functools.singledispatch -def _analyze_form(form: Union[ReaderForm, ISeq], ctx: AnalyzerContext): +def _analyze_form(form: ReaderForm | ISeq, ctx: AnalyzerContext): raise ctx.AnalyzerException(f"Unexpected form type {type(form)}", form=form) # type: ignore[arg-type] @@ -929,7 +930,7 @@ def _await_ast(form: ISeq, ctx: AnalyzerContext) -> Await: def __should_warn_on_redef( current_ns: runtime.Namespace, defsym: sym.Symbol, - def_meta: Optional[lmap.PersistentMap], + def_meta: lmap.PersistentMap | None, ) -> bool: """Return True if the compiler should emit a warning about this name being redefined.""" if def_meta is not None and def_meta.val_at(SYM_NO_WARN_ON_REDEF_META_KEY, False): @@ -967,7 +968,7 @@ def _def_ast( # pylint: disable=too-many-locals,too-many-statements tag_ast = _tag_ast(_tag_meta(name), ctx) - init_idx: Optional[int] + init_idx: int | None children: vec.PersistentVector[kw.Keyword] if nelems == 2: init_idx = None @@ -1205,11 +1206,11 @@ def __deftype_method_param_bindings( def __deftype_classmethod( # pylint: disable=too-many-locals - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, method_name: str, args: vec.PersistentVector, - kwarg_support: Optional[KeywordArgSupport] = None, + kwarg_support: KeywordArgSupport | None = None, ) -> DefTypeClassMethod: """Emit a node for a :classmethod member of a `deftype*` form.""" with ( @@ -1265,12 +1266,12 @@ def __deftype_classmethod( # pylint: disable=too-many-locals def __deftype_or_reify_method( # pylint: disable=too-many-arguments,too-many-locals - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, method_name: str, args: vec.PersistentVector, special_form: sym.Symbol, - kwarg_support: Optional[KeywordArgSupport] = None, + kwarg_support: KeywordArgSupport | None = None, ) -> DefTypeMethodArity: """Emit a node for a method member of a `deftype*` or `reify*` form.""" assert special_form in {SpecialForm.DEFTYPE, SpecialForm.REIFY} @@ -1329,7 +1330,7 @@ def __deftype_or_reify_method( # pylint: disable=too-many-arguments,too-many-lo def __deftype_or_reify_property( - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, method_name: str, args: vec.PersistentVector, @@ -1394,11 +1395,11 @@ def __deftype_or_reify_property( def __deftype_staticmethod( - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, method_name: str, args: vec.PersistentVector, - kwarg_support: Optional[KeywordArgSupport] = None, + kwarg_support: KeywordArgSupport | None = None, ) -> DefTypeStaticMethod: """Emit a node for a :staticmethod member of a `deftype*` form.""" with ( @@ -1432,10 +1433,10 @@ def __deftype_staticmethod( def __deftype_or_reify_prop_or_method_arity( - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, special_form: sym.Symbol, -) -> Union[DefTypeMethodArity, DefTypePythonMember]: +) -> DefTypeMethodArity | DefTypePythonMember: """Emit either a `deftype*` or `reify*` property node or an arity of a `deftype*` or `reify*` method. @@ -1514,7 +1515,7 @@ def __deftype_or_reify_prop_or_method_arity( def __deftype_or_reify_method_node_from_arities( - form: Union[llist.PersistentList, ISeq], + form: llist.PersistentList | ISeq, ctx: AnalyzerContext, arities: list[DefTypeMethodArity], special_form: sym.Symbol, @@ -1524,7 +1525,7 @@ def __deftype_or_reify_method_node_from_arities( assert special_form in {SpecialForm.DEFTYPE, SpecialForm.REIFY} fixed_arities: MutableSet[int] = set() - fixed_arity_for_variadic: Optional[int] = None + fixed_arity_for_variadic: int | None = None num_variadic = 0 for arity in arities: if arity.is_variadic: @@ -2043,7 +2044,7 @@ def _do_ast(form: ISeq, ctx: AnalyzerContext) -> Do: def __fn_method_ast( # pylint: disable=too-many-locals form: ISeq, ctx: AnalyzerContext, - fnname: Optional[sym.Symbol] = None, + fnname: sym.Symbol | None = None, is_async: bool = False, ) -> FnArity: with ctx.new_symbol_table("fn-method", is_context_boundary=True): @@ -2135,7 +2136,7 @@ def __fn_method_ast( # pylint: disable=too-many-locals return method -def __fn_kwargs_support(ctx: AnalyzerContext, o: IMeta) -> Optional[KeywordArgSupport]: +def __fn_kwargs_support(ctx: AnalyzerContext, o: IMeta) -> KeywordArgSupport | None: if o.meta is None: return None @@ -2169,11 +2170,11 @@ def __unquote_args_sym(f: sym.Symbol, args: frozenset[sym.Symbol]): def _inline_fn_ast( ctx: AnalyzerContext, - form: Union[llist.PersistentList, ISeq], - name: Optional[Binding], + form: llist.PersistentList | ISeq, + name: Binding | None, arities: vec.PersistentVector[FnArity], num_variadic: int, -) -> Optional[Fn]: +) -> Fn | None: if not ctx.should_generate_auto_inlines: return None @@ -2221,7 +2222,7 @@ def _inline_fn_ast( @_with_meta def _fn_ast( # pylint: disable=too-many-locals,too-many-statements - form: Union[llist.PersistentList, ISeq], ctx: AnalyzerContext + form: llist.PersistentList | ISeq, ctx: AnalyzerContext ) -> Fn: assert form.first == SpecialForm.FN @@ -2236,7 +2237,7 @@ def _fn_ast( # pylint: disable=too-many-locals,too-many-statements form=form, ) from e - name_node: Optional[Binding] + name_node: Binding | None inline: InlineMeta if isinstance(name, sym.Symbol): name_node = Binding( @@ -2304,7 +2305,7 @@ def _fn_ast( # pylint: disable=too-many-locals,too-many-statements ) fixed_arities: MutableSet[int] = set() - fixed_arity_for_variadic: Optional[int] = None + fixed_arity_for_variadic: int | None = None num_variadic = 0 for arity in arities: if arity.is_variadic: @@ -2431,7 +2432,7 @@ def _host_prop_ast(form: ISeq, ctx: AnalyzerContext) -> HostField: ) -def _host_interop_ast(form: ISeq, ctx: AnalyzerContext) -> Union[HostCall, HostField]: +def _host_interop_ast(form: ISeq, ctx: AnalyzerContext) -> HostCall | HostField: assert form.first == SpecialForm.INTEROP_CALL nelems = count(form) assert nelems >= 3 @@ -2699,8 +2700,8 @@ def _import_ast(form: ISeq, ctx: AnalyzerContext) -> Import: def __handle_macroexpanded_ast( - original: Union[llist.PersistentList, ISeq], - expanded: Union[ReaderForm, ISeq], + original: llist.PersistentList | ISeq, + expanded: ReaderForm | ISeq, ctx: AnalyzerContext, ) -> Node: """Prepare the Lisp AST from macroexpanded and inlined code.""" @@ -2723,10 +2724,10 @@ def __handle_macroexpanded_ast( def _do_warn_on_arity_mismatch( - fn: VarRef, form: Union[llist.PersistentList, ISeq], ctx: AnalyzerContext + fn: VarRef, form: llist.PersistentList | ISeq, ctx: AnalyzerContext ) -> None: if ctx.warn_on_arity_mismatch and getattr(fn.var.value, "_basilisp_fn", False): - arities: Optional[tuple[Union[int, kw.Keyword]]] = getattr( + arities: tuple[int | kw.Keyword] | None = getattr( fn.var.value, "arities", None ) if arities is not None: @@ -2756,7 +2757,7 @@ def _do_warn_on_arity_mismatch( ) -def _invoke_ast(form: Union[llist.PersistentList, ISeq], ctx: AnalyzerContext) -> Node: +def _invoke_ast(form: llist.PersistentList | ISeq, ctx: AnalyzerContext) -> Node: with ctx.expr_pos(): fn = _analyze_form(form.first, ctx) @@ -3368,7 +3369,7 @@ def _try_ast(form: ISeq, ctx: AnalyzerContext) -> Try: try_exprs = [] catches = [] - finally_: Optional[Do] = None + finally_: Do | None = None for expr in form.rest: if isinstance(expr, (llist.PersistentList, ISeq)): if expr.first == SpecialForm.CATCH: @@ -3575,7 +3576,7 @@ def __resolve_namespaced_symbol_in_ns( ctx: AnalyzerContext, which_ns: runtime.Namespace, form: sym.Symbol, -) -> Optional[Union[MaybeHostForm, VarRef]]: +) -> MaybeHostForm | VarRef | None: """Resolve the symbol `form` in the context of the Namespace `which_ns`. If `allow_fuzzy_macroexpansion_matching` is True and no match is made on existing imports, import aliases, or namespace aliases, then attempt to match the @@ -3656,7 +3657,7 @@ def __resolve_namespaced_symbol_in_ns( def __resolve_namespaced_symbol( # pylint: disable=too-many-branches ctx: AnalyzerContext, form: sym.Symbol -) -> Union[Const, HostField, MaybeClass, MaybeHostForm, VarRef]: +) -> Const | HostField | MaybeClass | MaybeHostForm | VarRef: """Resolve a namespaced symbol into a Python name or Basilisp Var.""" # Support Clojure 1.12 qualified method names # @@ -3789,7 +3790,7 @@ def __resolve_namespaced_symbol( # pylint: disable=too-many-branches def __resolve_bare_symbol( ctx: AnalyzerContext, form: sym.Symbol -) -> Union[Const, HostField, MaybeClass, VarRef]: +) -> Const | HostField | MaybeClass | VarRef: """Resolve a non-namespaced symbol into a Python name or a local Basilisp Var.""" assert form.ns is None @@ -3858,7 +3859,7 @@ def __resolve_bare_symbol( def _resolve_sym( ctx: AnalyzerContext, form: sym.Symbol -) -> Union[Const, HostField, MaybeClass, MaybeHostForm, VarRef]: +) -> Const | HostField | MaybeClass | MaybeHostForm | VarRef: """Resolve a Basilisp symbol as a Var or Python name.""" # Support special class-name syntax to instantiate new classes # (Classname. *args) @@ -3885,7 +3886,7 @@ def _resolve_sym( @_with_loc def _symbol_node( form: sym.Symbol, ctx: AnalyzerContext -) -> Union[Const, HostField, Local, MaybeClass, MaybeHostForm, VarRef]: +) -> Const | HostField | Local | MaybeClass | MaybeHostForm | VarRef: if ctx.is_quoted: return _const_node(form, ctx) @@ -3905,7 +3906,7 @@ def _symbol_node( @_analyze_form.register(dict) @_with_loc -def _py_dict_node(form: dict, ctx: AnalyzerContext) -> Union[Const, PyDict]: +def _py_dict_node(form: dict, ctx: AnalyzerContext) -> Const | PyDict: if ctx.is_quoted: return _const_node(form, ctx) @@ -3924,7 +3925,7 @@ def _py_dict_node(form: dict, ctx: AnalyzerContext) -> Union[Const, PyDict]: @_analyze_form.register(list) @_with_loc -def _py_list_node(form: list, ctx: AnalyzerContext) -> Union[Const, PyList]: +def _py_list_node(form: list, ctx: AnalyzerContext) -> Const | PyList: if ctx.is_quoted: return _const_node(form, ctx) return PyList( @@ -3936,7 +3937,7 @@ def _py_list_node(form: list, ctx: AnalyzerContext) -> Union[Const, PyList]: @_analyze_form.register(set) @_with_loc -def _py_set_node(form: set, ctx: AnalyzerContext) -> Union[Const, PySet]: +def _py_set_node(form: set, ctx: AnalyzerContext) -> Const | PySet: if ctx.is_quoted: return _const_node(form, ctx) return PySet( @@ -3948,7 +3949,7 @@ def _py_set_node(form: set, ctx: AnalyzerContext) -> Union[Const, PySet]: @_analyze_form.register(tuple) @_with_loc -def _py_tuple_node(form: tuple, ctx: AnalyzerContext) -> Union[Const, PyTuple]: +def _py_tuple_node(form: tuple, ctx: AnalyzerContext) -> Const | PyTuple: if ctx.is_quoted: return _const_node(form, ctx) return PyTuple( @@ -3977,7 +3978,7 @@ def _map_node(form: lmap.PersistentMap, ctx: AnalyzerContext) -> MapNode: @_with_loc def _map_node_or_quoted( form: lmap.PersistentMap, ctx: AnalyzerContext -) -> Union[Const, MapNode]: +) -> Const | MapNode: if ctx.is_quoted: return _const_node(form, ctx) return _map_node(form, ctx) @@ -3996,7 +3997,7 @@ def _queue_node(form: lqueue.PersistentQueue, ctx: AnalyzerContext) -> QueueNode @_with_loc def _queue_node_or_quoted( form: lqueue.PersistentQueue, ctx: AnalyzerContext -) -> Union[Const, QueueNode]: +) -> Const | QueueNode: if ctx.is_quoted: return _const_node(form, ctx) return _queue_node(form, ctx) @@ -4015,7 +4016,7 @@ def _set_node(form: lset.PersistentSet, ctx: AnalyzerContext) -> SetNode: @_with_loc def _set_node_or_quoted( form: lset.PersistentSet, ctx: AnalyzerContext -) -> Union[Const, SetNode]: +) -> Const | SetNode: if ctx.is_quoted: return _const_node(form, ctx) return _set_node(form, ctx) @@ -4034,7 +4035,7 @@ def _vector_node(form: vec.PersistentVector, ctx: AnalyzerContext) -> VectorNode @_with_loc def _vector_node_or_quoted( form: vec.PersistentVector, ctx: AnalyzerContext -) -> Union[Const, VectorNode]: +) -> Const | VectorNode: if ctx.is_quoted: return _const_node(form, ctx) return _vector_node(form, ctx) diff --git a/src/basilisp/lang/compiler/exception.py b/src/basilisp/lang/compiler/exception.py index ea0642ef6..0a57402ee 100644 --- a/src/basilisp/lang/compiler/exception.py +++ b/src/basilisp/lang/compiler/exception.py @@ -42,10 +42,10 @@ class CompilerPhase(Enum): @attr.frozen 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 def __bool__(self): return ( @@ -61,9 +61,9 @@ class CompilerException(IExceptionInfo): msg: str phase: CompilerPhase 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 @property def data(self) -> IPersistentMap: @@ -112,15 +112,15 @@ def __str__(self): @format_exception.register(CompilerException) def format_compiler_exception( # pylint: disable=too-many-branches,unused-argument 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]: """Format a compiler exception as a list of newline-terminated strings. If `disable_color` is True, no color formatting will be applied to the source code.""" - context_exc: Optional[BaseException] = e.__cause__ + context_exc: BaseException | None = e.__cause__ lines: list[str] = [os.linesep] if context_exc is not None: diff --git a/src/basilisp/lang/compiler/generator.py b/src/basilisp/lang/compiler/generator.py index 431803dcd..41a61cd4e 100644 --- a/src/basilisp/lang/compiler/generator.py +++ b/src/basilisp/lang/compiler/generator.py @@ -18,10 +18,12 @@ from functools import partial, wraps from itertools import chain from re import Pattern -from typing import TYPE_CHECKING, Callable, Generic, Optional, TypeVar, Union, cast +from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union, cast +from collections.abc import Callable import attr -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import ParamSpec +from typing import Concatenate from basilisp.lang import keyword as kw from basilisp.lang import list as llist @@ -168,7 +170,7 @@ def new_symbol(self, s: sym.Symbol, munged: str, ctx: LocalType) -> "SymbolTable self._table[s] = SymbolTableEntry(ctx, munged, s) return self - def find_symbol(self, s: sym.Symbol) -> Optional[SymbolTableEntry]: + def find_symbol(self, s: sym.Symbol) -> SymbolTableEntry | None: if s in self._table: return self._table[s] if self._parent is None: @@ -217,8 +219,8 @@ class RecurType(Enum): class RecurPoint: loop_id: str type: RecurType - binding_names: Optional[Iterable[str]] = None - is_variadic: Optional[bool] = None + binding_names: Iterable[str] | None = None + is_variadic: bool | None = None has_recur: bool = False @@ -233,7 +235,7 @@ class GeneratorContext: ) def __init__( - self, filename: Optional[str] = None, opts: Optional[CompilerOpts] = None + self, filename: str | None = None, opts: CompilerOpts | None = None ) -> None: self._filename = Maybe(filename).or_else_get(DEFAULT_COMPILER_FILE_PATH) self._opts = Maybe(opts).map(lmap.map).or_else_get(lmap.m()) # type: ignore @@ -289,8 +291,8 @@ def new_recur_point( self, loop_id: str, type_: RecurType, - binding_names: Optional[Iterable[str]] = None, - is_variadic: Optional[bool] = None, + binding_names: Iterable[str] | None = None, + is_variadic: bool | None = None, ): self._recur_points.append( RecurPoint( @@ -325,9 +327,9 @@ def new_this(self, this: sym.Symbol): def GeneratorException( self, msg: 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, ) -> CompilerException: """Return a CompilerException annotated with the current filename and :code-generation compiler phase set. The remaining keyword arguments are @@ -536,9 +538,9 @@ def _fn_node( # pylint: disable=too-many-arguments args: ast.arguments, body: list[ast.stmt], decorator_list: list[ast.expr], - returns: Optional[ast.expr], + returns: ast.expr | None, is_async: bool, -) -> Union[ast.AsyncFunctionDef, ast.FunctionDef]: +) -> ast.AsyncFunctionDef | ast.FunctionDef: if is_async: return ast_AsyncFunctionDef( name=name, @@ -558,8 +560,8 @@ def _fn_node( # pylint: disable=too-many-arguments def _tagged_assign( - target: ast.Name, value: ast.expr, annotation: Optional[ast.expr] = None -) -> Union[ast.Assign, ast.AnnAssign]: + target: ast.Name, value: ast.expr, annotation: ast.expr | None = None +) -> ast.Assign | ast.AnnAssign: """Return a possibly annotated assignment.""" if annotation is not None: return ast.AnnAssign( @@ -654,7 +656,7 @@ def with_lineno_and_col( MetaNode = Union[Const, MapNode] -def _should_gen_safe_python_param_names(fn_meta_node: Optional[MetaNode]) -> bool: +def _should_gen_safe_python_param_names(fn_meta_node: MetaNode | None) -> bool: """Return True if the `fn_meta_node` has the meta key set to generate globally unique function parameter names.""" return ( @@ -831,8 +833,8 @@ def statementize(e: PyASTNode) -> ast.stmt: def expressionize( body: GeneratedPyAST, fn_name: str, - args: Optional[Iterable[ast.arg]] = None, - vargs: Optional[ast.arg] = None, + args: Iterable[ast.arg] | None = None, + vargs: ast.arg | None = None, ) -> ast.FunctionDef: """Given a series of expression AST nodes, create a function AST node with the given name that can be called and will return the result of @@ -929,7 +931,7 @@ def _def_to_py_ast( # pylint: disable=too-many-locals def_ast = gen_py_ast(ctx, node.init) is_defn = False - tag: Optional[ast.expr] + tag: ast.expr | None tag_deps: Iterable[PyASTNode] if node.tag is not None and (tag_ast := gen_py_ast(ctx, node.tag)) is not None: tag = tag_ast.node @@ -1095,8 +1097,8 @@ def __deftype_property_to_py_ast( def __multi_arity_deftype_dispatch_method( name: str, arity_map: Mapping[int, str], - default_name: Optional[str] = None, - max_fixed_arity: Optional[int] = None, + default_name: str | None = None, + max_fixed_arity: int | None = None, ) -> GeneratedPyAST[ast.stmt]: """Return the Python AST nodes for an argument-length dispatch method for multi-arity `deftype*` or `reify*` methods. @@ -1135,7 +1137,7 @@ def method(self, *args): """ method_prefix = genname("self") - dispatch_keys: list[Optional[ast.expr]] = [] + dispatch_keys: list[ast.expr | None] = [] dispatch_vals: list[ast.expr] = [] for k, v in arity_map.items(): dispatch_keys.append(ast.Constant(k)) @@ -1266,7 +1268,7 @@ def __multi_arity_deftype_method_to_py_ast( ) arity_to_name = {} - rest_arity_name: Optional[str] = None + rest_arity_name: str | None = None fn_defs = [] for arity in arities: arity_name = arity.python_name @@ -1301,7 +1303,7 @@ def __deftype_method_arity_to_py_ast( ctx: GeneratorContext, node: DefTypeMethod, arity: DefTypeMethodArity, - method_name: Optional[str] = None, + method_name: str | None = None, ) -> GeneratedPyAST[ast.stmt]: assert arity.op == NodeOp.DEFTYPE_METHOD_ARITY assert node.name == arity.name @@ -1417,7 +1419,7 @@ def __deftype_member_to_py_ast( def __deftype_or_reify_bases_to_py_ast( ctx: GeneratorContext, - node: Union[DefType, Reify], + node: DefType | Reify, interfaces: Iterable[DefTypeBase], ) -> list[ast.expr]: """Return a list of AST nodes for the base classes for a `deftype*` or `reify*`.""" @@ -1490,7 +1492,7 @@ def _deftype_to_py_ast( # pylint: disable=too-many-locals else: attr_default_kws = [] - tag: Optional[ast.expr] = None + tag: ast.expr | None = None if ( field.tag is not None and (tag_ast := gen_py_ast(ctx, field.tag)) is not None @@ -1640,7 +1642,7 @@ def _synthetic_do_to_py_ast( ) -def __fn_name(ctx: GeneratorContext, s: Optional[str]) -> str: +def __fn_name(ctx: GeneratorContext, s: str | None) -> str: """Generate a safe Python function name from a function name symbol. If no symbol is provided, generate a name with a default prefix. @@ -1659,7 +1661,7 @@ def __fn_args_to_py_ast( params: Iterable[Binding], body: Do, should_generate_safe_names: bool = False, -) -> tuple[list[ast.arg], Optional[ast.arg], list[ast.stmt], Iterable[PyASTNode]]: +) -> tuple[list[ast.arg], ast.arg | None, list[ast.stmt], Iterable[PyASTNode]]: """Generate a list of Python AST nodes from function method parameters. Parameter names are munged and modified to ensure global @@ -1681,7 +1683,7 @@ def __fn_args_to_py_ast( if should_generate_safe_names or binding.name == "_": arg_name = genname(arg_name) - arg_tag: Optional[ast.expr] + arg_tag: ast.expr | None if ( binding.tag is not None and (arg_tag_ast := gen_py_ast(ctx, binding.tag)) is not None @@ -1771,7 +1773,7 @@ def __fn_decorator( def __fn_meta( - ctx: GeneratorContext, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, meta_node: MetaNode | None = None ) -> tuple[Iterable[PyASTNode], Iterable[ast.expr]]: if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) @@ -1790,7 +1792,7 @@ def __fn_meta( def __kwargs_support_decorator( - node: Union[Fn, DefTypeMethodArity, DefTypeClassMethod, DefTypeStaticMethod], + node: Fn | DefTypeMethodArity | DefTypeClassMethod | DefTypeStaticMethod, ) -> Iterable[ast.expr]: if node.kwarg_support is None: return @@ -1806,8 +1808,8 @@ def __single_arity_fn_to_py_ast( # pylint: disable=too-many-locals ctx: GeneratorContext, node: Fn, method: FnArity, - def_name: Optional[str] = None, - meta_node: Optional[MetaNode] = None, + def_name: str | None = None, + meta_node: MetaNode | None = None, ) -> GeneratedPyAST[ast.expr]: """Return a Python AST node for a function with a single arity.""" assert node.op == NodeOp.FN @@ -1834,7 +1836,7 @@ def __single_arity_fn_to_py_ast( # pylint: disable=too-many-locals ) meta_deps, meta_decorators = __fn_meta(ctx, meta_node) - ret_ann_tag: Optional[ast.expr] + ret_ann_tag: ast.expr | None ret_ann_deps: Iterable[PyASTNode] if ( method.tag is not None @@ -1903,11 +1905,11 @@ def __multi_arity_dispatch_fn( # pylint: disable=too-many-arguments,too-many-lo ctx: GeneratorContext, name: str, arity_map: Mapping[int, str], - return_tags: Iterable[Optional[Node]], - default_name: Optional[str] = None, - rest_arity_fixed_arity: Optional[int] = None, - max_fixed_arity: Optional[int] = None, - meta_node: Optional[MetaNode] = None, + return_tags: Iterable[Node | None], + default_name: str | None = None, + rest_arity_fixed_arity: int | None = None, + max_fixed_arity: int | None = None, + meta_node: MetaNode | None = None, is_async: bool = False, ) -> GeneratedPyAST[ast.expr]: """Return the Python AST nodes for a argument-length dispatch function @@ -1925,7 +1927,7 @@ def fn(*args): """ dispatch_map_name = f"{name}_dispatch_map" - dispatch_keys: list[Optional[ast.expr]] = [] + dispatch_keys: list[ast.expr | None] = [] dispatch_vals: list[ast.expr] = [] for k, v in arity_map.items(): dispatch_keys.append(ast.Constant(k)) @@ -2025,7 +2027,7 @@ def fn(*args): meta_deps, meta_decorators = __fn_meta(ctx, meta_node) - ret_ann_ast: Optional[ast.expr] = None + ret_ann_ast: ast.expr | None = None ret_ann_deps: list[PyASTNode] = [] if all(tag is not None for tag in return_tags): ret_ann_asts: list[ast.expr] = [] @@ -2100,8 +2102,8 @@ def __multi_arity_fn_to_py_ast( # pylint: disable=too-many-locals ctx: GeneratorContext, node: Fn, arities: Collection[FnArity], - def_name: Optional[str] = None, - meta_node: Optional[MetaNode] = None, + def_name: str | None = None, + meta_node: MetaNode | None = None, ) -> GeneratedPyAST[ast.expr]: """Return a Python AST node for a function with multiple arities.""" assert node.op == NodeOp.FN @@ -2112,8 +2114,8 @@ def __multi_arity_fn_to_py_ast( # pylint: disable=too-many-locals py_fn_name = __fn_name(ctx, lisp_fn_name) if def_name is None else munge(def_name) arity_to_name = {} - rest_arity_name: Optional[str] = None - rest_arity_fixed_arity: Optional[int] = None + rest_arity_name: str | None = None + rest_arity_fixed_arity: int | None = None fn_defs = [] all_arity_def_deps: list[PyASTNode] = [] for arity in arities: @@ -2149,7 +2151,7 @@ def __multi_arity_fn_to_py_ast( # pylint: disable=too-many-locals ) all_arity_def_deps.extend(fn_def_deps) - ret_ann_tag: Optional[ast.expr] + ret_ann_tag: ast.expr | None if ( arity.tag is not None and (ret_ann_ast := gen_py_ast(ctx, arity.tag)) is not None @@ -2205,8 +2207,8 @@ def __multi_arity_fn_to_py_ast( # pylint: disable=too-many-locals def _fn_to_py_ast( ctx: GeneratorContext, node: Fn, - def_name: Optional[str] = None, - meta_node: Optional[MetaNode] = None, + def_name: str | None = None, + meta_node: MetaNode | None = None, ) -> GeneratedPyAST[ast.expr]: """Return a Python AST Node for a `fn` expression.""" assert node.op == NodeOp.FN @@ -2222,7 +2224,7 @@ def _fn_to_py_ast( @_with_ast_loc_deps def __if_body_to_py_ast( - ctx: GeneratorContext, node: Node, result_name: Optional[str] + ctx: GeneratorContext, node: Node, result_name: str | None ) -> GeneratedPyAST: """Generate custom `if` nodes to handle `recur` bodies. @@ -2410,7 +2412,7 @@ def _import_to_py_ast(ctx: GeneratorContext, node: Import) -> GeneratedPyAST[ast ) ) - refers: Optional[ast.expr] = None + refers: ast.expr | None = None if alias.refer_all: key, val = genname("k"), genname("v") refers = ast.DictComp( @@ -2448,7 +2450,7 @@ def _import_to_py_ast(ctx: GeneratorContext, node: Import) -> GeneratedPyAST[ast ], ) elif alias.refers: - refer_keys: list[Optional[ast.expr]] = [] + refer_keys: list[ast.expr | None] = [] refer_vals: list[ast.expr] = [] for refer in alias.refers: refer_keys.append( @@ -2536,7 +2538,7 @@ def _let_to_py_ast(ctx: GeneratorContext, node: Let) -> GeneratedPyAST[ast.expr] assert init_node is not None init_ast = gen_py_ast(ctx, init_node) - tag: Optional[ast.expr] + tag: ast.expr | None if ( binding.tag is not None and (tag_ast := gen_py_ast(ctx, binding.tag)) is not None @@ -2797,12 +2799,12 @@ def _recur_to_py_ast(ctx: GeneratorContext, node: Recur) -> GeneratedPyAST[ast.e @_with_ast_loc def _reify_to_py_ast( - ctx: GeneratorContext, node: Reify, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, node: Reify, meta_node: MetaNode | None = None ) -> GeneratedPyAST[ast.expr]: """Return a Python AST Node for a `reify*` expression.""" assert node.op == NodeOp.REIFY - meta_ast: Optional[GeneratedPyAST] + meta_ast: GeneratedPyAST | None if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) else: @@ -3108,7 +3110,7 @@ def _throw_to_py_ast(ctx: GeneratorContext, node: Throw) -> GeneratedPyAST[ast.e exc_ast = gen_py_ast(ctx, node.exception) - cause: Optional[ast.expr] + cause: ast.expr | None cause_deps: Iterable[PyASTNode] if ( node.cause is not None @@ -3250,7 +3252,7 @@ def _local_sym_to_py_ast( ) -def __name_in_module(name: str, module: BasilispModule) -> Optional[str]: +def __name_in_module(name: str, module: BasilispModule) -> str | None: """Resolve the name inside of module. If the munged name can be found inside the module, return the munged name. Return None otherwise.""" safe_name = munge(name) @@ -3264,7 +3266,7 @@ def __var_direct_link_to_py_ast( current_ns: runtime.Namespace, var: runtime.Var, py_var_ctx: PyASTCtx, -) -> Optional[GeneratedPyAST[ast.expr]]: +) -> GeneratedPyAST[ast.expr] | None: """Attempt to directly link a Var reference to a Python variable in the module of the current Namespace. @@ -3473,11 +3475,11 @@ def _maybe_host_form_to_py_ast( @_with_ast_loc def _map_to_py_ast( - ctx: GeneratorContext, node: MapNode, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, node: MapNode, meta_node: MetaNode | None = None ) -> GeneratedPyAST[ast.expr]: assert node.op == NodeOp.MAP - meta_ast: Optional[GeneratedPyAST] + meta_ast: GeneratedPyAST | None if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) else: @@ -3505,11 +3507,11 @@ def _map_to_py_ast( @_with_ast_loc def _queue_to_py_ast( - ctx: GeneratorContext, node: QueueNode, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, node: QueueNode, meta_node: MetaNode | None = None ) -> GeneratedPyAST[ast.expr]: assert node.op == NodeOp.QUEUE - meta_ast: Optional[GeneratedPyAST] + meta_ast: GeneratedPyAST | None if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) else: @@ -3534,11 +3536,11 @@ def _queue_to_py_ast( @_with_ast_loc def _set_to_py_ast( - ctx: GeneratorContext, node: SetNode, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, node: SetNode, meta_node: MetaNode | None = None ) -> GeneratedPyAST[ast.expr]: assert node.op == NodeOp.SET - meta_ast: Optional[GeneratedPyAST] + meta_ast: GeneratedPyAST | None if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) else: @@ -3563,11 +3565,11 @@ def _set_to_py_ast( @_with_ast_loc def _vec_to_py_ast( - ctx: GeneratorContext, node: VectorNode, meta_node: Optional[MetaNode] = None + ctx: GeneratorContext, node: VectorNode, meta_node: MetaNode | None = None ) -> GeneratedPyAST[ast.expr]: assert node.op == NodeOp.VECTOR - meta_ast: Optional[GeneratedPyAST] + meta_ast: GeneratedPyAST | None if meta_node is not None: meta_ast = gen_py_ast(ctx, meta_node) else: @@ -3717,7 +3719,7 @@ def _collection_literal_to_py_ast( def _const_meta_kwargs_ast( ctx: GeneratorContext, form: LispForm -) -> Optional[GeneratedPyAST]: +) -> GeneratedPyAST | None: if isinstance(form, IMeta) and form.meta is not None: genned = _const_val_to_py_ast(_clean_meta(form), ctx) return GeneratedPyAST( @@ -3736,7 +3738,7 @@ def _const_meta_kwargs_ast( @_const_val_to_py_ast.register(int) @_const_val_to_py_ast.register(str) @_simple_ast_generator -def _py_const_to_py_ast(form: Union[bool, None], _: GeneratorContext) -> ast.Constant: +def _py_const_to_py_ast(form: bool | None, _: GeneratorContext) -> ast.Constant: return ast.Constant(form) @@ -3920,7 +3922,7 @@ def _const_set_to_py_ast( @_const_val_to_py_ast.register(llist.PersistentList) @_const_val_to_py_ast.register(ISeq) def _const_seq_to_py_ast( - form: Union[llist.PersistentList, ISeq], ctx: GeneratorContext + form: llist.PersistentList | ISeq, ctx: GeneratorContext ) -> GeneratedPyAST[ast.expr]: elem_deps, elems = _chain_py_ast(*_collection_literal_to_py_ast(ctx, form)) diff --git a/src/basilisp/lang/compiler/nodes.py b/src/basilisp/lang/compiler/nodes.py index ff4605542..4eb3fa2c6 100644 --- a/src/basilisp/lang/compiler/nodes.py +++ b/src/basilisp/lang/compiler/nodes.py @@ -1,7 +1,8 @@ from abc import ABC, abstractmethod from collections.abc import Iterable, MutableMapping, Sequence from enum import Enum -from typing import Any, Callable, Generic, Optional, TypeVar, Union +from typing import Any, Generic, Optional, TypeVar, Union +from collections.abc import Callable import attr @@ -186,7 +187,7 @@ def visit(self, f: Callable[..., None], *args, **kwargs): f(child, *args, **kwargs) 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]": """Return a transformed copy of this node with location in this node's environment updated to match the `form_loc` if given, or using its @@ -207,7 +208,7 @@ def fix_missing_locations( e is not None for e in loc ), "Must specify location information" - new_attrs: MutableMapping[str, Union[NodeEnv, Node, Iterable[Node]]] = { + new_attrs: MutableMapping[str, NodeEnv | Node | Iterable[Node]] = { "env": attr.evolve( self.env, line=loc[0], col=loc[1], end_line=loc[2], end_col=loc[3] ) @@ -330,12 +331,12 @@ class LocalType(Enum): class NodeEnv: ns: Namespace 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 @attr.frozen @@ -355,11 +356,11 @@ class Binding(Node[sym.Symbol], Assignable): name: str local: LocalType 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 children: Sequence[kw.Keyword] = vec.EMPTY op: NodeOp = NodeOp.BINDING @@ -399,10 +400,10 @@ class Def(Node[SpecialForm]): form: SpecialForm name: sym.Symbol 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 children: Sequence[kw.Keyword] = vec.EMPTY op: NodeOp = NodeOp.DEF @@ -455,7 +456,7 @@ class DefTypeClassMethod(DefTypeMember): fixed_arity: int body: "Do" is_variadic: bool = False - kwarg_support: Optional[KeywordArgSupport] = None + kwarg_support: KeywordArgSupport | None = None children: Sequence[kw.Keyword] = vec.v(CLASS_LOCAL, PARAMS, BODY) op: NodeOp = NodeOp.DEFTYPE_CLASSMETHOD top_level: bool = False @@ -484,7 +485,7 @@ class DefTypeMethodArity(Node[SpecialForm]): loop_id: LoopID env: NodeEnv = attr.field(hash=False) is_variadic: bool = False - kwarg_support: Optional[KeywordArgSupport] = None + kwarg_support: KeywordArgSupport | None = None children: Sequence[kw.Keyword] = vec.v(THIS_LOCAL, PARAMS, BODY) op: NodeOp = NodeOp.DEFTYPE_METHOD_ARITY top_level: bool = False @@ -512,7 +513,7 @@ class DefTypeStaticMethod(DefTypeMember): fixed_arity: int body: "Do" is_variadic: bool = False - kwarg_support: Optional[KeywordArgSupport] = None + kwarg_support: KeywordArgSupport | None = None children: Sequence[kw.Keyword] = vec.v(PARAMS, BODY) op: NodeOp = NodeOp.DEFTYPE_STATICMETHOD top_level: bool = False @@ -542,10 +543,10 @@ class Fn(Node[SpecialForm]): max_fixed_arity: int arities: IPersistentVector["FnArity"] 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 children: Sequence[kw.Keyword] = vec.v(ARITIES) op: NodeOp = NodeOp.FN @@ -561,7 +562,7 @@ class FnArity(Node[SpecialForm]): fixed_arity: int body: Do env: NodeEnv = attr.field(hash=False) - tag: Optional[Node] = None + tag: Node | None = None is_variadic: bool = False children: Sequence[kw.Keyword] = vec.v(PARAMS, BODY) op: NodeOp = NodeOp.FN_ARITY @@ -585,7 +586,7 @@ class HostCall(Node[SpecialForm]): @attr.frozen class HostField(Node[Union[SpecialForm, sym.Symbol]], Assignable): - form: Union[SpecialForm, sym.Symbol] + form: SpecialForm | sym.Symbol field: str target: Node env: NodeEnv = attr.field(hash=False) @@ -622,9 +623,9 @@ class Import(Node[SpecialForm]): @attr.frozen 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) @@ -678,7 +679,7 @@ class Local(Node[sym.Symbol], Assignable): local: LocalType env: NodeEnv = attr.field(hash=False) is_assignable: bool = False - arg_id: Optional[int] = None + arg_id: int | None = None is_variadic: bool = False children: Sequence[kw.Keyword] = vec.EMPTY op: NodeOp = NodeOp.LOCAL @@ -761,7 +762,7 @@ class PyList(Node[list]): @attr.frozen(eq=True) class PySet(Node[Union[frozenset, set]]): - form: Union[frozenset, set] + form: frozenset | set items: Iterable[Node] env: NodeEnv = attr.field(hash=False) children: Sequence[kw.Keyword] = vec.v(ITEMS) @@ -839,9 +840,9 @@ def python_member_names(self) -> Iterable[str]: @attr.frozen 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) children: Sequence[kw.Keyword] = vec.EMPTY op: NodeOp = NodeOp.REQUIRE_ALIAS @@ -874,7 +875,7 @@ class Set(Node[IPersistentSet]): @attr.frozen class SetBang(Node[SpecialForm]): form: SpecialForm - target: Union[Assignable, Node] + target: Assignable | Node val: Node env: NodeEnv = attr.field(hash=False) children: Sequence[kw.Keyword] = vec.v(TARGET, VAL) @@ -887,7 +888,7 @@ class SetBang(Node[SpecialForm]): class Throw(Node[SpecialForm]): form: SpecialForm exception: Node - cause: Optional[Node] + cause: Node | None env: NodeEnv = attr.field(hash=False) children: Sequence[kw.Keyword] = vec.v(EXCEPTION) op: NodeOp = NodeOp.THROW @@ -902,7 +903,7 @@ class Try(Node[SpecialForm]): catches: Iterable[Catch] children: Sequence[kw.Keyword] env: NodeEnv = attr.field(hash=False) - finally_: Optional[Do] = None + finally_: Do | None = None op: NodeOp = NodeOp.TRY top_level: bool = False raw_forms: IPersistentVector[LispForm] = vec.EMPTY @@ -910,7 +911,7 @@ class Try(Node[SpecialForm]): @attr.frozen class VarRef(Node[Union[sym.Symbol, ISeq]], Assignable): - form: Union[sym.Symbol, ISeq] + form: sym.Symbol | ISeq var: Var env: NodeEnv = attr.field(hash=False) return_var: bool = False @@ -939,7 +940,7 @@ class Vector(Node[IPersistentVector]): @attr.frozen class WithMeta(Node[LispForm], Generic[T_withmeta]): form: LispForm - meta: Union[Const, Map] + meta: Const | Map expr: T_withmeta env: NodeEnv = attr.field(hash=False) children: Sequence[kw.Keyword] = vec.v(META, EXPR) @@ -951,7 +952,7 @@ class WithMeta(Node[LispForm], Generic[T_withmeta]): @attr.frozen class Yield(Node[SpecialForm]): form: SpecialForm - expr: Optional[Node] + expr: Node | None env: NodeEnv = attr.field(hash=False) children: Sequence[kw.Keyword] = vec.v(EXPR) op: NodeOp = NodeOp.YIELD diff --git a/src/basilisp/lang/compiler/optimizer.py b/src/basilisp/lang/compiler/optimizer.py index 3e989c509..aa12d388f 100644 --- a/src/basilisp/lang/compiler/optimizer.py +++ b/src/basilisp/lang/compiler/optimizer.py @@ -150,7 +150,7 @@ def visit_Call(self, node: ast.Call) -> ast.AST: ) return new_node - 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.""" new_node = self.generic_visit(node) assert isinstance(new_node, ast.ExceptHandler) @@ -163,14 +163,14 @@ def visit_ExceptHandler(self, node: ast.ExceptHandler) -> Optional[ast.AST]: new_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 as standalone statements.""" if isinstance(node.value, (ast.Constant, ast.Name)): return None return node - 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.""" with self._new_global_context(): new_node = self.generic_visit(node) @@ -186,7 +186,7 @@ def visit_FunctionDef(self, node: ast.FunctionDef) -> Optional[ast.AST]: new_node, ) - 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. Python `global` statements may only refer to a name prior to its declaration. @@ -201,7 +201,7 @@ def visit_Global(self, node: ast.Global) -> Optional[ast.Global]: else None ) - 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. If the new `if` statement `body` is empty after eliminating dead code, replace @@ -232,7 +232,7 @@ def visit_If(self, node: ast.If) -> Optional[ast.AST]: return ast.copy_location(ifstmt, new_node) - 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.""" new_node = self.generic_visit(node) assert isinstance(new_node, ast.While) @@ -245,7 +245,7 @@ def visit_While(self, node: ast.While) -> Optional[ast.AST]: new_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.""" new_node = self.generic_visit(node) assert isinstance(new_node, ast.Try) diff --git a/src/basilisp/lang/delay.py b/src/basilisp/lang/delay.py index 03270e702..404b5be98 100644 --- a/src/basilisp/lang/delay.py +++ b/src/basilisp/lang/delay.py @@ -1,4 +1,5 @@ -from typing import Callable, Generic, Optional, TypeVar +from typing import Generic, Optional, TypeVar +from collections.abc import Callable import attr @@ -11,7 +12,7 @@ @attr.frozen class _DelayState(Generic[T]): f: Callable[[], T] - value: Optional[T] + value: T | None computed: bool = False @@ -28,7 +29,7 @@ def __deref(state: _DelayState) -> _DelayState: else: return _DelayState(f=state.f, value=state.f(), computed=True) - def deref(self) -> Optional[T]: + def deref(self) -> T | None: return self._state.swap(self.__deref).value @property diff --git a/src/basilisp/lang/exception.py b/src/basilisp/lang/exception.py index 43be9bd04..c6abaee87 100644 --- a/src/basilisp/lang/exception.py +++ b/src/basilisp/lang/exception.py @@ -26,10 +26,10 @@ def __str__(self): @functools.singledispatch 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]: """Format an exception into something readable, returning a list of newline terminated strings. @@ -49,9 +49,9 @@ def format_exception( # pylint: disable=unused-argument 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: """Print the given exception `e` using Basilisp's own exception formatting. diff --git a/src/basilisp/lang/futures.py b/src/basilisp/lang/futures.py index 9830212b5..21059fc36 100644 --- a/src/basilisp/lang/futures.py +++ b/src/basilisp/lang/futures.py @@ -2,7 +2,8 @@ from concurrent.futures import ProcessPoolExecutor as _ProcessPoolExecutor from concurrent.futures import ThreadPoolExecutor as _ThreadPoolExecutor from concurrent.futures import TimeoutError as _TimeoutError -from typing import Callable, Optional, TypeVar +from typing import Optional, TypeVar +from collections.abc import Callable import attr from typing_extensions import ParamSpec @@ -27,8 +28,8 @@ def cancelled(self) -> bool: return self._future.cancelled() 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: return self._future.result(timeout=timeout) except _TimeoutError: @@ -43,7 +44,7 @@ def is_realized(self) -> bool: # Pass `Future.result(timeout=...)` through so `Executor.map(...)` can # 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) @@ -53,7 +54,7 @@ def result(self, timeout: Optional[float] = None) -> T: 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) # pylint: disable=arguments-differ @@ -66,7 +67,7 @@ def submit( # type: ignore[override] class ThreadPoolExecutor(_ThreadPoolExecutor): def __init__( self, - max_workers: Optional[int] = None, + max_workers: int | None = None, thread_name_prefix: str = "basilisp-futures", ): super().__init__(max_workers=max_workers, thread_name_prefix=thread_name_prefix) diff --git a/src/basilisp/lang/interfaces.py b/src/basilisp/lang/interfaces.py index c29ed9f05..d728471b8 100644 --- a/src/basilisp/lang/interfaces.py +++ b/src/basilisp/lang/interfaces.py @@ -4,7 +4,6 @@ from typing import ( AbstractSet, Any, - Callable, Final, Generic, Optional, @@ -13,6 +12,7 @@ Union, overload, ) +from collections.abc import Callable from typing_extensions import Self, Unpack @@ -33,7 +33,7 @@ class IDeref(Generic[T], ABC): __slots__ = () @abstractmethod - def deref(self) -> Optional[T]: + def deref(self) -> T | None: raise NotImplementedError() @@ -50,8 +50,8 @@ class IBlockingDeref(IDeref[T]): @abstractmethod 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() @@ -178,12 +178,12 @@ def name(self) -> str: @property @abstractmethod - def ns(self) -> Optional[str]: + def ns(self) -> str | None: raise NotImplementedError() @classmethod @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`.""" raise NotImplementedError() @@ -239,11 +239,11 @@ def remove_watch(self, k: RefWatchKey) -> "IReference": 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() @@ -304,7 +304,7 @@ class ILookup(Generic[K, V], ABC): __slots__ = () @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() @@ -364,7 +364,7 @@ def contains(self, k: K) -> bool: raise NotImplementedError() @abstractmethod - def entry(self, k: K) -> Optional[IMapEntry[K, V]]: + def entry(self, k: K) -> IMapEntry[K, V] | None: raise NotImplementedError() @@ -380,7 +380,7 @@ class IPersistentStack(IPersistentCollection[T]): __slots__ = () @abstractmethod - def peek(self) -> Optional[T]: + def peek(self) -> T | None: raise NotImplementedError() @abstractmethod @@ -605,7 +605,7 @@ def contains_transient(self, k: K) -> bool: raise NotImplementedError() @abstractmethod - def entry_transient(self, k: K) -> Optional[IMapEntry[K, V]]: + def entry_transient(self, k: K) -> IMapEntry[K, V] | None: raise NotImplementedError() @@ -767,7 +767,7 @@ def is_empty(self) -> bool: @property @abstractmethod - def first(self) -> Optional[T]: + def first(self) -> T | None: raise NotImplementedError() @property diff --git a/src/basilisp/lang/keyword.py b/src/basilisp/lang/keyword.py index adbedcc21..e98bfb8c7 100644 --- a/src/basilisp/lang/keyword.py +++ b/src/basilisp/lang/keyword.py @@ -23,7 +23,7 @@ class Keyword(ILispObject, INamed): __slots__ = ("_name", "_ns", "_hash") - def __init__(self, name: str, ns: Optional[str] = None) -> None: + def __init__(self, name: str, ns: str | None = None) -> None: self._name = name self._ns = ns self._hash = hash_kw(name, ns) @@ -33,11 +33,11 @@ def name(self) -> str: return self._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) -> "Keyword": + def with_name(cls, name: str, ns: str | None = None) -> "Keyword": return keyword(name, ns=ns) def _lrepr(self, **kwargs: Unpack[PrintSettings]) -> str: @@ -67,7 +67,7 @@ def __lt__(self, other): return False return self._ns < other._ns or self._name < other._name - def __call__(self, m: Union[IAssociative, IPersistentSet], default=None): + def __call__(self, m: IAssociative | IPersistentSet, default=None): if isinstance(m, IPersistentSet): return self if self in m else default try: @@ -81,7 +81,7 @@ def __reduce__(self): def complete( text: str, - kw_cache: Optional[IPersistentMap[int, Keyword]] = None, + kw_cache: IPersistentMap[int, Keyword] | None = None, ) -> Iterable[str]: """Return an iterable of possible completions for the given text.""" assert text.startswith(":") @@ -107,12 +107,12 @@ def complete( return map(str, results) -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.""" 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 keyword with name `name` and optional namespace `ns`. @@ -136,14 +136,14 @@ def keyword_from_hash(kw_hash: int, name: str, ns: Optional[str] = None) -> Keyw return kw -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. If the keyword with that name is not interned, return None.""" with _LOCK: return _INTERN.val_at(hash_kw(name, ns)) -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`. Keyword instances are interned, so an existing object may be returned if one diff --git a/src/basilisp/lang/list.py b/src/basilisp/lang/list.py index efc65e1eb..94f4a46b3 100644 --- a/src/basilisp/lang/list.py +++ b/src/basilisp/lang/list.py @@ -42,10 +42,10 @@ def _lrepr(self, **kwargs: Unpack[PrintSettings]) -> str: return _seq_lrepr(self._inner, "(", ")", meta=self._meta, **kwargs) @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) @property @@ -74,7 +74,7 @@ def cons(self, *elems: T) -> "PersistentList[T]": def empty(self) -> "PersistentList": return EMPTY.with_meta(self._meta) - def seq(self) -> Optional[ISeq[T]]: + def seq(self) -> ISeq[T] | None: if len(self._inner) == 0: return None return super().seq() diff --git a/src/basilisp/lang/map.py b/src/basilisp/lang/map.py index 2b500b75a..1889ba0f4 100644 --- a/src/basilisp/lang/map.py +++ b/src/basilisp/lang/map.py @@ -1,7 +1,8 @@ from builtins import map as pymap from collections.abc import Iterable, Mapping from itertools import islice -from typing import Any, Callable, Optional, TypeVar, Union, cast +from typing import Any, Optional, TypeVar, Union, cast +from collections.abc import Callable from immutables import Map as _Map from immutables import MapMutation @@ -78,7 +79,7 @@ def dissoc_transient(self, *ks: K) -> "TransientMap[K, V]": pass return self - 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)) if v is _ENTRY_SENTINEL: return None @@ -89,12 +90,12 @@ def val_at(self, k, default=None): def cons_transient( # type: ignore[override] 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]": try: for elem in elems: @@ -123,7 +124,7 @@ def map_lrepr( # pylint: disable=too-many-locals entries: Callable[[], Iterable[tuple[Any, Any]]], start: str, end: str, - meta: Optional[IPersistentMap] = None, + meta: IPersistentMap | None = None, **kwargs: Unpack[PrintSettings], ) -> str: """Produce a Lisp representation of an associative collection, bookended @@ -220,7 +221,7 @@ class PersistentMap( def __init__( self, m: "_Map[K, V]", - meta: Optional[IPersistentMap] = None, + meta: IPersistentMap | None = None, ) -> None: self._inner = m self._meta = meta @@ -228,8 +229,8 @@ def __init__( @classmethod def from_coll( 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]": return PersistentMap(_Map(members), meta=meta) @@ -273,10 +274,10 @@ def _lrepr(self, **kwargs: Unpack[PrintSettings]): ) @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) def assoc(self, *kvs): @@ -321,12 +322,12 @@ def update_with( # type: ignore[return] def cons( # type: ignore[override, return] 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]": with self._inner.mutate() as m: try: @@ -351,7 +352,7 @@ def cons( # type: ignore[override, return] def empty(self) -> "PersistentMap": return EMPTY.with_meta(self._meta) - def seq(self) -> Optional[ISeq[IMapEntry[K, V]]]: + def seq(self) -> ISeq[IMapEntry[K, V]] | None: if len(self._inner) == 0: return None return iterator_sequence((MapEntry.of(k, v) for k, v in self._inner.items())) @@ -371,7 +372,7 @@ def reduce_kv(self, f: ReduceKVFunction, init: T_reduce) -> T_reduce: 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]: """Creates a new map.""" # For some reason, creating a new `immutables.Map` instance from an existing diff --git a/src/basilisp/lang/multifn.py b/src/basilisp/lang/multifn.py index 5c29c4d56..c7070cf09 100644 --- a/src/basilisp/lang/multifn.py +++ b/src/basilisp/lang/multifn.py @@ -1,5 +1,6 @@ import threading -from typing import Any, Callable, Generic, Optional, TypeVar +from typing import Any, Generic, Optional, TypeVar +from collections.abc import Callable from basilisp.lang import map as lmap from basilisp.lang import runtime @@ -35,7 +36,7 @@ def __init__( name: sym.Symbol, dispatch: DispatchFunction, default: T, - hierarchy: Optional[IRef] = None, + hierarchy: IRef | None = None, ) -> None: self._name = name self._default = default @@ -101,11 +102,11 @@ def add_method(self, key: T, method: Method) -> None: self._methods = self._methods.assoc(key, method) self._reset_cache() - def _find_and_cache_method(self, key: T) -> Optional[Method]: + def _find_and_cache_method(self, key: T) -> Method | 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(): if self._is_a(key, method_key): if best_key is None or self._precedes(method_key, best_key): @@ -125,7 +126,7 @@ def _find_and_cache_method(self, key: T) -> Optional[Method]: return best_method - def get_method(self, key: T) -> Optional[Method]: + def get_method(self, key: T) -> Method | None: """Return the method which would handle this dispatch key or None if no method defined for this key and no default.""" if self._cached_hierarchy != self._hierarchy.deref(): @@ -159,7 +160,7 @@ def prefers(self): """Return a mapping of preferred values to the set of other values.""" return self._prefers - def remove_method(self, key: T) -> Optional[Method]: + def remove_method(self, key: T) -> Method | None: """Remove the method defined for this key and return it.""" with self._lock: method = self._methods.val_at(key, None) diff --git a/src/basilisp/lang/promise.py b/src/basilisp/lang/promise.py index 4af620674..31d86ff4a 100644 --- a/src/basilisp/lang/promise.py +++ b/src/basilisp/lang/promise.py @@ -12,7 +12,7 @@ class Promise(IBlockingDeref[T], IPending): def __init__(self) -> None: self._condition = threading.Condition() self._is_delivered = False - self._value: Optional[T] = None + self._value: T | None = None def deliver(self, value: T) -> None: with self._condition: @@ -22,8 +22,8 @@ def deliver(self, value: T) -> None: self._condition.notify_all() 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: if self._condition.wait_for(lambda: self._is_delivered, timeout=timeout): return self._value diff --git a/src/basilisp/lang/queue.py b/src/basilisp/lang/queue.py index eb7061c2a..c25a0eae1 100644 --- a/src/basilisp/lang/queue.py +++ b/src/basilisp/lang/queue.py @@ -53,10 +53,10 @@ def _lrepr(self, **kwargs: Unpack[PrintSettings]) -> str: return _seq_lrepr(self._inner, "#queue (", ")", meta=self._meta, **kwargs) @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) def cons(self, *elems: T) -> "PersistentQueue[T]": @@ -76,7 +76,7 @@ def pop(self) -> "PersistentQueue[T]": raise IndexError("Cannot pop an empty queue") return PersistentQueue(self._inner.popleft(), meta=self._meta) - def seq(self) -> Optional[ISeq[T]]: + def seq(self) -> ISeq[T] | None: if len(self._inner) == 0: return None return sequence(self) diff --git a/src/basilisp/lang/reader.py b/src/basilisp/lang/reader.py index ee5587ad4..4c18e677a 100644 --- a/src/basilisp/lang/reader.py +++ b/src/basilisp/lang/reader.py @@ -15,7 +15,8 @@ from itertools import chain from re import Pattern from types import TracebackType -from typing import Any, Callable, NoReturn, Optional, TypeVar, Union, cast +from typing import Any, NoReturn, Optional, TypeVar, Union, cast +from collections.abc import Callable import attr from typing_extensions import Unpack @@ -127,9 +128,9 @@ class Comment: @attr.define(repr=False, str=False) class SyntaxError(Exception): message: str - line: Optional[int] = None - col: Optional[int] = None - filename: Optional[str] = None + line: int | None = None + col: int | None = None + filename: str | None = None def __repr__(self): return ( @@ -138,7 +139,7 @@ def __repr__(self): ) def __str__(self): - keys: dict[str, Union[str, int]] = {} + keys: dict[str, str | int] = {} if self.filename is not None: keys["file"] = self.filename if self.line is not None and self.col is not None: @@ -154,14 +155,14 @@ def __str__(self): @format_exception.register(SyntaxError) def format_syntax_error( # pylint: disable=unused-argument e: SyntaxError, - 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]: """If `disable_color` is True, no color formatting will be applied to the source code.""" - context_exc: Optional[BaseException] = e.__cause__ + context_exc: BaseException | None = e.__cause__ lines: list[str] = [os.linesep] if context_exc is not None: @@ -225,8 +226,8 @@ def __init__( self, stream: io.TextIOBase, pushback_depth: int = 5, - init_line: Optional[int] = None, - init_column: Optional[int] = None, + init_line: int | None = None, + init_column: int | None = None, ) -> None: """`init_line` and `init_column` refer to where the `stream` starts in the broader context, defaulting to 1 and 0 @@ -245,7 +246,7 @@ def __init__( self._update_loc() @property - def name(self) -> Optional[str]: + def name(self) -> str | None: return getattr(self._stream, "name", None) @property @@ -378,12 +379,12 @@ class ReaderContext: def __init__( # pylint: disable=too-many-arguments self, reader: StreamReader, - resolver: Optional[Resolver] = None, - data_readers: Optional[DataReaders] = None, + resolver: Resolver | None = None, + data_readers: DataReaders | None = None, eof: Any = None, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, - default_data_reader_fn: Optional[DefaultDataReaderFn] = None, + default_data_reader_fn: DefaultDataReaderFn | None = None, ) -> None: self._data_readers = Maybe(data_readers).or_else_get(lmap.EMPTY) self._default_data_reader_fn = Maybe(default_data_reader_fn).or_else_get( @@ -540,8 +541,8 @@ def _compile_feature_vec(form: IPersistentList[tuple[kw.Keyword, ReaderForm]]): return vec.vector(feature_list) def val_at( - self, k: kw.Keyword, default: Optional[ReaderForm] = None - ) -> Optional[ReaderForm]: + self, k: kw.Keyword, default: ReaderForm | None = None + ) -> ReaderForm | None: if k == READER_COND_FORM_KW: return self._form elif k == READER_COND_SPLICING_KW: @@ -555,7 +556,7 @@ def is_splicing(self): def select_feature( self, features: IPersistentSet[kw.Keyword] - ) -> Union[ReaderForm, object]: + ) -> ReaderForm | object: for k, form in self._feature_vec: if k in features: return form @@ -610,8 +611,8 @@ def _consume_whitespace(ctx: ReaderContext) -> str: def _read_namespaced( - ctx: ReaderContext, allowed_suffix: Optional[str] = None -) -> tuple[Optional[str], str]: + ctx: ReaderContext, allowed_suffix: str | None = None +) -> tuple[str | None, str]: """Read a namespaced token (keyword or symbol) from the input stream.""" ns: list[str] = [] name: list[str] = [] @@ -657,7 +658,7 @@ def _read_coll( ctx: ReaderContext, f: Callable[ [Collection[Any]], - Union[llist.PersistentList, lset.PersistentSet, vec.PersistentVector], + llist.PersistentList | lset.PersistentSet | vec.PersistentVector, ], end_char: str, coll_name: str, @@ -771,7 +772,7 @@ def __read_map_elems(ctx: ReaderContext) -> Iterable[RawReaderForm]: def _map_key_processor( - namespace: Optional[str], + namespace: str | None, ) -> Callable[[Any], Any]: """Return a map key processor. @@ -799,7 +800,7 @@ def process_key(k: Any) -> Any: @_with_loc def _read_map( - ctx: ReaderContext, namespace: Optional[str] = None + ctx: ReaderContext, namespace: str | None = None ) -> lmap.PersistentMap: """Return a map from the input stream.""" reader = ctx.reader @@ -974,7 +975,7 @@ def _read_str(ctx: ReaderContext, allow_arbitrary_escapes: bool = False) -> str: s.append(char) -def _read_fstr(ctx: ReaderContext) -> Union[str, llist.PersistentList]: +def _read_fstr(ctx: ReaderContext) -> str | llist.PersistentList: """Return a UTF-8 encoded string from the input stream.""" elems: list[LispReaderForm] = [] s: list[str] = [] @@ -1151,7 +1152,7 @@ def _read_meta(ctx: ReaderContext) -> IMeta: assert start == "^" meta = _read_next_consuming_comment(ctx) - meta_map: Optional[lmap.PersistentMap[LispForm, LispForm]] + meta_map: lmap.PersistentMap[LispForm, LispForm] | None if isinstance(meta, sym.Symbol): meta_map = lmap.map({READER_TAG_KW: meta}) elif isinstance(meta, kw.Keyword): @@ -1188,7 +1189,7 @@ def _walk(form, _, outer_f): @_walk.register(IPersistentList) @_walk.register(ISeq) -def _walk_ipersistentlist(form: Union[IPersistentList, ISeq], inner_f, outer_f): +def _walk_ipersistentlist(form: IPersistentList | ISeq, inner_f, outer_f): coll = llist.list(map(inner_f, form)) if isinstance(form, IMeta) and form.meta is not None: coll = coll.with_meta(form.meta) @@ -1238,7 +1239,7 @@ def _read_function(ctx: ReaderContext) -> llist.PersistentList: form = _read_list(ctx) arg_set = set() - def arg_suffix(arg_num: Optional[str]) -> str: + def arg_suffix(arg_num: str | None) -> str: if arg_num is None: return "1" elif arg_num == "&": @@ -1246,7 +1247,7 @@ def arg_suffix(arg_num: Optional[str]) -> str: else: return arg_num - def sym_replacement(arg_num: Optional[str]) -> sym.Symbol: + def sym_replacement(arg_num: str | None) -> sym.Symbol: suffix = arg_suffix(arg_num) if ctx.is_syntax_quoted: suffix = f"{suffix}#" @@ -1630,7 +1631,7 @@ def _read_reader_conditional(ctx: ReaderContext) -> LispReaderForm: def _load_record_or_type( ctx: ReaderContext, s: sym.Symbol, v: LispReaderForm -) -> Union[IRecord, IType]: +) -> IRecord | IType: """Attempt to load the constructor named by `s` and construct a new record or type instance from the vector or map following name.""" assert s.ns is None, "Record reader macro cannot have namespace" @@ -1821,12 +1822,12 @@ def _read_next(ctx: ReaderContext) -> LispReaderForm: # noqa: C901 def syntax_quote( # pylint: disable=too-many-arguments form: RawReaderForm, - resolver: Optional[Resolver] = None, - data_readers: Optional[DataReaders] = None, + resolver: Resolver | None = None, + data_readers: DataReaders | None = None, eof: Any = EOF, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, - default_data_reader_fn: Optional[DefaultDataReaderFn] = None, + default_data_reader_fn: DefaultDataReaderFn | None = None, ): """Return the syntax quoted version of a form.""" # the buffer is unused here, but is necessary to create a ReaderContext @@ -1845,15 +1846,15 @@ def syntax_quote( # pylint: disable=too-many-arguments def read( # pylint: disable=too-many-arguments stream, - resolver: Optional[Resolver] = None, - data_readers: Optional[DataReaders] = None, + resolver: Resolver | None = None, + data_readers: DataReaders | None = None, eof: Any = EOF, is_eof_error: bool = False, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, - default_data_reader_fn: Optional[DefaultDataReaderFn] = None, - init_line: Optional[int] = None, - init_column: Optional[int] = None, + default_data_reader_fn: DefaultDataReaderFn | None = None, + init_line: int | None = None, + init_column: int | None = None, ) -> Iterable[RawReaderForm]: """Read the contents of a stream as a Lisp expression. @@ -1907,15 +1908,15 @@ def read( # pylint: disable=too-many-arguments def read_str( # pylint: disable=too-many-arguments s: str, - resolver: Optional[Resolver] = None, - data_readers: Optional[DataReaders] = None, + resolver: Resolver | None = None, + data_readers: DataReaders | None = None, eof: Any = EOF, is_eof_error: bool = False, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, - default_data_reader_fn: Optional[DefaultDataReaderFn] = None, - init_line: Optional[int] = None, - init_column: Optional[int] = None, + default_data_reader_fn: DefaultDataReaderFn | None = None, + init_line: int | None = None, + init_column: int | None = None, ) -> Iterable[RawReaderForm]: """Read the contents of a string as a Lisp expression. @@ -1942,13 +1943,13 @@ def read_str( # pylint: disable=too-many-arguments def read_file( # pylint: disable=too-many-arguments filename: str, - resolver: Optional[Resolver] = None, - data_readers: Optional[DataReaders] = None, + resolver: Resolver | None = None, + data_readers: DataReaders | None = None, eof: Any = EOF, is_eof_error: bool = False, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, - default_data_reader_fn: Optional[DefaultDataReaderFn] = None, + default_data_reader_fn: DefaultDataReaderFn | None = None, ) -> Iterable[RawReaderForm]: """Read the contents of a file as a Lisp expression. diff --git a/src/basilisp/lang/reference.py b/src/basilisp/lang/reference.py index 476d654f3..7007def5d 100644 --- a/src/basilisp/lang/reference.py +++ b/src/basilisp/lang/reference.py @@ -1,7 +1,9 @@ import threading -from typing import Any, Callable, Optional, TypeVar +from typing import Any, Optional, TypeVar +from collections.abc import Callable -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import ParamSpec +from typing import Concatenate from basilisp.lang import keyword as kw from basilisp.lang import map as lmap @@ -28,19 +30,19 @@ class ReferenceBase(IReference): Implementers must have the `_lock` and `_meta` properties defined.""" _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: self._meta = f(self._meta, *args) return self._meta - def reset_meta(self, meta: Optional[IPersistentMap]) -> Optional[IPersistentMap]: + def reset_meta(self, meta: IPersistentMap | None) -> IPersistentMap | None: with self._lock: self._meta = meta return meta @@ -59,7 +61,7 @@ class RefBase(IRef[T], ReferenceBase): Implementers must have the `_validators` and `_watches` properties defined. """ - _validator: Optional[RefValidator[T]] + _validator: RefValidator[T] | None _watches: IPersistentMap[RefWatchKey, RefWatcher[T]] def add_watch(self, k: RefWatchKey, wf: RefWatcher[T]) -> "RefBase[T]": @@ -76,16 +78,16 @@ def remove_watch(self, k: RefWatchKey) -> "RefBase[T]": self._watches = self._watches.dissoc(k) return self - 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: if vf is not None: self._validate(self.deref(), vf=vf) self._validator = vf - 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 if vf is not None: try: diff --git a/src/basilisp/lang/runtime.py b/src/basilisp/lang/runtime.py index 773e33aca..1258a1033 100644 --- a/src/basilisp/lang/runtime.py +++ b/src/basilisp/lang/runtime.py @@ -19,7 +19,8 @@ import types from collections.abc import Iterable, Iterator, Mapping, Sequence, Sized from fractions import Fraction -from typing import AbstractSet, Any, Callable, NoReturn, Optional, TypeVar, Union, cast +from typing import AbstractSet, Any, NoReturn, Optional, TypeVar, Union, cast +from collections.abc import Callable import attr @@ -245,7 +246,7 @@ def __init__( ns: "Namespace", name: sym.Symbol, dynamic: bool = False, - meta: Optional[IPersistentMap] = None, + meta: IPersistentMap | None = None, ) -> None: self._ns = ns self._name = name @@ -296,7 +297,7 @@ def set_dynamic(self, dynamic: bool) -> None: self._tl = _VarBindings() if dynamic else None @property - def is_private(self) -> Optional[bool]: + def is_private(self) -> bool | None: if self._meta is not None: return self._meta.val_at(_PRIVATE_META_KEY) return False @@ -388,7 +389,7 @@ def intern( # pylint: disable=too-many-arguments name: sym.Symbol, val, dynamic: bool = False, - meta: Optional[IPersistentMap] = None, + meta: IPersistentMap | None = None, ) -> "Var": """Intern the value bound to the symbol `name` in namespace `ns`. @@ -415,7 +416,7 @@ def intern_unbound( ns: Union["Namespace", sym.Symbol], name: sym.Symbol, dynamic: bool = False, - meta: Optional[IPersistentMap] = None, + meta: IPersistentMap | None = None, ) -> "Var": """Create a new unbound `Var` instance to the symbol `name` in namespace `ns`.""" return cls.intern(ns, name, cls.__UNBOUND_SENTINEL, dynamic=dynamic, meta=meta) @@ -592,12 +593,12 @@ class Namespace(ReferenceBase): ) def __init__( - self, name: sym.Symbol, module: Optional[BasilispModule] = None + self, name: sym.Symbol, module: BasilispModule | None = None ) -> None: self._name = name self._module = Maybe(module).or_else(lambda: _new_module(name.as_python_sym())) - self._meta: Optional[IPersistentMap] = None + self._meta: IPersistentMap | None = None self._lock = threading.RLock() self._aliases: NamespaceMap = lmap.EMPTY @@ -776,7 +777,7 @@ def unmap(self, sym: sym.Symbol) -> None: with self._lock: self._interns = self._interns.dissoc(sym) - def find(self, sym: sym.Symbol) -> Optional[Var]: + def find(self, sym: sym.Symbol) -> Var | None: """Find Vars mapped by the given Symbol input or None if no Vars are mapped by that Symbol.""" with self._lock: @@ -790,7 +791,7 @@ def add_import( sym: sym.Symbol, module: Module, *aliases: sym.Symbol, - refers: Optional[dict[sym.Symbol, Any]] = None, + refers: dict[sym.Symbol, Any] | None = None, ) -> None: """Add the Symbol as an imported Symbol in this Namespace. @@ -817,14 +818,14 @@ def add_import( m = m.assoc(alias, sym) self._import_aliases = m - def get_import_refer(self, sym: sym.Symbol) -> Optional[sym.Symbol]: + def get_import_refer(self, sym: sym.Symbol) -> sym.Symbol | None: """Get the Python module member name referred by Symbol or None if it does not exist.""" with self._lock: refer = self._import_refers.val_at(sym, None) return refer.module_name if refer is not None else None - def get_import(self, sym: sym.Symbol) -> Optional[BasilispModule]: + def get_import(self, sym: sym.Symbol) -> BasilispModule | None: """Return the module if a module named by sym has been imported into this Namespace, None otherwise. @@ -845,7 +846,7 @@ def add_refer(self, sym: sym.Symbol, var: Var) -> None: with self._lock: self._refers = self._refers.assoc(sym, var) - def get_refer(self, sym: sym.Symbol) -> Optional[Var]: + def get_refer(self, sym: sym.Symbol) -> Var | None: """Get the Var referred by Symbol or None if it does not exist.""" with self._lock: return self._refers.val_at(sym, None) @@ -868,7 +869,7 @@ def ns_cache(cls) -> lmap.PersistentMap: def __get_or_create( ns_cache: NamespaceMap, name: sym.Symbol, - module: Optional[BasilispModule] = None, + module: BasilispModule | None = None, ) -> lmap.PersistentMap: """Private swap function used by `get_or_create` to atomically swap the new namespace map into the global cache.""" @@ -893,7 +894,7 @@ def __get_or_create( @classmethod def get_or_create( - cls, name: sym.Symbol, module: Optional[BasilispModule] = None + cls, name: sym.Symbol, module: BasilispModule | None = None ) -> "Namespace": """Get the namespace bound to the symbol `name` in the global namespace cache, creating it if it does not exist. @@ -923,7 +924,7 @@ def remove(cls, name: sym.Symbol) -> Optional["Namespace"]: raise ValueError("Cannot remove the Basilisp core namespace") while True: oldval: lmap.PersistentMap = cls._NAMESPACES.deref() - ns: Optional[Namespace] = oldval.val_at(name, None) + ns: Namespace | None = oldval.val_at(name, None) newval = oldval if ns is not None: newval = oldval.dissoc(name) @@ -943,7 +944,7 @@ def is_match(entry: tuple[sym.Symbol, Any]) -> bool: return is_match def __complete_alias( - self, prefix: str, name_in_ns: Optional[str] = None + self, prefix: str, name_in_ns: str | None = None ) -> Iterable[str]: """Return an iterable of possible completions matching the given prefix from the list of aliased namespaces. If name_in_ns is given, @@ -963,7 +964,7 @@ def __complete_alias( yield f"{alias}/" def __complete_imports_and_aliases( - self, prefix: str, name_in_module: Optional[str] = None + self, prefix: str, name_in_module: str | None = None ) -> Iterable[str]: """Return an iterable of possible completions matching the given prefix from the list of imports and aliased imports. If name_in_module @@ -1208,7 +1209,7 @@ def _first_none(_: None) -> None: @first.register(ISeq) -def _first_iseq(o: ISeq[T]) -> Optional[T]: +def _first_iseq(o: ISeq[T]) -> T | None: return o.first @@ -1246,13 +1247,13 @@ def nthrest(coll, i: int): coll = rest(coll) -def next_(o) -> Optional[ISeq]: +def next_(o) -> ISeq | None: """Calls rest on o. If o returns an empty sequence or None, returns None. Otherwise, returns the elements after the first in o.""" return to_seq(rest(o)) -def nthnext(coll, i: int) -> Optional[ISeq]: +def nthnext(coll, i: int) -> ISeq | None: """Returns the nth next sequence of coll.""" while True: if coll is None: @@ -1309,7 +1310,7 @@ def concat(*seqs: Any) -> ISeq: def internal_reduce( coll: Any, f: ReduceFunction, - init: Union[T_reduce_init, object] = IReduce.REDUCE_SENTINEL, + init: T_reduce_init | object = IReduce.REDUCE_SENTINEL, ) -> T_reduce_init: raise TypeError(f"Type {type(coll)} cannot be reduced") @@ -1317,9 +1318,9 @@ def internal_reduce( @internal_reduce.register(collections.abc.Iterable) @internal_reduce.register(type(None)) def _internal_reduce_iterable( - coll: Optional[Iterable[T]], + coll: Iterable[T] | None, f: ReduceFunction[T_reduce_init, T], - init: Union[T_reduce_init, object] = IReduce.REDUCE_SENTINEL, + init: T_reduce_init | object = IReduce.REDUCE_SENTINEL, ) -> T_reduce_init: s = to_seq(coll) @@ -1345,7 +1346,7 @@ def _internal_reduce_iterable( def _internal_reduce_ireduce( coll: IReduce, f: ReduceFunction[T_reduce_init, T], - init: Union[T_reduce_init, object] = IReduce.REDUCE_SENTINEL, + init: T_reduce_init | object = IReduce.REDUCE_SENTINEL, ) -> T_reduce_init: if init is IReduce.REDUCE_SENTINEL: return coll.reduce(f) @@ -1566,13 +1567,13 @@ def _keys_none(_: None) -> None: @keys.register(collections.abc.Iterable) @keys.register(ISeqable) -def _keys_iterable(o: Union[ISeqable, Iterable]) -> Optional[ISeq]: +def _keys_iterable(o: ISeqable | Iterable) -> ISeq | None: return keys(to_seq(o)) @keys.register(ISeq) -def _keys_iseq(o: ISeq) -> Optional[ISeq]: - def _key_seq(s: ISeq) -> Optional[ISeq]: +def _keys_iseq(o: ISeq) -> ISeq | None: + def _key_seq(s: ISeq) -> ISeq | None: if to_seq(s) is not None: e = s.first if not isinstance(e, IMapEntry): @@ -1586,7 +1587,7 @@ def _key_seq(s: ISeq) -> Optional[ISeq]: @keys.register(collections.abc.Mapping) -def _keys_mapping(o: Mapping) -> Optional[ISeq]: +def _keys_mapping(o: Mapping) -> ISeq | None: return to_seq(o.keys()) @@ -1602,13 +1603,13 @@ def _vals_none(_: None) -> None: @keys.register(collections.abc.Iterable) @vals.register(ISeqable) -def _vals_iterable(o: Union[ISeqable, Iterable]) -> Optional[ISeq]: +def _vals_iterable(o: ISeqable | Iterable) -> ISeq | None: return vals(to_seq(o)) @vals.register(ISeq) -def _vals_iseq(o: ISeq) -> Optional[ISeq]: - def _val_seq(s: ISeq) -> Optional[ISeq]: +def _vals_iseq(o: ISeq) -> ISeq | None: + def _val_seq(s: ISeq) -> ISeq | None: if to_seq(s) is not None: e = s.first if not isinstance(e, IMapEntry): @@ -1622,7 +1623,7 @@ def _val_seq(s: ISeq) -> Optional[ISeq]: @vals.register(collections.abc.Mapping) -def _vals_mapping(o: Mapping) -> Optional[ISeq]: +def _vals_mapping(o: Mapping) -> ISeq | None: return to_seq(o.values()) @@ -1658,8 +1659,8 @@ def _update_signature_for_partial(f: BasilispFunction, num_args: int) -> None: Additionally, partials do not take the meta from the wrapped function, so that value should be cleared and the `with-meta` method should be replaced with a new method.""" - existing_arities: IPersistentSet[Union[kw.Keyword, int]] = f.arities - new_arities: set[Union[kw.Keyword, int]] = set() + existing_arities: IPersistentSet[kw.Keyword | int] = f.arities + new_arities: set[kw.Keyword | int] = set() for arity in existing_arities: if isinstance(arity, kw.Keyword): new_arities.add(arity) @@ -1705,7 +1706,7 @@ def deref(o, timeout_ms=None, timeout_val=None): @deref.register(IBlockingDeref) def _deref_blocking( - o: IBlockingDeref, timeout_ms: Optional[int] = None, timeout_val=None + o: IBlockingDeref, timeout_ms: int | None = None, timeout_val=None ): timeout_s = None if timeout_ms is not None: @@ -1812,7 +1813,7 @@ def cmp(x, y): return cmp -def sort(coll, f=compare) -> Optional[ISeq]: +def sort(coll, f=compare) -> ISeq | None: """Return a sorted sequence of the elements in coll. If a comparator function f is provided, compare elements in coll using f or use the `compare` fn if not. @@ -1853,7 +1854,7 @@ def __ge__(self, other): return llist.EMPTY -def sort_by(keyfn, coll, cmp=compare) -> Optional[ISeq]: +def sort_by(keyfn, coll, cmp=compare) -> ISeq | None: """Return a sorted sequence of the elements in coll. If a comparator function cmp is provided, compare elements in coll using cmp or use the `compare` fn if not. @@ -1963,7 +1964,7 @@ def _to_py_kw(o: kw.Keyword, keyword_fn: Callable[[kw.Keyword], Any] = _kw_name) @to_py.register(ISeq) @to_py.register(IPersistentVector) def _to_py_list( - o: Union[IPersistentList, ISeq, IPersistentVector], + o: IPersistentList | ISeq | IPersistentVector, keyword_fn: Callable[[kw.Keyword], Any] = _kw_name, ) -> list: return list(map(functools.partial(to_py, keyword_fn=keyword_fn), o)) @@ -2134,7 +2135,7 @@ def decorator(f): return decorator -def _fn_with_meta(f, meta: Optional[lmap.PersistentMap]): +def _fn_with_meta(f, meta: lmap.PersistentMap | None): """Return a new function with the given meta. If the function f already has a meta map, then merge the new meta with the existing meta.""" @@ -2163,7 +2164,7 @@ def wrapped_f(*args, **kwargs): def _basilisp_fn( - arities: tuple[Union[int, kw.Keyword], ...], + arities: tuple[int | kw.Keyword, ...], ) -> Callable[..., BasilispFunction]: """Create a Basilisp function, setting meta and supplying a with_meta method implementation.""" @@ -2269,7 +2270,7 @@ def _load_constant(s: bytes) -> Any: ############################### -def resolve_alias(s: sym.Symbol, ns: Optional[Namespace] = None) -> sym.Symbol: +def resolve_alias(s: sym.Symbol, ns: Namespace | None = None) -> sym.Symbol: """Resolve the aliased symbol in the current namespace.""" if s in _SPECIAL_FORMS: return s @@ -2289,7 +2290,7 @@ def resolve_alias(s: sym.Symbol, ns: Optional[Namespace] = None) -> sym.Symbol: return sym.symbol(s.name, ns=ns.name) -def resolve_var(s: sym.Symbol, ns: Optional[Namespace] = None) -> Optional[Var]: +def resolve_var(s: sym.Symbol, ns: Namespace | None = None) -> Var | None: """Resolve the aliased symbol to a Var from the specified namespace, or the current namespace if none is specified.""" ns_qualified_sym = resolve_alias(s, ns) @@ -2302,7 +2303,7 @@ def resolve_var(s: sym.Symbol, ns: Optional[Namespace] = None) -> Optional[Var]: @contextlib.contextmanager -def bindings(bindings: Optional[Mapping[Var, Any]] = None): +def bindings(bindings: Mapping[Var, Any] | None = None): """Context manager for temporarily changing the value thread-local value for Basilisp dynamic Vars.""" m = lmap.map(bindings or {}) @@ -2321,7 +2322,7 @@ def bindings(bindings: Optional[Mapping[Var, Any]] = None): @contextlib.contextmanager def ns_bindings( - ns_name: str, module: Optional[BasilispModule] = None + ns_name: str, module: BasilispModule | None = None ) -> Iterator[Namespace]: """Context manager for temporarily changing the value of basilisp.core/*ns*.""" symbol = sym.symbol(ns_name) @@ -2360,7 +2361,7 @@ def get_current_ns() -> Namespace: def set_current_ns( ns_name: str, - module: Optional[BasilispModule] = None, + module: BasilispModule | None = None, ) -> Var: """Set the value of the dynamic variable `*ns*` in the current thread.""" symbol = sym.symbol(ns_name) @@ -2380,7 +2381,7 @@ def set_current_ns( def add_generated_python( generated_python: str, - which_ns: Optional[Namespace] = None, + which_ns: Namespace | None = None, ) -> None: """Add generated Python code to a dynamic variable in which_ns.""" if which_ns is None: diff --git a/src/basilisp/lang/seq.py b/src/basilisp/lang/seq.py index 463c3f573..824053e46 100644 --- a/src/basilisp/lang/seq.py +++ b/src/basilisp/lang/seq.py @@ -1,7 +1,8 @@ import functools import threading from collections.abc import Iterable -from typing import Callable, Optional, TypeVar, overload +from typing import Optional, TypeVar, overload +from collections.abc import Callable from basilisp.lang.interfaces import ( IPersistentMap, @@ -18,7 +19,7 @@ class _EmptySequence(IWithMeta, ISequential, ISeq[T]): __slots__ = ("_meta",) - def __init__(self, meta: Optional[IPersistentMap] = None): + def __init__(self, meta: IPersistentMap | None = None): self._meta = meta def __repr__(self): @@ -27,14 +28,14 @@ def __repr__(self): def __bool__(self): return True - 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) @property @@ -42,7 +43,7 @@ def is_empty(self) -> bool: return True @property - def first(self) -> Optional[T]: + def first(self) -> T | None: return None @property @@ -68,8 +69,8 @@ class Cons(ISeq[T], ISequential, IWithMeta): def __init__( self, first: T, - seq: Optional[ISeq[T]] = None, - meta: Optional[IPersistentMap] = None, + seq: ISeq[T] | None = None, + meta: IPersistentMap | None = None, ) -> None: self._first = first self._rest = Maybe(seq).or_else_get(EMPTY) @@ -80,7 +81,7 @@ def is_empty(self) -> bool: return False @property - def first(self) -> Optional[T]: + def first(self) -> T | None: return self._first @property @@ -97,10 +98,10 @@ def empty(self): return EMPTY @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) @@ -119,22 +120,22 @@ class LazySeq(IWithMeta, ISequential, ISeq[T]): def __init__( 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() 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) # LazySeqs have a fairly complex inner state, in spite of the simple interface. @@ -146,7 +147,7 @@ def with_meta(self, meta: Optional[IPersistentMap]) -> "LazySeq[T]": # LazySeq objects before calling `(seq ...)` on the result, which is cached in the # _seq attribute. - def _compute_seq(self) -> Optional[ISeq[T]]: + def _compute_seq(self) -> ISeq[T] | None: if self._gen is not None: # This local caching of the generator function and clearing of self._gen # is absolutely critical for supporting co-recursive lazy sequences. @@ -168,7 +169,7 @@ def _compute_seq(self) -> Optional[ISeq[T]]: self._obj = gen() return self._obj if self._obj is not None else self._seq - def seq(self) -> Optional[ISeq[T]]: + def seq(self) -> ISeq[T] | None: with self._lock: self._compute_seq() if self._obj is not None: @@ -192,7 +193,7 @@ def is_empty(self) -> bool: return self.seq() is None @property - def first(self) -> Optional[T]: + def first(self) -> T | None: if self.is_empty: return None return self.seq().first # type: ignore[union-attr] @@ -253,7 +254,7 @@ def _seq_or_nil(s: None) -> None: ... @overload -def _seq_or_nil(s: ISeq) -> Optional[ISeq]: ... +def _seq_or_nil(s: ISeq) -> ISeq | None: ... def _seq_or_nil(s): @@ -264,7 +265,7 @@ def _seq_or_nil(s): @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.""" return _seq_or_nil(sequence(o)) @@ -275,16 +276,16 @@ def _to_seq_none(_) -> None: @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) @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. 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()) diff --git a/src/basilisp/lang/set.py b/src/basilisp/lang/set.py index 8029d5b0d..e9f5b96f6 100644 --- a/src/basilisp/lang/set.py +++ b/src/basilisp/lang/set.py @@ -75,13 +75,13 @@ class PersistentSet( __slots__ = ("_inner", "_meta") - 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 self._meta = meta @classmethod def from_iterable( - cls, members: Optional[Iterable[T]], meta: Optional[IPersistentMap] = None + cls, members: Iterable[T] | None, meta: IPersistentMap | None = None ) -> "PersistentSet": return PersistentSet(_Map((m, m) for m in (members or ())), meta=meta) @@ -145,10 +145,10 @@ def union(self, *others): return e @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) def cons(self, *elems: T) -> "PersistentSet[T]": # type: ignore[return] @@ -169,7 +169,7 @@ def disj(self, *elems: T) -> "PersistentSet[T]": # type: ignore[return] def empty(self) -> "PersistentSet": return EMPTY.with_meta(self._meta) - def seq(self) -> Optional[ISeq[T]]: + def seq(self) -> ISeq[T] | None: if len(self._inner) == 0: return None return sequence(self) @@ -182,12 +182,12 @@ def to_transient(self) -> TransientSet: def set( # pylint:disable=redefined-builtin - members: Iterable[T], meta: Optional[IPersistentMap] = None + members: Iterable[T], meta: IPersistentMap | None = None ) -> PersistentSet[T]: """Creates a new set.""" return PersistentSet.from_iterable(members, meta=meta) -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) diff --git a/src/basilisp/lang/source.py b/src/basilisp/lang/source.py index 0de16136f..be8fd9c44 100644 --- a/src/basilisp/lang/source.py +++ b/src/basilisp/lang/source.py @@ -11,15 +11,15 @@ except ImportError: # pragma: no cover 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: return f"{s}{os.linesep}" else: 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 inspecting various environment variables set by terminals. @@ -37,7 +37,7 @@ def _get_formatter_name( return "terminal" def _format_source( - s: str, disable_color: Optional[bool] = None + s: str, disable_color: bool | None = None ) -> str: # pragma: no cover """Format source code for terminal output. @@ -56,10 +56,10 @@ def _format_source( def format_source_context( # pylint: disable=too-many-arguments,too-many-locals filename: str, 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]: """Format source code context with line numbers and identifiers for the affected line(s). @@ -71,7 +71,7 @@ def format_source_context( # pylint: disable=too-many-arguments,too-many-locals lines = [] if not filename.startswith("<") and not filename.endswith(">"): - cause_range: Optional[range] + cause_range: range | None if not show_cause_marker: cause_range = None elif end_line is not None and end_line != line: diff --git a/src/basilisp/lang/symbol.py b/src/basilisp/lang/symbol.py index 8dfe0223f..873e4fbd6 100644 --- a/src/basilisp/lang/symbol.py +++ b/src/basilisp/lang/symbol.py @@ -20,7 +20,7 @@ class Symbol(ILispObject, INamed, IWithMeta): __slots__ = ("_name", "_ns", "_meta", "_hash") 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: self._name = name self._ns = ns @@ -44,18 +44,18 @@ def name(self) -> str: return self._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) def as_python_sym(self) -> str: @@ -84,7 +84,7 @@ def __lt__(self, other): return False return self._ns < other._ns or self._name < other._name - def __call__(self, m: Union[IAssociative, IPersistentSet], default=None): + def __call__(self, m: IAssociative | IPersistentSet, default=None): if isinstance(m, IPersistentSet): return self if self in m else default try: @@ -94,7 +94,7 @@ def __call__(self, m: Union[IAssociative, IPersistentSet], default=None): 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) diff --git a/src/basilisp/lang/tagged.py b/src/basilisp/lang/tagged.py index 9237368e3..8a772a345 100644 --- a/src/basilisp/lang/tagged.py +++ b/src/basilisp/lang/tagged.py @@ -23,7 +23,7 @@ class TaggedLiteral(ILispObject, ILookup[K, T]): def __init__(self, tag: Symbol, form) -> None: self._tag = tag self._form = form - self._hash: Optional[int] = None + self._hash: int | None = None @property def tag(self) -> Symbol: @@ -51,7 +51,7 @@ def __hash__(self): def __getitem__(self, item): return self.val_at(item) - 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: return self._tag elif k == _FORM_KW: diff --git a/src/basilisp/lang/typing.py b/src/basilisp/lang/typing.py index ab1629e23..ce46af5ad 100644 --- a/src/basilisp/lang/typing.py +++ b/src/basilisp/lang/typing.py @@ -55,9 +55,9 @@ 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": ... diff --git a/src/basilisp/lang/vector.py b/src/basilisp/lang/vector.py index 45ca65c07..e8c2c3e0c 100644 --- a/src/basilisp/lang/vector.py +++ b/src/basilisp/lang/vector.py @@ -64,7 +64,7 @@ def assoc_transient(self, *kvs: T) -> "TransientVector[T]": def contains_transient(self, k: int) -> bool: return 0 <= k < len(self._inner) - def entry_transient(self, k: int) -> Optional[IMapEntry[int, T]]: + def entry_transient(self, k: int) -> IMapEntry[int, T] | None: try: return MapEntry.of(k, self._inner[k]) except IndexError: @@ -102,7 +102,7 @@ class PersistentVector( __slots__ = ("_inner", "_meta") def __init__( - self, wrapped: "PVector[T]", meta: Optional[IPersistentMap] = None + self, wrapped: "PVector[T]", meta: IPersistentMap | None = None ) -> None: self._inner = wrapped self._meta = meta @@ -134,7 +134,7 @@ def __iter__(self): def __len__(self): return len(self._inner) - def __call__(self, k: int, default: Optional[T] = None) -> Optional[T]: + def __call__(self, k: int, default: T | None = None) -> T | None: return self.val_at(k, default=default) def __lt__(self, other): @@ -164,10 +164,10 @@ def _lrepr(self, **kwargs: Unpack[PrintSettings]) -> str: return _seq_lrepr(self._inner, "[", "]", meta=self._meta, **kwargs) @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) def cons(self, *elems: T) -> "PersistentVector[T]": # type: ignore[override] @@ -182,13 +182,13 @@ def assoc(self, *kvs: T) -> "PersistentVector[T]": def contains(self, k: int) -> bool: 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: return MapEntry.of(k, self._inner[k]) except IndexError: return None - 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: return self._inner[k] except (IndexError, TypeError): @@ -197,12 +197,12 @@ def val_at(self, k: int, default: Optional[T] = None) -> Optional[T]: def empty(self) -> "PersistentVector[T]": return EMPTY.with_meta(self._meta) - def seq(self) -> Optional[ISeq[T]]: # type: ignore[override] + def seq(self) -> ISeq[T] | None: # type: ignore[override] if len(self._inner) == 0: return None return sequence(self) - def peek(self) -> Optional[T]: + def peek(self) -> T | None: if len(self) == 0: return None return self[-1] @@ -280,7 +280,7 @@ def of(k: K, v: V) -> "MapEntry[K, V]": return MapEntry(pvector([k, v])) @staticmethod - def from_vec(v: Sequence[Union[K, V]]) -> "MapEntry[K, V]": + def from_vec(v: Sequence[K | V]) -> "MapEntry[K, V]": return MapEntry(pvector(v)) @@ -288,12 +288,12 @@ def from_vec(v: Sequence[Union[K, V]]) -> "MapEntry[K, V]": def vector( - members: Iterable[T], meta: Optional[IPersistentMap] = None + members: Iterable[T], meta: IPersistentMap | None = None ) -> PersistentVector[T]: """Creates a new vector.""" return PersistentVector(pvector(members), meta=meta) -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) diff --git a/src/basilisp/lang/volatile.py b/src/basilisp/lang/volatile.py index 858abfba6..1993c5920 100644 --- a/src/basilisp/lang/volatile.py +++ b/src/basilisp/lang/volatile.py @@ -1,7 +1,9 @@ -from typing import Callable, Optional, TypeVar +from typing import Optional, TypeVar +from collections.abc import Callable import attr -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import ParamSpec +from typing import Concatenate from basilisp.lang.interfaces import IDeref @@ -17,7 +19,7 @@ class Volatile(IDeref[T]): value: T - def deref(self) -> Optional[T]: + def deref(self) -> T | None: return self.value def reset(self, v: T) -> T: diff --git a/src/basilisp/logconfig.py b/src/basilisp/logconfig.py index 8b6350dd9..2262d35dc 100644 --- a/src/basilisp/logconfig.py +++ b/src/basilisp/logconfig.py @@ -18,7 +18,7 @@ def get_level() -> str: def get_handler( - level: Optional[str] = None, fmt: str = DEFAULT_FORMAT + level: str | None = None, fmt: str = DEFAULT_FORMAT ) -> logging.Handler: """Get the default logging handler for Basilisp.""" handler = ( @@ -32,7 +32,7 @@ def get_handler( def configure_root_logger( - level: Optional[str] = None, fmt: str = DEFAULT_FORMAT + level: str | None = None, fmt: str = DEFAULT_FORMAT ) -> None: """Configure the Basilisp root logger.""" level = level or get_level() diff --git a/src/basilisp/main.py b/src/basilisp/main.py index 542d8560d..8be9afe09 100644 --- a/src/basilisp/main.py +++ b/src/basilisp/main.py @@ -16,7 +16,7 @@ _runtime_is_initialized = False -def init(opts: Optional[CompilerOpts] = None, force_reload: bool = False) -> None: +def init(opts: CompilerOpts | None = None, force_reload: bool = False) -> None: """ Initialize the runtime environment for Basilisp code evaluation. @@ -45,7 +45,7 @@ def init(opts: Optional[CompilerOpts] = None, force_reload: bool = False) -> Non def bootstrap( - target: str, opts: Optional[CompilerOpts] = None + target: str, opts: CompilerOpts | None = None ) -> None: # pragma: no cover """ Import a Basilisp namespace or function identified by ``target``. If a function @@ -71,7 +71,7 @@ def bootstrap( getattr(mod, fn_name)() -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 in ``site-packages`` directory (corresponding to "purelib" in :external:py:func:`sysconfig.get_paths`). Returns the path to the @@ -91,7 +91,7 @@ def bootstrap_python(site_packages: Optional[str] = None) -> str: return str(pth) -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 directory (corresponding to "purelib" in :external:py:func:`sysconfig.get_paths`). Return the path of the removed file, if any.""" diff --git a/src/basilisp/util.py b/src/basilisp/util.py index 7710321ef..36d8b3064 100644 --- a/src/basilisp/util.py +++ b/src/basilisp/util.py @@ -1,11 +1,12 @@ import contextlib import time from collections.abc import Iterable, Sequence -from typing import Callable, Generic, Optional, TypeVar +from typing import Generic, Optional, TypeVar +from collections.abc import Callable @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 f (if it is given) with the resulting time in nanoseconds.""" start = time.perf_counter() @@ -23,7 +24,7 @@ def timed(f: Optional[Callable[[int], None]] = None): class Maybe(Generic[T]): __slots__ = ("_inner",) - def __init__(self, inner: Optional[T]) -> None: + def __init__(self, inner: T | None) -> None: self._inner = inner def __eq__(self, other): @@ -58,7 +59,7 @@ def map(self, f: Callable[[T], U]) -> "Maybe[U]": return Maybe(f(self._inner)) @property - def value(self) -> Optional[T]: + def value(self) -> T | None: return self._inner @property diff --git a/tests/basilisp/cli_test.py b/tests/basilisp/cli_test.py index 53a04bf99..59df3fd09 100644 --- a/tests/basilisp/cli_test.py +++ b/tests/basilisp/cli_test.py @@ -82,7 +82,7 @@ class CapturedIO: @pytest.fixture def run_cli(monkeypatch, capsys, cap_lisp_io): - def _run_cli(args: Sequence[str], input: Optional[str] = None): + def _run_cli(args: Sequence[str], input: str | None = None): monkeypatch.setattr("basilisp.main._runtime_is_initialized", False) if input is not None: monkeypatch.setattr( diff --git a/tests/basilisp/compiler_test.py b/tests/basilisp/compiler_test.py index be2b8d56f..bd6a848d6 100644 --- a/tests/basilisp/compiler_test.py +++ b/tests/basilisp/compiler_test.py @@ -75,9 +75,9 @@ def _assert_no_logs() -> None: @pytest.fixture def assert_matching_logs( caplog, -) -> typing.Callable[[str, int, typing.Union[typing.Pattern, str]], None]: +) -> typing.Callable[[str, int, typing.Pattern | str], None]: def _assert_matching_logs( - logger_name: str, log_level: int, pattern: typing.Union[typing.Pattern, str] + logger_name: str, log_level: int, pattern: typing.Pattern | str ) -> None: if isinstance(pattern, str): pattern = re.compile(pattern) @@ -106,9 +106,9 @@ def _assert_matching_logs( @pytest.fixture def assert_no_matching_logs( caplog, -) -> typing.Callable[[str, int, typing.Union[typing.Pattern, str]], None]: +) -> typing.Callable[[str, int, typing.Pattern | str], None]: def _assert_no_matching_logs( - logger_name: str, log_level: int, pattern: typing.Union[typing.Pattern, str] + logger_name: str, log_level: int, pattern: typing.Pattern | str ) -> None: if isinstance(pattern, str): pattern = re.compile(pattern) diff --git a/tests/basilisp/conftest.py b/tests/basilisp/conftest.py index b1bc6ecab..ef4ca903c 100644 --- a/tests/basilisp/conftest.py +++ b/tests/basilisp/conftest.py @@ -48,8 +48,8 @@ def ns(test_ns: str, test_ns_sym: sym.Symbol) -> runtime.Namespace: def lcompile(ns: runtime.Namespace, compiler_file_path: str) -> CompileFn: def _lcompile( s: str, - resolver: Optional[reader.Resolver] = None, - opts: Optional[dict[str, bool]] = None, + resolver: reader.Resolver | None = None, + opts: dict[str, bool] | None = None, ): """Compile and execute the code in the input string. diff --git a/tests/basilisp/helpers.py b/tests/basilisp/helpers.py index 77743cc18..9a0ddfead 100644 --- a/tests/basilisp/helpers.py +++ b/tests/basilisp/helpers.py @@ -1,4 +1,5 @@ -from typing import Any, Callable, Tuple +from typing import Any, Tuple +from collections.abc import Callable from basilisp.lang import symbol as sym from basilisp.lang.runtime import CORE_NS_SYM, Namespace diff --git a/tests/basilisp/importer_test.py b/tests/basilisp/importer_test.py index ec87e3372..6af25e134 100644 --- a/tests/basilisp/importer_test.py +++ b/tests/basilisp/importer_test.py @@ -119,7 +119,7 @@ def make_new_module(self, module_dir): filenames = set() def _make_new_module( - *ns_path: str, ns_name: str = "", module_text: Optional[str] = None + *ns_path: str, ns_name: str = "", module_text: str | None = None ) -> None: """Generate a new module. If ns_name is not the empty string, use that name as the name of a Basilisp namespace with a single Var named `val` diff --git a/tests/basilisp/prompt_test.py b/tests/basilisp/prompt_test.py index 782b1fbda..5fb8e5545 100644 --- a/tests/basilisp/prompt_test.py +++ b/tests/basilisp/prompt_test.py @@ -1,5 +1,5 @@ from collections.abc import Iterable -from typing import Callable +from collections.abc import Callable from unittest.mock import MagicMock, patch import pytest diff --git a/tests/basilisp/reader_test.py b/tests/basilisp/reader_test.py index fff7b7931..a4bcd57cc 100644 --- a/tests/basilisp/reader_test.py +++ b/tests/basilisp/reader_test.py @@ -37,7 +37,7 @@ def read_str_first( resolver: reader.Resolver = None, data_readers=None, is_eof_error: bool = False, - features: Optional[IPersistentSet[kw.Keyword]] = None, + features: IPersistentSet[kw.Keyword] | None = None, process_reader_cond: bool = True, default_data_reader_fn=None, ): From 7326ab24b3d5c302c1df1fdce6e30b3d689715e1 Mon Sep 17 00:00:00 2001 From: Chris Rink Date: Wed, 29 Oct 2025 08:08:46 -0400 Subject: [PATCH 2/3] Formatting --- src/basilisp/cli.py | 3 +-- src/basilisp/contrib/pytest/testrunner.py | 3 +-- src/basilisp/lang/atom.py | 3 +-- src/basilisp/lang/compiler/__init__.py | 3 +-- src/basilisp/lang/compiler/analyzer.py | 9 +++------ src/basilisp/lang/compiler/generator.py | 6 ++---- src/basilisp/lang/compiler/nodes.py | 3 +-- src/basilisp/lang/delay.py | 2 +- src/basilisp/lang/futures.py | 2 +- src/basilisp/lang/interfaces.py | 11 +++++++++-- src/basilisp/lang/map.py | 19 +++++++++---------- src/basilisp/lang/multifn.py | 2 +- src/basilisp/lang/reader.py | 7 ++----- src/basilisp/lang/reference.py | 3 +-- src/basilisp/lang/runtime.py | 11 +++-------- src/basilisp/lang/seq.py | 3 +-- src/basilisp/lang/volatile.py | 3 +-- src/basilisp/logconfig.py | 8 ++------ src/basilisp/util.py | 3 +-- tests/basilisp/helpers.py | 2 +- tests/basilisp/prompt_test.py | 3 +-- 21 files changed, 44 insertions(+), 65 deletions(-) diff --git a/src/basilisp/cli.py b/src/basilisp/cli.py index 2a7ddfea4..1ca14602e 100644 --- a/src/basilisp/cli.py +++ b/src/basilisp/cli.py @@ -6,10 +6,9 @@ import sys import textwrap import types -from collections.abc import Sequence +from collections.abc import Callable, Sequence from pathlib import Path from typing import Any, Optional, Union -from collections.abc import Callable from basilisp import main as basilisp from basilisp.lang import compiler as compiler diff --git a/src/basilisp/contrib/pytest/testrunner.py b/src/basilisp/contrib/pytest/testrunner.py index bb7a24dd3..fdf44dd31 100644 --- a/src/basilisp/contrib/pytest/testrunner.py +++ b/src/basilisp/contrib/pytest/testrunner.py @@ -3,11 +3,10 @@ import os import sys import traceback -from collections.abc import Iterable, Iterator +from collections.abc import Callable, Iterable, Iterator from pathlib import Path from types import GeneratorType from typing import Optional -from collections.abc import Callable import pytest diff --git a/src/basilisp/lang/atom.py b/src/basilisp/lang/atom.py index 41405015b..aad4e764a 100644 --- a/src/basilisp/lang/atom.py +++ b/src/basilisp/lang/atom.py @@ -1,9 +1,8 @@ import threading -from typing import Generic, Optional, TypeVar from collections.abc import Callable +from typing import Concatenate, Generic, Optional, TypeVar from typing_extensions import ParamSpec -from typing import Concatenate from basilisp.lang import map as lmap from basilisp.lang.interfaces import IPersistentMap, RefValidator diff --git a/src/basilisp/lang/compiler/__init__.py b/src/basilisp/lang/compiler/__init__.py index 74f93d9fe..0dbd7393a 100644 --- a/src/basilisp/lang/compiler/__init__.py +++ b/src/basilisp/lang/compiler/__init__.py @@ -3,10 +3,9 @@ import os import types from ast import unparse -from collections.abc import Iterable +from collections.abc import Callable, Iterable from pathlib import Path from typing import Any, Optional -from collections.abc import Callable from basilisp.lang import list as llist from basilisp.lang import map as lmap diff --git a/src/basilisp/lang/compiler/analyzer.py b/src/basilisp/lang/compiler/analyzer.py index 30fcd6864..7e8efb9b5 100644 --- a/src/basilisp/lang/compiler/analyzer.py +++ b/src/basilisp/lang/compiler/analyzer.py @@ -11,6 +11,7 @@ import uuid from collections import defaultdict from collections.abc import ( + Callable, Collection, Iterable, Iterator, @@ -23,11 +24,9 @@ from fractions import Fraction from functools import partial, wraps from re import Pattern -from typing import Any, Optional, TypeVar, Union, cast -from collections.abc import Callable +from typing import Any, Literal, Optional, TypeVar, Union, cast import attr -from typing import Literal from basilisp.lang import keyword as kw from basilisp.lang import list as llist @@ -2727,9 +2726,7 @@ def _do_warn_on_arity_mismatch( fn: VarRef, form: llist.PersistentList | ISeq, ctx: AnalyzerContext ) -> None: if ctx.warn_on_arity_mismatch and getattr(fn.var.value, "_basilisp_fn", False): - arities: tuple[int | kw.Keyword] | None = getattr( - fn.var.value, "arities", None - ) + arities: tuple[int | kw.Keyword] | None = getattr(fn.var.value, "arities", None) if arities is not None: has_variadic = REST_KW in arities fixed_arities = set(filter(lambda v: v != REST_KW, arities)) diff --git a/src/basilisp/lang/compiler/generator.py b/src/basilisp/lang/compiler/generator.py index 41a61cd4e..56a85ac96 100644 --- a/src/basilisp/lang/compiler/generator.py +++ b/src/basilisp/lang/compiler/generator.py @@ -10,7 +10,7 @@ import pickle # nosec B403 import re import uuid -from collections.abc import Collection, Iterable, Mapping, MutableMapping +from collections.abc import Callable, Collection, Iterable, Mapping, MutableMapping from datetime import datetime from decimal import Decimal from enum import Enum @@ -18,12 +18,10 @@ from functools import partial, wraps from itertools import chain from re import Pattern -from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union, cast -from collections.abc import Callable +from typing import TYPE_CHECKING, Concatenate, Generic, Optional, TypeVar, Union, cast import attr from typing_extensions import ParamSpec -from typing import Concatenate from basilisp.lang import keyword as kw from basilisp.lang import list as llist diff --git a/src/basilisp/lang/compiler/nodes.py b/src/basilisp/lang/compiler/nodes.py index 4eb3fa2c6..6062ac853 100644 --- a/src/basilisp/lang/compiler/nodes.py +++ b/src/basilisp/lang/compiler/nodes.py @@ -1,8 +1,7 @@ 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, Generic, Optional, TypeVar, Union -from collections.abc import Callable import attr diff --git a/src/basilisp/lang/delay.py b/src/basilisp/lang/delay.py index 404b5be98..cf1f30c2d 100644 --- a/src/basilisp/lang/delay.py +++ b/src/basilisp/lang/delay.py @@ -1,5 +1,5 @@ -from typing import Generic, Optional, TypeVar from collections.abc import Callable +from typing import Generic, Optional, TypeVar import attr diff --git a/src/basilisp/lang/futures.py b/src/basilisp/lang/futures.py index 21059fc36..7d6c44af6 100644 --- a/src/basilisp/lang/futures.py +++ b/src/basilisp/lang/futures.py @@ -1,9 +1,9 @@ +from collections.abc import Callable from concurrent.futures import Future as _Future # noqa # pylint: disable=unused-import from concurrent.futures import ProcessPoolExecutor as _ProcessPoolExecutor from concurrent.futures import ThreadPoolExecutor as _ThreadPoolExecutor from concurrent.futures import TimeoutError as _TimeoutError from typing import Optional, TypeVar -from collections.abc import Callable import attr from typing_extensions import ParamSpec diff --git a/src/basilisp/lang/interfaces.py b/src/basilisp/lang/interfaces.py index d728471b8..fc16fca3e 100644 --- a/src/basilisp/lang/interfaces.py +++ b/src/basilisp/lang/interfaces.py @@ -1,6 +1,14 @@ 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, @@ -12,7 +20,6 @@ Union, overload, ) -from collections.abc import Callable from typing_extensions import Self, Unpack diff --git a/src/basilisp/lang/map.py b/src/basilisp/lang/map.py index 1889ba0f4..23ed349ed 100644 --- a/src/basilisp/lang/map.py +++ b/src/basilisp/lang/map.py @@ -1,8 +1,7 @@ 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, Optional, TypeVar, Union, cast -from collections.abc import Callable from immutables import Map as _Map from immutables import MapMutation @@ -91,10 +90,10 @@ def val_at(self, k, default=None): def cons_transient( # type: ignore[override] self, *elems: ( - IPersistentMap[K, V] | - IMapEntry[K, V] | - IPersistentVector[K | V] | - Mapping[K, V] + IPersistentMap[K, V] + | IMapEntry[K, V] + | IPersistentVector[K | V] + | Mapping[K, V] ), ) -> "TransientMap[K, V]": try: @@ -323,10 +322,10 @@ def update_with( # type: ignore[return] def cons( # type: ignore[override, return] self, *elems: ( - IPersistentMap[K, V] | - IMapEntry[K, V] | - IPersistentVector[K | V] | - Mapping[K, V] + IPersistentMap[K, V] + | IMapEntry[K, V] + | IPersistentVector[K | V] + | Mapping[K, V] ), ) -> "PersistentMap[K, V]": with self._inner.mutate() as m: diff --git a/src/basilisp/lang/multifn.py b/src/basilisp/lang/multifn.py index c7070cf09..411304d0a 100644 --- a/src/basilisp/lang/multifn.py +++ b/src/basilisp/lang/multifn.py @@ -1,6 +1,6 @@ import threading -from typing import Any, Generic, Optional, TypeVar from collections.abc import Callable +from typing import Any, Generic, Optional, TypeVar from basilisp.lang import map as lmap from basilisp.lang import runtime diff --git a/src/basilisp/lang/reader.py b/src/basilisp/lang/reader.py index 4c18e677a..ff2ab9e50 100644 --- a/src/basilisp/lang/reader.py +++ b/src/basilisp/lang/reader.py @@ -9,14 +9,13 @@ import os import re import uuid -from collections.abc import Collection, Iterable, MutableMapping, Sequence +from collections.abc import Callable, Collection, Iterable, MutableMapping, Sequence from datetime import datetime from fractions import Fraction from itertools import chain from re import Pattern from types import TracebackType from typing import Any, NoReturn, Optional, TypeVar, Union, cast -from collections.abc import Callable import attr from typing_extensions import Unpack @@ -799,9 +798,7 @@ def process_key(k: Any) -> Any: @_with_loc -def _read_map( - ctx: ReaderContext, namespace: str | None = None -) -> lmap.PersistentMap: +def _read_map(ctx: ReaderContext, namespace: str | None = None) -> lmap.PersistentMap: """Return a map from the input stream.""" reader = ctx.reader start = reader.advance() diff --git a/src/basilisp/lang/reference.py b/src/basilisp/lang/reference.py index 7007def5d..8b35940ee 100644 --- a/src/basilisp/lang/reference.py +++ b/src/basilisp/lang/reference.py @@ -1,9 +1,8 @@ import threading -from typing import Any, Optional, TypeVar from collections.abc import Callable +from typing import Any, Concatenate, Optional, TypeVar from typing_extensions import ParamSpec -from typing import Concatenate from basilisp.lang import keyword as kw from basilisp.lang import map as lmap diff --git a/src/basilisp/lang/runtime.py b/src/basilisp/lang/runtime.py index 1258a1033..4467c6e49 100644 --- a/src/basilisp/lang/runtime.py +++ b/src/basilisp/lang/runtime.py @@ -17,10 +17,9 @@ import sys import threading import types -from collections.abc import Iterable, Iterator, Mapping, Sequence, Sized +from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence, Sized from fractions import Fraction from typing import AbstractSet, Any, NoReturn, Optional, TypeVar, Union, cast -from collections.abc import Callable import attr @@ -592,9 +591,7 @@ class Namespace(ReferenceBase): "_import_refers", ) - def __init__( - self, name: sym.Symbol, module: BasilispModule | None = None - ) -> None: + def __init__(self, name: sym.Symbol, module: BasilispModule | None = None) -> None: self._name = name self._module = Maybe(module).or_else(lambda: _new_module(name.as_python_sym())) @@ -1705,9 +1702,7 @@ def deref(o, timeout_ms=None, timeout_val=None): @deref.register(IBlockingDeref) -def _deref_blocking( - o: IBlockingDeref, timeout_ms: int | None = None, timeout_val=None -): +def _deref_blocking(o: IBlockingDeref, timeout_ms: int | None = None, timeout_val=None): timeout_s = None if timeout_ms is not None: timeout_s = timeout_ms / 1000 if timeout_ms != 0 else 0 diff --git a/src/basilisp/lang/seq.py b/src/basilisp/lang/seq.py index 824053e46..3cbe235d1 100644 --- a/src/basilisp/lang/seq.py +++ b/src/basilisp/lang/seq.py @@ -1,8 +1,7 @@ import functools import threading -from collections.abc import Iterable +from collections.abc import Callable, Iterable from typing import Optional, TypeVar, overload -from collections.abc import Callable from basilisp.lang.interfaces import ( IPersistentMap, diff --git a/src/basilisp/lang/volatile.py b/src/basilisp/lang/volatile.py index 1993c5920..9a2c96bfd 100644 --- a/src/basilisp/lang/volatile.py +++ b/src/basilisp/lang/volatile.py @@ -1,9 +1,8 @@ -from typing import Optional, TypeVar from collections.abc import Callable +from typing import Concatenate, Optional, TypeVar import attr from typing_extensions import ParamSpec -from typing import Concatenate from basilisp.lang.interfaces import IDeref diff --git a/src/basilisp/logconfig.py b/src/basilisp/logconfig.py index 2262d35dc..6fd6c49b0 100644 --- a/src/basilisp/logconfig.py +++ b/src/basilisp/logconfig.py @@ -17,9 +17,7 @@ def get_level() -> str: return os.getenv("BASILISP_LOGGING_LEVEL", "WARNING") -def get_handler( - level: str | None = 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.""" handler = ( logging.StreamHandler() @@ -31,9 +29,7 @@ def get_handler( return handler -def configure_root_logger( - level: str | None = None, fmt: str = DEFAULT_FORMAT -) -> None: +def configure_root_logger(level: str | None = None, fmt: str = DEFAULT_FORMAT) -> None: """Configure the Basilisp root logger.""" level = level or get_level() logger = logging.getLogger("basilisp") diff --git a/src/basilisp/util.py b/src/basilisp/util.py index 36d8b3064..f291559e3 100644 --- a/src/basilisp/util.py +++ b/src/basilisp/util.py @@ -1,8 +1,7 @@ import contextlib import time -from collections.abc import Iterable, Sequence +from collections.abc import Callable, Iterable, Sequence from typing import Generic, Optional, TypeVar -from collections.abc import Callable @contextlib.contextmanager diff --git a/tests/basilisp/helpers.py b/tests/basilisp/helpers.py index 9a0ddfead..11f7b2072 100644 --- a/tests/basilisp/helpers.py +++ b/tests/basilisp/helpers.py @@ -1,5 +1,5 @@ -from typing import Any, Tuple from collections.abc import Callable +from typing import Any, Tuple from basilisp.lang import symbol as sym from basilisp.lang.runtime import CORE_NS_SYM, Namespace diff --git a/tests/basilisp/prompt_test.py b/tests/basilisp/prompt_test.py index 5fb8e5545..699ea6063 100644 --- a/tests/basilisp/prompt_test.py +++ b/tests/basilisp/prompt_test.py @@ -1,5 +1,4 @@ -from collections.abc import Iterable -from collections.abc import Callable +from collections.abc import Callable, Iterable from unittest.mock import MagicMock, patch import pytest From 05898d5a112531777959db9ee0e69363168ad7f6 Mon Sep 17 00:00:00 2001 From: Chris Rink Date: Wed, 29 Oct 2025 21:22:31 -0400 Subject: [PATCH 3/3] Fix imports --- src/basilisp/cli.py | 2 +- src/basilisp/contrib/sphinx/autodoc.py | 2 +- src/basilisp/contrib/sphinx/domain.py | 2 +- src/basilisp/importer.py | 2 +- src/basilisp/lang/atom.py | 2 +- src/basilisp/lang/compiler/__init__.py | 2 +- src/basilisp/lang/compiler/exception.py | 2 +- src/basilisp/lang/compiler/optimizer.py | 2 +- src/basilisp/lang/delay.py | 2 +- src/basilisp/lang/exception.py | 1 - src/basilisp/lang/futures.py | 2 +- src/basilisp/lang/keyword.py | 1 - src/basilisp/lang/list.py | 2 +- src/basilisp/lang/map.py | 2 +- src/basilisp/lang/multifn.py | 2 +- src/basilisp/lang/promise.py | 2 +- src/basilisp/lang/queue.py | 2 +- src/basilisp/lang/reader.py | 2 +- src/basilisp/lang/set.py | 2 +- src/basilisp/lang/source.py | 1 - src/basilisp/lang/symbol.py | 1 - src/basilisp/lang/tagged.py | 2 +- src/basilisp/lang/typing.py | 2 +- src/basilisp/lang/vector.py | 2 +- src/basilisp/lang/volatile.py | 2 +- src/basilisp/logconfig.py | 1 - src/basilisp/main.py | 1 - src/basilisp/util.py | 2 +- tests/basilisp/cli_test.py | 7 +++---- tests/basilisp/conftest.py | 1 - tests/basilisp/helpers.py | 2 +- tests/basilisp/importer_test.py | 2 -- tests/basilisp/reader_test.py | 1 - 33 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/basilisp/cli.py b/src/basilisp/cli.py index 1ca14602e..1d7dd2625 100644 --- a/src/basilisp/cli.py +++ b/src/basilisp/cli.py @@ -8,7 +8,7 @@ import types from collections.abc import Callable, Sequence from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Union from basilisp import main as basilisp from basilisp.lang import compiler as compiler diff --git a/src/basilisp/contrib/sphinx/autodoc.py b/src/basilisp/contrib/sphinx/autodoc.py index a897e4caf..ac3acf5ff 100644 --- a/src/basilisp/contrib/sphinx/autodoc.py +++ b/src/basilisp/contrib/sphinx/autodoc.py @@ -3,7 +3,7 @@ import logging import sys import types -from typing import Any, Optional, cast +from typing import Any, cast from sphinx.ext.autodoc import ( ClassDocumenter, diff --git a/src/basilisp/contrib/sphinx/domain.py b/src/basilisp/contrib/sphinx/domain.py index c19dc791c..8eed7c629 100644 --- a/src/basilisp/contrib/sphinx/domain.py +++ b/src/basilisp/contrib/sphinx/domain.py @@ -1,7 +1,7 @@ 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 from docutils import nodes from docutils.nodes import Element, Node diff --git a/src/basilisp/importer.py b/src/basilisp/importer.py index 0be82d9a0..5484e0a7b 100644 --- a/src/basilisp/importer.py +++ b/src/basilisp/importer.py @@ -9,7 +9,7 @@ from functools import lru_cache from importlib.abc import MetaPathFinder, SourceLoader from importlib.machinery import ModuleSpec -from typing import Any, Optional, cast +from typing import Any, cast from typing_extensions import TypedDict diff --git a/src/basilisp/lang/atom.py b/src/basilisp/lang/atom.py index aad4e764a..8b07eca1b 100644 --- a/src/basilisp/lang/atom.py +++ b/src/basilisp/lang/atom.py @@ -1,6 +1,6 @@ import threading from collections.abc import Callable -from typing import Concatenate, Generic, Optional, TypeVar +from typing import Concatenate, Generic, TypeVar from typing_extensions import ParamSpec diff --git a/src/basilisp/lang/compiler/__init__.py b/src/basilisp/lang/compiler/__init__.py index 0dbd7393a..f64368b5c 100644 --- a/src/basilisp/lang/compiler/__init__.py +++ b/src/basilisp/lang/compiler/__init__.py @@ -5,7 +5,7 @@ from ast import unparse from collections.abc import Callable, Iterable from pathlib import Path -from typing import Any, Optional +from typing import Any from basilisp.lang import list as llist from basilisp.lang import map as lmap diff --git a/src/basilisp/lang/compiler/exception.py b/src/basilisp/lang/compiler/exception.py index 0a57402ee..3115dc3e1 100644 --- a/src/basilisp/lang/compiler/exception.py +++ b/src/basilisp/lang/compiler/exception.py @@ -2,7 +2,7 @@ import os from enum import Enum from types import TracebackType -from typing import Any, Optional, Union +from typing import Any import attr diff --git a/src/basilisp/lang/compiler/optimizer.py b/src/basilisp/lang/compiler/optimizer.py index aa12d388f..9252dfb97 100644 --- a/src/basilisp/lang/compiler/optimizer.py +++ b/src/basilisp/lang/compiler/optimizer.py @@ -3,7 +3,7 @@ from collections import deque from collections.abc import Iterable from contextlib import contextmanager -from typing import Deque, Optional +from typing import Deque from basilisp.lang.compiler.constants import OPERATOR_ALIAS from basilisp.lang.compiler.utils import ast_FunctionDef diff --git a/src/basilisp/lang/delay.py b/src/basilisp/lang/delay.py index cf1f30c2d..6b56f60df 100644 --- a/src/basilisp/lang/delay.py +++ b/src/basilisp/lang/delay.py @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import Generic, Optional, TypeVar +from typing import Generic, TypeVar import attr diff --git a/src/basilisp/lang/exception.py b/src/basilisp/lang/exception.py index c6abaee87..32f10c7e3 100644 --- a/src/basilisp/lang/exception.py +++ b/src/basilisp/lang/exception.py @@ -2,7 +2,6 @@ import sys import traceback from types import TracebackType -from typing import Optional import attr diff --git a/src/basilisp/lang/futures.py b/src/basilisp/lang/futures.py index 7d6c44af6..f69308b46 100644 --- a/src/basilisp/lang/futures.py +++ b/src/basilisp/lang/futures.py @@ -3,7 +3,7 @@ from concurrent.futures import ProcessPoolExecutor as _ProcessPoolExecutor from concurrent.futures import ThreadPoolExecutor as _ThreadPoolExecutor from concurrent.futures import TimeoutError as _TimeoutError -from typing import Optional, TypeVar +from typing import TypeVar import attr from typing_extensions import ParamSpec diff --git a/src/basilisp/lang/keyword.py b/src/basilisp/lang/keyword.py index e98bfb8c7..62941e152 100644 --- a/src/basilisp/lang/keyword.py +++ b/src/basilisp/lang/keyword.py @@ -1,7 +1,6 @@ import threading from collections.abc import Iterable from functools import total_ordering -from typing import Optional, Union from typing_extensions import Unpack diff --git a/src/basilisp/lang/list.py b/src/basilisp/lang/list.py index 94f4a46b3..bd33fc492 100644 --- a/src/basilisp/lang/list.py +++ b/src/basilisp/lang/list.py @@ -1,4 +1,4 @@ -from typing import Optional, TypeVar, cast +from typing import TypeVar, cast from pyrsistent import PList, plist # noqa # pylint: disable=unused-import from pyrsistent._plist import _EMPTY_PLIST # pylint: disable=import-private-name diff --git a/src/basilisp/lang/map.py b/src/basilisp/lang/map.py index 23ed349ed..1723f5463 100644 --- a/src/basilisp/lang/map.py +++ b/src/basilisp/lang/map.py @@ -1,7 +1,7 @@ from builtins import map as pymap from collections.abc import Callable, Iterable, Mapping from itertools import islice -from typing import Any, Optional, TypeVar, Union, cast +from typing import Any, TypeVar, cast from immutables import Map as _Map from immutables import MapMutation diff --git a/src/basilisp/lang/multifn.py b/src/basilisp/lang/multifn.py index 411304d0a..6bcd8c55d 100644 --- a/src/basilisp/lang/multifn.py +++ b/src/basilisp/lang/multifn.py @@ -1,6 +1,6 @@ import threading from collections.abc import Callable -from typing import Any, Generic, Optional, TypeVar +from typing import Any, Generic, TypeVar from basilisp.lang import map as lmap from basilisp.lang import runtime diff --git a/src/basilisp/lang/promise.py b/src/basilisp/lang/promise.py index 31d86ff4a..735b0c8fb 100644 --- a/src/basilisp/lang/promise.py +++ b/src/basilisp/lang/promise.py @@ -1,5 +1,5 @@ import threading -from typing import Optional, TypeVar +from typing import TypeVar from basilisp.lang.interfaces import IBlockingDeref, IPending diff --git a/src/basilisp/lang/queue.py b/src/basilisp/lang/queue.py index c25a0eae1..3f1e3e517 100644 --- a/src/basilisp/lang/queue.py +++ b/src/basilisp/lang/queue.py @@ -1,4 +1,4 @@ -from typing import Optional, TypeVar +from typing import TypeVar from pyrsistent import PDeque, pdeque # noqa # pylint: disable=unused-import from typing_extensions import Unpack diff --git a/src/basilisp/lang/reader.py b/src/basilisp/lang/reader.py index ff2ab9e50..d39f0bde1 100644 --- a/src/basilisp/lang/reader.py +++ b/src/basilisp/lang/reader.py @@ -15,7 +15,7 @@ from itertools import chain from re import Pattern from types import TracebackType -from typing import Any, NoReturn, Optional, TypeVar, Union, cast +from typing import Any, NoReturn, TypeVar, Union, cast import attr from typing_extensions import Unpack diff --git a/src/basilisp/lang/set.py b/src/basilisp/lang/set.py index e9f5b96f6..fe15a2982 100644 --- a/src/basilisp/lang/set.py +++ b/src/basilisp/lang/set.py @@ -1,6 +1,6 @@ from collections.abc import Iterable from collections.abc import Set as _PySet -from typing import AbstractSet, Optional, TypeVar +from typing import AbstractSet, TypeVar from immutables import Map as _Map from immutables import MapMutation diff --git a/src/basilisp/lang/source.py b/src/basilisp/lang/source.py index be8fd9c44..e779e90a7 100644 --- a/src/basilisp/lang/source.py +++ b/src/basilisp/lang/source.py @@ -2,7 +2,6 @@ import linecache import os from collections.abc import Iterable -from typing import Optional try: import pygments.formatters diff --git a/src/basilisp/lang/symbol.py b/src/basilisp/lang/symbol.py index 873e4fbd6..d0a0d56e7 100644 --- a/src/basilisp/lang/symbol.py +++ b/src/basilisp/lang/symbol.py @@ -1,5 +1,4 @@ from functools import total_ordering -from typing import Optional, Union from typing_extensions import Unpack diff --git a/src/basilisp/lang/tagged.py b/src/basilisp/lang/tagged.py index 8a772a345..05d807d96 100644 --- a/src/basilisp/lang/tagged.py +++ b/src/basilisp/lang/tagged.py @@ -1,4 +1,4 @@ -from typing import Optional, TypeVar, Union +from typing import TypeVar, Union from typing_extensions import Unpack diff --git a/src/basilisp/lang/typing.py b/src/basilisp/lang/typing.py index ce46af5ad..df4236505 100644 --- a/src/basilisp/lang/typing.py +++ b/src/basilisp/lang/typing.py @@ -3,7 +3,7 @@ from decimal import Decimal from fractions import Fraction from re import Pattern -from typing import Optional, Protocol, Union +from typing import Protocol, Union from basilisp.lang import keyword as kw from basilisp.lang import list as llist diff --git a/src/basilisp/lang/vector.py b/src/basilisp/lang/vector.py index e8c2c3e0c..5809f767e 100644 --- a/src/basilisp/lang/vector.py +++ b/src/basilisp/lang/vector.py @@ -1,6 +1,6 @@ from collections.abc import Iterable, Sequence from functools import total_ordering -from typing import Optional, TypeVar, Union, cast, overload +from typing import TypeVar, Union, cast, overload from pyrsistent import PVector, pvector # noqa # pylint: disable=unused-import from pyrsistent.typing import PVectorEvolver diff --git a/src/basilisp/lang/volatile.py b/src/basilisp/lang/volatile.py index 9a2c96bfd..178af5f62 100644 --- a/src/basilisp/lang/volatile.py +++ b/src/basilisp/lang/volatile.py @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import Concatenate, Optional, TypeVar +from typing import Concatenate, TypeVar import attr from typing_extensions import ParamSpec diff --git a/src/basilisp/logconfig.py b/src/basilisp/logconfig.py index 6fd6c49b0..f7f31c730 100644 --- a/src/basilisp/logconfig.py +++ b/src/basilisp/logconfig.py @@ -1,6 +1,5 @@ import logging import os -from typing import Optional TRACE = 5 diff --git a/src/basilisp/main.py b/src/basilisp/main.py index 8be9afe09..e36f28a11 100644 --- a/src/basilisp/main.py +++ b/src/basilisp/main.py @@ -3,7 +3,6 @@ import sysconfig import threading from pathlib import Path -from typing import Optional from basilisp import importer as importer from basilisp import logconfig diff --git a/src/basilisp/util.py b/src/basilisp/util.py index f291559e3..a88a6ad7e 100644 --- a/src/basilisp/util.py +++ b/src/basilisp/util.py @@ -1,7 +1,7 @@ import contextlib import time from collections.abc import Callable, Iterable, Sequence -from typing import Generic, Optional, TypeVar +from typing import Generic, TypeVar @contextlib.contextmanager diff --git a/tests/basilisp/cli_test.py b/tests/basilisp/cli_test.py index 59df3fd09..9975a5491 100644 --- a/tests/basilisp/cli_test.py +++ b/tests/basilisp/cli_test.py @@ -13,7 +13,6 @@ import venv from collections.abc import Sequence from threading import Thread -from typing import Optional from unittest.mock import patch import attr @@ -333,7 +332,7 @@ def test_repl_include_extra_path( ["repl", *temp_path_args], input=" ".join( [ - f"(import pathlib sys)", + "(import pathlib sys)", "(doseq [path sys/path]", " (prn (.as-posix (pathlib/Path path))))", ] @@ -413,7 +412,7 @@ def test_run_code_include_extra_path( "-c", os.linesep.join( [ - f"(import pathlib sys)", + "(import pathlib sys)", "(doseq [path sys/path]", " (prn (.as-posix (pathlib/Path path))))", ] @@ -731,7 +730,7 @@ def test_run_stdin_include_extra_path( ["run", *temp_path_args, "-"], input=os.linesep.join( [ - f"(import pathlib sys)", + "(import pathlib sys)", "(doseq [path sys/path]", " (prn (.as-posix (pathlib/Path path))))", ] diff --git a/tests/basilisp/conftest.py b/tests/basilisp/conftest.py index ef4ca903c..fa1d9fffe 100644 --- a/tests/basilisp/conftest.py +++ b/tests/basilisp/conftest.py @@ -1,6 +1,5 @@ import io import sys -from typing import Dict, Optional, Tuple import pytest diff --git a/tests/basilisp/helpers.py b/tests/basilisp/helpers.py index 11f7b2072..376b7896d 100644 --- a/tests/basilisp/helpers.py +++ b/tests/basilisp/helpers.py @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import Any, Tuple +from typing import Any from basilisp.lang import symbol as sym from basilisp.lang.runtime import CORE_NS_SYM, Namespace diff --git a/tests/basilisp/importer_test.py b/tests/basilisp/importer_test.py index 6af25e134..02339aec0 100644 --- a/tests/basilisp/importer_test.py +++ b/tests/basilisp/importer_test.py @@ -8,12 +8,10 @@ import tempfile from multiprocessing import Process, get_start_method from tempfile import TemporaryDirectory -from typing import Optional from unittest.mock import patch import pytest -import basilisp.main from basilisp import importer as importer from basilisp.lang import runtime as runtime from basilisp.lang import symbol as sym diff --git a/tests/basilisp/reader_test.py b/tests/basilisp/reader_test.py index a4bcd57cc..9e9ea1d45 100644 --- a/tests/basilisp/reader_test.py +++ b/tests/basilisp/reader_test.py @@ -7,7 +7,6 @@ import uuid from fractions import Fraction from pathlib import Path -from typing import Optional import pytest