Repository: tobymao/sqlglot

Issue:
not-sure-if-bug: strange mypy behavior in the latest sqlglot
```python
from sqlglot import parse_one, exp

a = parse_one("SELECT * FROM t").find(exp.Table)
print(a)
```

```bash
$ python -m mypy test.py
test.py:3: error: <nothing> has no attribute "find"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)
```

Could be a mypy bug or the usual mypy idiocy, but just FYI.


Discussion:
Not sure why this is happening.. any execution path in `parse_one` should either raise or return an `Expression`.

IIRC, `<nothing>` means that mypy failed to solve the type constraints [1, 2, 3, 4] introduced by the use of `TypeVar`s, so my guess is that it's either a mypy bug, or our `@t.overload` annotations are wrong for `parse_one`.

On another note: I think we should clean up `IntoType` at some point. It feels inelegant to have a `str` variant, even more so if the only reason to do have it is to enable the hack with `"JoinType"` in `EXPRESSION_PARSERS`.

[1] https://github.com/python/mypy/issues/3283
[2] https://github.com/python/mypy/blob/6f2bfff521e708f015af1eec5118db4600b829be/mypy/typeops.py#L330
[3] https://github.com/python/mypy/blob/6f2bfff521e708f015af1eec5118db4600b829be/mypy/types.py#L3013
[4] https://github.com/python/mypy/wiki/Type-Checker#join-and-meet
can you repro this @GeorgeSittas ?
> can you repro this @GeorgeSittas ?

Yeah and it seems like an issue in general, not just our latest release.
I can also verify that by getting rid of the `@t.overload`s, the error disappears

```python
# With just this mypy stopped complaining
def parse_one(
    sql: str,
    read: DialectType = None,
    into: t.Optional[exp.IntoType] = None,
    **opts,
) -> Expression:
    # Definition goes here
```
> Yeah and it seems like an issue in general, not just our latest release.

I have upgraded both mypy and sqlglot recently. But I'm not sure anymore. Maybe it was indeed happening before, but just silenced.
In any case my investigation also didn't find any problems in sqlglot type hits.
That's why "not-sure-if-bug"
Looks like it's a mypy bug: https://github.com/python/mypy/issues/10817

Resolving patch:
diff --git a/sqlglot/__init__.py b/sqlglot/__init__.py
--- a/sqlglot/__init__.py
+++ b/sqlglot/__init__.py
@@ -84,58 +84,17 @@ def parse(sql: str, read: DialectType = None, **opts) -> t.List[t.Optional[Expre
 
 
 @t.overload
-def parse_one(
-    sql: str,
-    read: None = None,
-    into: t.Type[E] = ...,
-    **opts,
-) -> E:
+def parse_one(sql: str, *, into: t.Type[E], **opts) -> E:
     ...
 
 
 @t.overload
-def parse_one(
-    sql: str,
-    read: DialectType,
-    into: t.Type[E],
-    **opts,
-) -> E:
+def parse_one(sql: str, **opts) -> Expression:
     ...
 
 
-@t.overload
 def parse_one(
-    sql: str,
-    read: None = None,
-    into: t.Union[str, t.Collection[t.Union[str, t.Type[Expression]]]] = ...,
-    **opts,
-) -> Expression:
-    ...
-
-
-@t.overload
-def parse_one(
-    sql: str,
-    read: DialectType,
-    into: t.Union[str, t.Collection[t.Union[str, t.Type[Expression]]]],
-    **opts,
-) -> Expression:
-    ...
-
-
-@t.overload
-def parse_one(
-    sql: str,
-    **opts,
-) -> Expression:
-    ...
-
-
-def parse_one(
-    sql: str,
-    read: DialectType = None,
-    into: t.Optional[exp.IntoType] = None,
-    **opts,
+    sql: str, read: DialectType = None, into: t.Optional[exp.IntoType] = None, **opts
 ) -> Expression:
     """
     Parses the given SQL string and returns a syntax tree for the first parsed SQL statement.


Test patch: