dropbox / sqlalchemy-stubs

Mypy plugin and stubs for SQLAlchemy
Apache License 2.0
570 stars 101 forks source link

Is this repository still maintained? #195

Open jd opened 3 years ago

jd commented 3 years ago

I see many issues and pull requests without any response.

Is this still being maintained and worth contributing? Anything the community can do to help?

ilevkivskyi commented 3 years ago

Unfortunately, we didn't have much time for this lately. @JukkaL what do you think we can do?

heckad commented 3 years ago

Could you submit the project to the sqlalchemy community?

Fruglemonkey commented 3 years ago

Would love if https://github.com/dropbox/sqlalchemy-stubs/pull/149 could make it into a release - this solves many long-standing annoyances we have at my org!

klaasjanelzinga commented 3 years ago

Maybe it is an idea to get new maintainers on board who do have time?

ilevkivskyi commented 3 years ago

There is a plan to switch to modular typeshed, see https://github.com/python/typeshed/issues/2491. One possible option is when this will be implemented, we can probably transfer stubs there, so they will be community maintained. It is not clear however what to do with the plugin, making changes that requires coordination between mypy plugin and stubs will be harder.

ilevkivskyi commented 3 years ago

Btw, I am going to make a release later today. Please test the current master to check if there are any issues.

klaasjanelzinga commented 3 years ago

good to see some activity again!

ilevkivskyi commented 3 years ago

I finally released sqlalchemy-stubs v0.4 on PyPI. Please try it!

wbolster commented 3 years ago

thanks @ilevkivskyi it's really appreciated 🙏

Spindel commented 3 years ago

I'm still missing the omit_join and sync_backref arguments from https://github.com/dropbox/sqlalchemy-stubs/pull/169, I've rebased against master and will run our lints against that.

Spindel commented 3 years ago

With #169 applied, our stuff goes through neatly with 0.4 release. Cheers!

zzzeek commented 3 years ago

@ilevkivskyi we are at the point now where I have time to start looking at this, as SQLAlchemy 1.4.0b2 is released, 1.4 will be next, and from there we go into 2.0 which is Python 3 only. I'd like 1.4 to have mypy support and the internals have changed enough that SQLAlchemy should first be publishing its own .pyi files + plugin, then in 2.0 it would likely all be included inline including the plugin. I observed today that mypy needs a plugin even for Python's own dataclasses, so it looks like plugins are a fixed requirement to support this kind of thing.

ilevkivskyi commented 3 years ago

Great news! Yes, a plugin is required for mypy, but it should be easy to ship it with the distribution, it is just a moderate size module. Also it is easy to enable in mypy configs, moreover I think people who have it already configured will not need to update configs after moving the plugin to SQLAlchemy (assuming you keep the module name).

zzzeek commented 3 years ago

any progress on making the plugin API less unpredictable? im referring to https://github.com/python/mypy/issues/6617. any docs yet?

ilevkivskyi commented 3 years ago

There are some docs at https://mypy.readthedocs.io/en/stable/extending_mypy.html#extending-mypy-using-plugins, it is still not 100% stable, but backwards incompatible changes are now extremely rare.

zzzeek commented 3 years ago

ah they were buried in there, thanks!

zzzeek commented 3 years ago

Great news! Yes, a plugin is required for mypy, but it should be easy to ship it with the distribution, it is just a moderate size module. Also it is easy to enable in mypy configs, moreover I think people who have it already configured will not need to update configs after moving the plugin to SQLAlchemy (assuming you keep the module name).

OK so just looking at concrete steps to get where we want, for the 1.4 series of SQLAlchemy I'm interested in updating / improving the mypy plugin (which seems at the very least some hardcoded names will have to change in order to identify mappings) as well as the stubs themselves, however the stubs would remain a separate package. Whether we are maintaining a new "stubs" package under the sqlalchemy organization, or we are sending PRs to this project, is unclear.

For the 2.0 series of SQLAlchemy, type annotations will be inline and I would hope that the mypy plugin can be shipped within the distribution. I also am considering having just the mypy plugin part as an experimental ext within SQLAlchemy 1.4 itself, so that it is easier to maintain, but it would only work if one has the stubs installed as well.

So the most immediate concern is, I want to take the the https://github.com/dropbox/sqlalchemy-stubs/blob/master/sqlmypy.py file into SQLAlchemy's codebase, which is under the MIT license, not Apache. I suppose I could place the Apache license inline with the sqlmypy.py file itself if a license change is not possible, and then that one part of SQLAlchemy would have its own license. But also how does this cover the stubs themselves, if I transfer the stubs into SQLAlchemy's inline code, those now become MIT licensed too, which still means I just switched the license.

since Dropbox is a real company and we don't want to mess around with copyright please advise what approach should be taken. Dropbox switching LICENSE to MIT would be probably most straightforward.

zzzeek commented 3 years ago

Correct me if I'm wrong but it looks like from things like https://github.com/dropbox/sqlalchemy-stubs/blob/master/sqlmypy.py#L79, the plugin makes assumptions such as, if it sees a Column object, that object is assumed to be part of a declarative mapping unconditionally (This would not really be accurate as Column objects occur in all kinds of non-ORM contexts) ? I'm comparing this approach to the one I see used for dataclasses in mypy itself at https://github.com/python/mypy/blob/master/mypy/plugins/dataclasses.py#L198, where it is only looking at attributes in terms of a class that's already known to be "a dataclass". That is, it would be more (a lot more) accurate for me to detect SQLAlchemy declarative classes first, then iterate through their attrbibutes, then make sure those attributes, columns or whatever they are, are redefined as things that work with mypy. Im just digging into this to see how this can work and I think the "dataclasses" approach is probably best.

ilevkivskyi commented 3 years ago

@JukkaL could you please help with the legal stuff?

About that Column thing: yes and no. IIRC that particular plugin hook you linked (i.e. get_function_hook()) only helps figuring out more precise type argument for the result of Column(...) call, i.e. whether it is Column[str] or Column[Optional[str]]. The "main part" of how Column works with mypy is implemented in the stubs using descriptor protocol (__get__() and __set__() that mypy supports). I know this is a "shortcut", but I was too lazy at the time implementing the actual logic involving detection of whether it is in a declarative class (also it may be tricky to implement, plus what we have now works in 99% of cases practically).

zzzeek commented 3 years ago

yeah I have an approach using descriptors "working" now but Im trying to make various things happen that sort of sometimes work and sometimes dont and I don't know why yet, because it's not clear when and how to modify these various mypy structures at what points for what effects. I can see both that this would be supremely difficult to document "what can I change when" at the same time how important it is for this to someday be documented, I'm winding up reading the source code to most of mypy anyway to understand what I can do when.

CaselIT commented 3 years ago

SQLAlchemy 1.4 added support for mypy. See the documentation

The plugin is not yet published on pypi though

orsinium commented 3 years ago

So, what is the status of sqlalchemy-stubs and sqlalchemy.ext.mypy? Is sqlalchemy.ext.mypy stable? Should sqlalchemy-stubs be deprecated in favor of the official solution?

jplhanna commented 2 years ago

Has a conclusion been made on this? I've been testing the official library and finding that it doesn't cover some of the same things that this library does, but does cover some things this library doesn't. The 2 libraries do seem to work together.

I've been testing on Python3.10 specifically.