From 19cccc108dffaff840521d8f5eaf5aba2e611360 Mon Sep 17 00:00:00 2001 From: Devon Stewart Date: Fri, 14 Feb 2025 22:49:04 -0500 Subject: [PATCH 1/3] Whoops, knew it was too good to be true I examined the whl and thought I was safe because no lint.py was in the dist, but I neglected to grep so I missed entrypoints --- pyproject.toml | 3 +++ scripts/lint/README.md | 1 + scripts/lint/pyproject.toml | 18 ++++++++++++++++++ .../lint/src/lint/__init__.py | 0 4 files changed, 22 insertions(+) create mode 100644 scripts/lint/README.md create mode 100644 scripts/lint/pyproject.toml rename src/lint.py => scripts/lint/src/lint/__init__.py (100%) diff --git a/pyproject.toml b/pyproject.toml index acc0b3a8..4930909b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,9 @@ dev-dependencies = [ "pytest-snapshot>=0.9.0", ] +[tool.uv.workspace] +members = ["scripts/lint"] + [tool.ruff] lint.select = ["F", "E", "W", "I001"] exclude = ["*/generated/*", "*/snapshots/*"] diff --git a/scripts/lint/README.md b/scripts/lint/README.md new file mode 100644 index 00000000..842b4942 --- /dev/null +++ b/scripts/lint/README.md @@ -0,0 +1 @@ +uv run lint, in lieu of https://github.com/astral-sh/uv/issues/5903 diff --git a/scripts/lint/pyproject.toml b/scripts/lint/pyproject.toml new file mode 100644 index 00000000..c7657778 --- /dev/null +++ b/scripts/lint/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "lint" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.11, <4" +dependencies = [] + +[project.scripts] +lint = "lint:main" +format = "lint:main" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/lint"] diff --git a/src/lint.py b/scripts/lint/src/lint/__init__.py similarity index 100% rename from src/lint.py rename to scripts/lint/src/lint/__init__.py From bedaab0032ce08efacb1e62ec82c8c725f0354d6 Mon Sep 17 00:00:00 2001 From: Devon Stewart Date: Fri, 14 Feb 2025 22:49:49 -0500 Subject: [PATCH 2/3] Adding lint as a _dev_ dep this time --- pyproject.toml | 4 ++++ uv.lock | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 4930909b..639f2399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,11 +49,15 @@ dev-dependencies = [ "types-nanoid>=2.0.0.20240601", "pyright>=1.1.389", "pytest-snapshot>=0.9.0", + "lint", ] [tool.uv.workspace] members = ["scripts/lint"] +[tool.uv.sources] +lint = { workspace = true } + [tool.ruff] lint.select = ["F", "E", "W", "I001"] exclude = ["*/generated/*", "*/snapshots/*"] diff --git a/uv.lock b/uv.lock index ec9229fb..fcd7277e 100644 --- a/uv.lock +++ b/uv.lock @@ -5,6 +5,12 @@ resolution-markers = [ "python_full_version >= '3.13'", ] +[manifest] +members = [ + "lint", + "replit-river", +] + [[package]] name = "aiochannel" version = "1.2.1" @@ -223,6 +229,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, ] +[[package]] +name = "lint" +version = "0.1.0" +source = { editable = "scripts/lint" } + [[package]] name = "msgpack" version = "1.1.0" @@ -588,6 +599,7 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "deptry" }, + { name = "lint" }, { name = "msgpack-types" }, { name = "mypy" }, { name = "mypy-protobuf" }, @@ -621,6 +633,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "deptry", specifier = ">=0.14.0" }, + { name = "lint", editable = "scripts/lint" }, { name = "msgpack-types", specifier = ">=0.3.0" }, { name = "mypy", specifier = ">=1.4.0" }, { name = "mypy-protobuf", specifier = ">=3.5.0" }, From 1c55778028cadc38cc447f1fe737daf4535d9a5a Mon Sep 17 00:00:00 2001 From: Devon Stewart Date: Fri, 14 Feb 2025 22:58:03 -0500 Subject: [PATCH 3/3] Fixing two incorrect type comparisons --- src/replit_river/codegen/client.py | 28 ++++++++++++++---------- src/replit_river/codegen/typing.py | 35 ++++++++++++------------------ 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/replit_river/codegen/client.py b/src/replit_river/codegen/client.py index 3d10c0be..eaa28f55 100644 --- a/src/replit_river/codegen/client.py +++ b/src/replit_river/codegen/client.py @@ -30,6 +30,7 @@ ListTypeExpr, LiteralTypeExpr, ModuleName, + NoneTypeExpr, OpenUnionTypeExpr, RenderedPath, TypeExpression, @@ -170,7 +171,7 @@ def encode_type( encoder_name: TypeName | None = None # defining this up here to placate mypy chunks: List[FileContents] = [] if isinstance(type, RiverNotType): - return (TypeName("None"), [], [], set()) + return (NoneTypeExpr(), [], [], set()) elif isinstance(type, RiverUnionType): typeddict_encoder = list[str]() encoder_names: set[TypeName] = set() @@ -379,17 +380,17 @@ def flatten_union(tpe: RiverType) -> list[RiverType]: typeddict_encoder.append( f"encode_{render_literal_type(inner_type_name)}(x)" ) - case DictTypeExpr(_): - raise ValueError( - "What does it mean to try and encode a dict in" - " this position?" - ) case LiteralTypeExpr(const): typeddict_encoder.append(repr(const)) + case TypeName(value): + typeddict_encoder.append(f"encode_{value}(x)") + case NoneTypeExpr(): + typeddict_encoder.append("None") case other: - typeddict_encoder.append( - f"encode_{render_literal_type(other)}(x)" + _o2: DictTypeExpr | OpenUnionTypeExpr | UnionTypeExpr = ( + other ) + raise ValueError(f"What does it mean to have {_o2} here?") if permit_unknown_members: union = OpenUnionTypeExpr(UnionTypeExpr(any_of)) else: @@ -471,7 +472,7 @@ def extract_props(tpe: RiverType) -> list[dict[str, RiverType]]: return (TypeName("bool"), [], [], set()) elif type.type == "null" or type.type == "undefined": typeddict_encoder.append("None") - return (TypeName("None"), [], [], set()) + return (NoneTypeExpr(), [], [], set()) elif type.type == "Date": typeddict_encoder.append("TODO: dstewart") return (TypeName("datetime.datetime"), [], [], set()) @@ -511,8 +512,11 @@ def extract_props(tpe: RiverType) -> list[dict[str, RiverType]]: ) case LiteralTypeExpr(const): typeddict_encoder.append(repr(const)) + case TypeName(value): + typeddict_encoder.append(f"encode_{value}(x)") case other: - typeddict_encoder.append(f"encode_{render_literal_type(other)}(x)") + _o1: NoneTypeExpr | OpenUnionTypeExpr | UnionTypeExpr = other + raise ValueError(f"What does it mean to have {_o1} here?") return (DictTypeExpr(type_name), module_info, type_chunks, encoder_names) assert type.type == "object", type.type @@ -823,7 +827,7 @@ def __init__(self, client: river.Client[Any]): module_names, permit_unknown_members=True, ) - if error_type == "None": + if isinstance(error_type, NoneTypeExpr): error_type = TypeName("RiverError") else: serdes.append( @@ -916,7 +920,7 @@ def __init__(self, client: river.Client[Any]): f"Unable to derive the input encoder from: {input_type}" ) - if output_type == "None": + if isinstance(output_type, NoneTypeExpr): parse_output_method = "lambda x: None" if procedure.type == "rpc": diff --git a/src/replit_river/codegen/typing.py b/src/replit_river/codegen/typing.py index 5808a2d2..ea1f00b7 100644 --- a/src/replit_river/codegen/typing.py +++ b/src/replit_river/codegen/typing.py @@ -17,6 +17,12 @@ def __str__(self) -> str: raise Exception("Complex type must be put through render_type_expr!") +@dataclass(frozen=True) +class NoneTypeExpr: + def __str__(self) -> str: + raise Exception("Complex type must be put through render_type_expr!") + + @dataclass(frozen=True) class DictTypeExpr: nested: "TypeExpression" @@ -59,6 +65,7 @@ def __str__(self) -> str: TypeExpression = ( TypeName + | NoneTypeExpr | DictTypeExpr | ListTypeExpr | LiteralTypeExpr @@ -86,6 +93,8 @@ def render_type_expr(value: TypeExpression) -> str: ) case TypeName(name): return name + case NoneTypeExpr(): + return "None" case other: assert_never(other) @@ -112,33 +121,17 @@ def extract_inner_type(value: TypeExpression) -> TypeName: ) case TypeName(name): return TypeName(name) + case NoneTypeExpr(): + raise ValueError(f"Attempting to extract from a literal 'None': {value}") case other: assert_never(other) def ensure_literal_type(value: TypeExpression) -> TypeName: match value: - case DictTypeExpr(_): - raise ValueError( - f"Unexpected expression when expecting a type name: {value}" - ) - case ListTypeExpr(_): - raise ValueError( - f"Unexpected expression when expecting a type name: {value}" - ) - case LiteralTypeExpr(_): - raise ValueError( - f"Unexpected expression when expecting a type name: {value}" - ) - case UnionTypeExpr(_): - raise ValueError( - f"Unexpected expression when expecting a type name: {value}" - ) - case OpenUnionTypeExpr(_): - raise ValueError( - f"Unexpected expression when expecting a type name: {value}" - ) case TypeName(name): return TypeName(name) case other: - assert_never(other) + raise ValueError( + f"Unexpected expression when expecting a type name: {other}" + )