Skip to content

Commit

Permalink
Remove typing_extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
nineteendo committed Aug 1, 2024
1 parent 6fbcd9d commit 43426ab
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 3,894 deletions.
5 changes: 1 addition & 4 deletions src/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

import sys
from argparse import ArgumentParser
from typing import cast
from typing import Literal, cast

import jsonyx.tool
from jsonyx.tool import JSONNamespace
from typing_extensions import Literal, assert_never # type: ignore


class _PyVZ2Namespace: # pylint: disable=R0903
Expand All @@ -28,8 +27,6 @@ def _main() -> None:
try:
if args.command == "json":
jsonyx.tool.run(cast(JSONNamespace, args))
else:
assert_never(args.command)
except BrokenPipeError as exc:
sys.exit(exc.errno)

Expand Down
17 changes: 8 additions & 9 deletions src/jsonyx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@
from pathlib import Path
from sys import stdout
from textwrap import dedent
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any, Literal

from jsonyx._decoder import DuplicateKey, JSONSyntaxError, make_scanner
from jsonyx._encoder import make_encoder
from jsonyx.allow import NOTHING
from typing_extensions import Any, Literal # type: ignore

if TYPE_CHECKING:
from collections.abc import Callable, Container
Expand Down Expand Up @@ -128,22 +127,22 @@ def encode_decimal(decimal: Decimal) -> str:

return decimal_str(decimal)

