Skip to content

Commit 049f53d

Browse files
authored
Improve the state of Python type hints in basilisp.lang.* (#797)
Second attempt to pare down the failing PyPy build for #784
1 parent 84282f5 commit 049f53d

23 files changed

+182
-175
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
### Removed
3232
* Removed support for PyPy 3.8 (#785)
3333

34+
### Other
35+
* Improve the state of the Python type hints in `basilisp.lang.*` (#797)
36+
37+
3438
## [v0.1.0b0]
3539
### Added
3640
* Added rudimentary support for `clojure.stacktrace` with `print-cause-trace` (part of #721)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ disable = [
219219
check_untyped_defs = true
220220
mypy_path = "src/"
221221
show_error_codes = true
222+
warn_redundant_casts = true
222223
warn_unused_configs = true
223224
warn_unused_ignores = true
224225

src/basilisp/cli.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,13 @@ def _subcommand(
237237
help: Optional[str] = None, # pylint: disable=redefined-builtin
238238
description: Optional[str] = None,
239239
handler: Handler,
240-
):
241-
def _wrap_add_subcommand(f: Callable[[argparse.ArgumentParser], None]):
240+
) -> Callable[
241+
[Callable[[argparse.ArgumentParser], None]],
242+
Callable[["argparse._SubParsersAction"], None],
243+
]:
244+
def _wrap_add_subcommand(
245+
f: Callable[[argparse.ArgumentParser], None]
246+
) -> Callable[["argparse._SubParsersAction"], None]:
242247
def _wrapped_subcommand(subparsers: "argparse._SubParsersAction"):
243248
parser = subparsers.add_parser(
244249
subcommand, help=help, description=description
@@ -279,14 +284,14 @@ def bootstrap_basilisp_installation(_, args: argparse.Namespace) -> None:
279284
description=textwrap.dedent(
280285
"""Bootstrap the Python installation to allow importing Basilisp namespaces"
281286
without requiring an additional bootstrapping step.
282-
287+
283288
Python installations are bootstrapped by installing a `basilispbootstrap.pth`
284289
file in your `site-packages` directory. Python installations execute `*.pth`
285290
files found at startup.
286-
291+
287292
Bootstrapping your Python installation in this way can help avoid needing to
288293
perform manual bootstrapping from Python code within your application.
289-
294+
290295
On the first startup, Basilisp will compile `basilisp.core` to byte code
291296
which could take up to 30 seconds in some cases depending on your system and
292297
which version of Python you are using. Subsequent startups should be
@@ -319,7 +324,7 @@ def _add_bootstrap_subcommand(parser: argparse.ArgumentParser) -> None:
319324
def nrepl_server(
320325
_,
321326
args: argparse.Namespace,
322-
):
327+
) -> None:
323328
opts = compiler.compiler_opts()
324329
basilisp.init(opts)
325330

@@ -369,7 +374,7 @@ def _add_nrepl_server_subcommand(parser: argparse.ArgumentParser) -> None:
369374
def repl(
370375
_,
371376
args: argparse.Namespace,
372-
):
377+
) -> None:
373378
opts = compiler.compiler_opts(
374379
warn_on_shadowed_name=args.warn_on_shadowed_name,
375380
warn_on_shadowed_var=args.warn_on_shadowed_var,
@@ -465,7 +470,7 @@ def _add_repl_subcommand(parser: argparse.ArgumentParser) -> None:
465470
def run(
466471
parser: argparse.ArgumentParser,
467472
args: argparse.Namespace,
468-
):
473+
) -> None:
469474
target = args.file_or_ns_or_code
470475
if args.load_namespace:
471476
if args.in_ns is not None:
@@ -523,18 +528,18 @@ def run(
523528
help="run a Basilisp script or code or namespace",
524529
description=textwrap.dedent(
525530
"""Run a Basilisp script or a line of code or load a Basilisp namespace.
526-
531+
527532
If `-c` is provided, execute the line of code as given. If `-n` is given,
528533
interpret `file_or_ns_or_code` as a fully qualified Basilisp namespace
529534
relative to `sys.path`. Otherwise, execute the file as a script relative to
530535
the current working directory.
531-
536+
532537
`*main-ns*` will be set to the value provided for `-n`. In all other cases,
533538
it will be `nil`."""
534539
),
535540
handler=run,
536541
)
537-
def _add_run_subcommand(parser: argparse.ArgumentParser):
542+
def _add_run_subcommand(parser: argparse.ArgumentParser) -> None:
538543
parser.add_argument(
539544
"file_or_ns_or_code",
540545
help=(
@@ -570,7 +575,9 @@ def _add_run_subcommand(parser: argparse.ArgumentParser):
570575
_add_debug_arg_group(parser)
571576

572577

573-
def test(parser: argparse.ArgumentParser, args: argparse.Namespace): # pragma: no cover
578+
def test(
579+
parser: argparse.ArgumentParser, args: argparse.Namespace
580+
) -> None: # pragma: no cover
574581
try:
575582
import pytest
576583
except (ImportError, ModuleNotFoundError):
@@ -591,7 +598,7 @@ def _add_test_subcommand(parser: argparse.ArgumentParser) -> None:
591598
parser.add_argument("args", nargs=-1)
592599

593600

594-
def version(_, __):
601+
def version(_, __) -> None:
595602
v = importlib.metadata.version("basilisp")
596603
print(f"Basilisp {v}")
597604

src/basilisp/importer.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
from functools import lru_cache
99
from importlib.abc import MetaPathFinder, SourceLoader
1010
from importlib.machinery import ModuleSpec
11-
from typing import Iterable, List, Mapping, MutableMapping, Optional, Sequence, cast
11+
from typing import (
12+
Any,
13+
Iterable,
14+
List,
15+
Mapping,
16+
MutableMapping,
17+
Optional,
18+
Sequence,
19+
cast,
20+
)
1221

1322
from basilisp.lang import compiler as compiler
1423
from basilisp.lang import reader as reader
@@ -191,22 +200,22 @@ def find_spec(
191200
return ModuleSpec(fullname, None, is_package=True)
192201
return None
193202

194-
def invalidate_caches(self):
203+
def invalidate_caches(self) -> None:
195204
super().invalidate_caches()
196205
self._cache = {}
197206

198-
def _cache_bytecode(self, source_path, cache_path, data):
207+
def _cache_bytecode(self, source_path: str, cache_path: str, data: bytes) -> None:
199208
self.set_data(cache_path, data)
200209

201-
def path_stats(self, path):
210+
def path_stats(self, path: str) -> Mapping[str, Any]:
202211
stat = os.stat(path)
203212
return {"mtime": int(stat.st_mtime), "size": stat.st_size}
204213

205-
def get_data(self, path):
214+
def get_data(self, path: str) -> bytes:
206215
with open(path, mode="r+b") as f:
207216
return f.read()
208217

209-
def set_data(self, path, data):
218+
def set_data(self, path: str, data: bytes) -> None:
210219
os.makedirs(os.path.dirname(path), exist_ok=True)
211220
with open(path, mode="w+b") as f:
212221
f.write(data)
@@ -279,7 +288,7 @@ def get_code(self, fullname: str) -> Optional[types.CodeType]:
279288
assert len(code) == 1
280289
return code[0]
281290

282-
def create_module(self, spec: ModuleSpec):
291+
def create_module(self, spec: ModuleSpec) -> BasilispModule:
283292
logger.debug(f"Creating Basilisp module '{spec.name}'")
284293
mod = BasilispModule(spec.name)
285294
mod.__file__ = spec.loader_state["filename"]
@@ -400,7 +409,7 @@ def exec_module(self, module: types.ModuleType) -> None:
400409
self._exec_module(fullname, spec.loader_state, path_stats, ns)
401410

402411

403-
def hook_imports():
412+
def hook_imports() -> None:
404413
"""Hook into Python's import machinery with a custom Basilisp code
405414
importer.
406415

src/basilisp/lang/compiler/analyzer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@
175175
AnalyzerException = partial(CompilerException, phase=CompilerPhase.ANALYZING)
176176

177177

178-
@attr.s(auto_attribs=True, slots=True)
178+
@attr.define
179179
class RecurPoint:
180180
loop_id: str
181181
args: Collection[Binding] = ()
182182

183183

184-
@attr.s(auto_attribs=True, frozen=True, slots=True)
184+
@attr.frozen
185185
class SymbolTableEntry:
186186
binding: Binding
187187
used: bool = False
@@ -196,7 +196,7 @@ def context(self) -> LocalType:
196196
return self.binding.local
197197

198198

199-
@attr.s(auto_attribs=True, slots=True)
199+
@attr.define
200200
class SymbolTable:
201201
name: str
202202
_is_context_boundary: bool = False

src/basilisp/lang/compiler/exception.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class CompilerPhase(Enum):
3030
COMPILING_PYTHON = kw.keyword("compiling-python")
3131

3232

33-
@attr.s(auto_attribs=True, frozen=True, slots=True)
33+
@attr.frozen
3434
class _loc:
3535
line: Optional[int] = None
3636
col: Optional[int] = None
@@ -46,7 +46,7 @@ def __bool__(self):
4646
)
4747

4848

49-
@attr.s(auto_attribs=True, slots=True, str=False)
49+
@attr.define(str=False)
5050
class CompilerException(IExceptionInfo):
5151
msg: str
5252
phase: CompilerPhase

src/basilisp/lang/compiler/generator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@
135135
GeneratorException = partial(CompilerException, phase=CompilerPhase.CODE_GENERATION)
136136

137137

138-
@attr.s(auto_attribs=True, frozen=True, slots=True)
138+
@attr.frozen
139139
class SymbolTableEntry:
140140
context: LocalType
141141
munged: str
142142
symbol: sym.Symbol
143143

144144

145-
@attr.s(auto_attribs=True, slots=True)
145+
@attr.define
146146
class SymbolTable:
147147
name: str
148148
_is_context_boundary: bool = False
@@ -203,7 +203,7 @@ class RecurType(Enum):
203203
LOOP = kw.keyword("loop")
204204

205205

206-
@attr.s(auto_attribs=True, slots=True)
206+
@attr.define
207207
class RecurPoint:
208208
loop_id: str
209209
type: RecurType
@@ -313,7 +313,7 @@ def new_this(self, this: sym.Symbol):
313313
self._this.pop()
314314

315315

316-
@attr.s(auto_attribs=True, frozen=True, slots=True)
316+
@attr.frozen
317317
class GeneratedPyAST:
318318
node: ast.AST
319319
dependencies: Iterable[ast.AST] = ()

0 commit comments

Comments
 (0)