self._encoder: Callable[[Any], str] = make_encoder(
self._encoder: Callable[[object], str] = make_encoder(
encode_decimal, indent, end, item_separator, key_separator,
allow_nan_and_infinity, allow_surrogates, ensure_ascii, sort_keys,
trailing_comma,
)
self._errors: str = "surrogatepass" if allow_surrogates else "strict"

def write(self, obj: Any, filename: StrPath) -> None:
def write(self, obj: object, filename: StrPath) -> None:
"""Serialize a Python object to a JSON file."""
Path(filename).write_text(self._encoder(obj), "utf_8", self._errors)

def dump(self, obj: Any, fp: SupportsWrite[str] = stdout) -> None:
def dump(self, obj: object, fp: SupportsWrite[str] = stdout) -> None:
"""Serialize a Python object to an open JSON file."""
fp.write(self._encoder(obj))

def dumps(self, obj: Any) -> str:
def dumps(self, obj: object) -> str:
"""Serialize a Python object to a JSON string."""
return self._encoder(obj)

Expand Down Expand Up @@ -238,7 +237,7 @@ def loads(

# pylint: disable-next=R0913
def write( # noqa: PLR0913
obj: Any,
obj: object,
filename: StrPath,
*,
allow: _AllowList = NOTHING,
Expand All @@ -265,7 +264,7 @@ def write( # noqa: PLR0913

# pylint: disable-next=R0913
def dump( # noqa: PLR0913
obj: Any,
obj: object,
fp: SupportsWrite[str] = stdout,
*,
allow: _AllowList = NOTHING,
Expand All @@ -292,7 +291,7 @@ def dump( # noqa: PLR0913

# pylint: disable-next=R0913
def dumps( # noqa: PLR0913
obj: Any,
obj: object,
*,
allow: _AllowList = NOTHING,
end: str = "\n",
Expand Down
10 changes: 5 additions & 5 deletions src/jsonyx/_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
from math import isinf
from re import DOTALL, MULTILINE, VERBOSE, Match, RegexFlag
from shutil import get_terminal_size
from typing import TYPE_CHECKING

from typing_extensions import Any # type: ignore
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
from collections.abc import Callable
Expand Down Expand Up @@ -169,7 +167,9 @@ def make_scanner( # noqa: C901, PLR0915, PLR0917, PLR0913
"""Make JSON scanner."""
memo: dict[str, str] = {}
memoize: Callable[[str, str], str] = memo.setdefault
parse_float: Callable[[str], Any] = Decimal if use_decimal else float
parse_float: Callable[
[str], Decimal | float,
] = Decimal if use_decimal else float

def skip_comments(filename: str, s: str, end: int) -> int:
find: Callable[[str, int], int] = s.find
Expand Down Expand Up @@ -382,7 +382,7 @@ def scan_array( # noqa: C901
return [], end + 1

values: list[Any] = []
append_value: Callable[[Any], None] = values.append
append_value: Callable[[object], None] = values.append
while True:
value, end = scan_value(filename, s, end)
append_value(value)
Expand Down
19 changes: 9 additions & 10 deletions src/jsonyx/_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
from re import Match
from typing import TYPE_CHECKING

from typing_extensions import Any # type: ignore

if TYPE_CHECKING:
from collections.abc import Callable, ItemsView

Expand Down Expand Up @@ -49,11 +47,11 @@ def make_encoder( # noqa: C901, PLR0915, PLR0917, PLR0913
ensure_ascii: bool, # noqa: FBT001
sort_keys: bool, # noqa: FBT001
trailing_comma: bool, # noqa: FBT001
) -> Callable[[Any], str]:
) -> Callable[[object], str]:
"""Make JSON encoder."""
float_repr: Callable[[float], str] = float.__repr__
int_repr: Callable[[int], str] = int.__repr__
markers: dict[int, Any] = {}
markers: dict[int, object] = {}

if not ensure_ascii:
def replace(match: Match[str]) -> str:
Expand Down Expand Up @@ -101,7 +99,7 @@ def floatstr(num: float) -> str:
return "NaN"

def write_list(
lst: list[Any], write: Callable[[str], Any], old_indent: str,
lst: list[object], write: Callable[[str], object], old_indent: str,
) -> None:
if not lst:
write("[]")
Expand Down Expand Up @@ -139,7 +137,8 @@ def write_list(
write("]")

def write_dict(
dct: dict[Any, Any], write: Callable[[str], Any], old_indent: str,
dct: dict[object, object], write: Callable[[str], object],
old_indent: str,
) -> None:
if not dct:
write("{}")
Expand All @@ -159,7 +158,7 @@ def write_dict(
write(current_indent)

first: bool = True
items: ItemsView[Any, Any] = dct.items()
items: ItemsView[object, object] = dct.items()
for key, value in sorted(items) if sort_keys else items:
if not isinstance(key, str):
msg = f"Keys must be str, not {type(key).__name__}"
Expand All @@ -183,7 +182,7 @@ def write_dict(
write("}")

def write_value(
obj: Any, write: Callable[[str], Any], current_indent: str,
obj: object, write: Callable[[str], object], current_indent: str,
) -> None:
if isinstance(obj, str):
write(encode_string(obj))
Expand All @@ -207,9 +206,9 @@ def write_value(
msg: str = f"{type(obj).__name__} is not JSON serializable"
raise TypeError(msg)

def encoder(obj: Any) -> str:
def encoder(obj: object) -> str:
fp: StringIO = StringIO()
write: Callable[[str], Any] = fp.write
write: Callable[[str], object] = fp.write
try:
write_value(obj, write, "\n")
except (ValueError, TypeError) as exc:
Expand Down
6 changes: 3 additions & 3 deletions src/jsonyx/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
if TYPE_CHECKING:
from types import ModuleType

cjson: ModuleType | None = import_fresh_module("jsonyx", fresh=["_jsonyx"])
pyjson: ModuleType | None = import_fresh_module("jsonyx", blocked=["_jsonyx"])
if cjson:
if cjson := import_fresh_module("jsonyx", fresh=["_jsonyx"]):
# JSONSyntaxError is cached inside the _jsonyx module
cjson.JSONSyntaxError = JSONSyntaxError # type: ignore

pyjson: ModuleType | None = import_fresh_module("jsonyx", blocked=["_jsonyx"])


@pytest.fixture(params=[cjson, pyjson], ids=["cjson", "pyjson"], name="json")
def get_json(request: pytest.FixtureRequest) -> ModuleType:
Expand Down
55 changes: 34 additions & 21 deletions src/jsonyx/test/test_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from decimal import Decimal
from math import isnan
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

import pytest
from jsonyx.allow import (
Expand All @@ -15,7 +15,6 @@
)
# pylint: disable-next=W0611
from jsonyx.test import get_json # type: ignore # noqa: F401
from typing_extensions import Any # type: ignore

if TYPE_CHECKING:
from types import ModuleType
Expand All @@ -41,7 +40,7 @@ def _check_syntax_err(
('"\ud800$"', "\ud800$"),
('"\udf48"', "\udf48"), # noqa: PT014
])
def test_surrogates(json: ModuleType, s: str, expected: Any) -> None:
def test_surrogates(json: ModuleType, s: str, expected: str) -> None:
"""Test surrogates."""
b: bytes = s.encode(errors="surrogatepass")
assert json.loads(b, allow=SURROGATES) == expected
Expand Down Expand Up @@ -70,7 +69,7 @@ def test_utf8_bom(json: ModuleType) -> None:
("false", False),
("null", None),
])
def test_keywords(json: ModuleType, s: str, expected: Any) -> None:
def test_keywords(json: ModuleType, s: str, *, expected: bool | None) -> None:
"""Test JSON keywords."""
assert json.loads(s) is expected

Expand All @@ -81,12 +80,14 @@ def test_nan_and_infinity(
json: ModuleType, s: str, *, use_decimal: bool,
) -> None:
"""Test NaN and infinity with decimal and float."""
obj: Any = json.loads(s, allow=NAN_AND_INFINITY, use_decimal=use_decimal)
expected_type: type = Decimal if use_decimal else float
expected: Any = expected_type(s)
obj: object = json.loads(
s, allow=NAN_AND_INFINITY, use_decimal=use_decimal,
)
expected_type: type[Decimal | float] = Decimal if use_decimal else float
expected: Decimal | float = expected_type(s)
assert isinstance(obj, expected_type)
if isnan(expected):
assert isnan(obj)
assert isnan(obj) # type: ignore[arg-type]
else:
assert obj == expected

Expand All @@ -112,7 +113,7 @@ def test_nan_and_infinity_not_allowed(
])
def test_int(json: ModuleType, s: str) -> None:
"""Test integer."""
obj: Any = json.loads(s)
obj: object = json.loads(s)
assert isinstance(obj, int)
assert obj == int(s)

Expand Down Expand Up @@ -143,8 +144,8 @@ def test_decimal_and_float(
json: ModuleType, s: str, *, use_decimal: bool,
) -> None:
"""Test decimal and float."""
obj: Any = json.loads(s, use_decimal=use_decimal)
expected_type: type = Decimal if use_decimal else float
obj: object = json.loads(s, use_decimal=use_decimal)
expected_type: type[Decimal | float] = Decimal if use_decimal else float
assert isinstance(obj, expected_type)
assert obj == expected_type(s)

Expand Down Expand Up @@ -213,7 +214,7 @@ def test_too_big_number(json: ModuleType, s: str) -> None:
('"foo"', "foo"),
(r'"foo\/bar"', "foo/bar"),
])
def test_string(json: ModuleType, s: str, expected: Any) -> None:
def test_string(json: ModuleType, s: str, expected: str) -> None:
"""Test JSON string."""
assert json.loads(s) == expected

Expand All @@ -223,7 +224,7 @@ def test_string(json: ModuleType, s: str, expected: Any) -> None:
(r'"\ud800\u0024"', "\ud800$"),
(r'"\udf48"', "\udf48"),
])
def test_surrogate_escapes(json: ModuleType, s: str, expected: Any) -> None:
def test_surrogate_escapes(json: ModuleType, s: str, expected: str) -> None:
"""Test surrogate escapes."""
assert json.loads(s, allow=SURROGATES) == expected

Expand Down Expand Up @@ -269,7 +270,7 @@ def test_invalid_string(
# Multiple values
("[1, 2, 3]", [1, 2, 3]),
]) # type: ignore
def test_array(json: ModuleType, s: str, expected: Any) -> None:
def test_array(json: ModuleType, s: str, expected: list[object]) -> None:
"""Test JSON array."""
assert json.loads(s) == expected

Expand All @@ -290,7 +291,9 @@ def test_array(json: ModuleType, s: str, expected: Any) -> None:
# After last element
("[1,2,3 ]", [1, 2, 3]),
])
def test_array_whitespace(json: ModuleType, s: str, expected: Any) -> None:
def test_array_whitespace(
json: ModuleType, s: str, expected: list[object],
) -> None:
"""Test whitespace in JSON array."""
assert json.loads(s) == expected

Expand All @@ -311,7 +314,9 @@ def test_array_whitespace(json: ModuleType, s: str, expected: Any) -> None:
# After last element
("[1,2,3/**/]", [1, 2, 3]),
])
def test_array_comments(json: ModuleType, s: str, expected: Any) -> None:
def test_array_comments(
json: ModuleType, s: str, expected: list[object],
) -> None:
"""Test comments in JSON array."""
assert json.loads(s, allow=COMMENTS) == expected

Expand Down Expand Up @@ -344,7 +349,7 @@ def test_invalid_array(
# Multiple values
('{"a": 1, "b": 2, "c": 3}', {"a": 1, "b": 2, "c": 3}),
]) # type: ignore
def test_object(json: ModuleType, s: str, expected: Any) -> None:
def test_object(json: ModuleType, s: str, expected: dict[str, object]) -> None:
"""Test JSON object."""
assert json.loads(s) == expected

Expand All @@ -371,7 +376,9 @@ def test_object(json: ModuleType, s: str, expected: Any) -> None:
# After last element
('{"a":1,"b":2,"c":3 }', {"a": 1, "b": 2, "c": 3}),
])
def test_object_whitespace(json: ModuleType, s: str, expected: Any) -> None:
def test_object_whitespace(
json: ModuleType, s: str, expected: dict[str, object],
) -> None:
"""Test whitespace in JSON object."""
assert json.loads(s) == expected

Expand All @@ -398,7 +405,9 @@ def test_object_whitespace(json: ModuleType, s: str, expected: Any) -> None:
# After last element
('{"a":1,"b":2,"c":3/**/}', {"a": 1, "b": 2, "c": 3}),
])
def test_object_comments(json: ModuleType, s: str, expected: Any) -> None:
def test_object_comments(
json: ModuleType, s: str, expected: dict[str, object],
) -> None:
"""Test comments in JSON object."""
assert json.loads(s, allow=COMMENTS) == expected

Expand Down Expand Up @@ -444,7 +453,9 @@ def test_reuse_keys(json: ModuleType) -> None:
("[1 2 3]", [1, 2, 3]),
('{"a": 1 "b": 2 "c": 3}', {"a": 1, "b": 2, "c": 3}),
])
def test_missing_commas(json: ModuleType, s: str, expected: Any) -> None:
def test_missing_commas(
json: ModuleType, s: str, expected: dict[str, object] | list[object],
) -> None:
"""Test missing comma's."""
assert json.loads(s, allow=MISSING_COMMAS) == expected

Expand All @@ -453,7 +464,9 @@ def test_missing_commas(json: ModuleType, s: str, expected: Any) -> None:
("[0,]", [0]),
('{"": 0,}', {"": 0}),
])
def test_trailing_comma(json: ModuleType, s: str, expected: Any) -> None:
def test_trailing_comma(
json: ModuleType, s: str, expected: dict[str, object] | list[object],
) -> None:
"""Test trailing comma."""
assert json.loads(s, allow=TRAILING_COMMA) == expected

Expand Down
Loading

0 comments on commit 43426ab

Please sign in to comment.