Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

Convert to attrs, remove runtype #723

Merged
merged 7 commits into from
Oct 2, 2023
Merged

Convert to attrs, remove runtype #723

merged 7 commits into from
Oct 2, 2023

Conversation

nolar
Copy link
Collaborator

@nolar nolar commented Oct 2, 2023

A replay of accidentally closed #720.

Short-term goal: resolve an issue where runtype cannot check isinstance() check, where the type is a string "Database" coming from Compilar.database: "Database".

Technically, it is a typing.ForwardRef[] and must be resolved to actual classes on usage. attrs and pydantic do that.

There is no way to convert it to a regular class, because there is still a circular class dependency Database <> Compiler.


Long-term goal: Since we are moving in the direction of strict type checking, let's make the first step: replace runtype with lots of implicit logic and not compatible with MyPy, with attrs, which require explicitness and work fine with MyPy & IDEs.

attrs is much more beneficial:

  • attrs is supported by type checkers, such as MyPy & IDEs
  • attrs is widely used and industry-proven
  • attrs is explicit in its declarations, there is no magic
  • attrs has slots

But mainly for the first item — type checking by type checkers.

And since we switch to attrs for already dataclass-like types, also expand it to all other (unannotated) classes to ensure proper attribute management in multiple inheritance.

In particular, in the last commit, there are a few cases where the code was ambiguous and had to be resolved by minor remakes.


It is better to review commit-by-commit.

@nolar nolar force-pushed the fix-aftermath-of-refactoring branch from 6be7a94 to 902fcc6 Compare October 2, 2023 11:58
@nolar nolar changed the base branch from fix-aftermath-of-refactoring to master October 2, 2023 13:36
tests/test_sql.py Outdated Show resolved Hide resolved
Copy link
Contributor

@dlawin dlawin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should merge master in after #722 to validate tests are fixed

Always, always, always call the inherited constructor — even if it does nothing. If not called, it breaks the MRO chain of inheritance and complicates the mixin/class building.

This must be a linting rule.
`attrs` cannot use multiple inheritance when both parents introduce their attributes (as documented). Only one side can inherit the attributes, other bases must be pure interfaces/protocols.

Reimplement the `ExprNode.type` via properties to exclude it from the sight of `attrs`.
We are going to do strict type checking. The default values of fields that clearly contradict the declared types is an error for MyPy and all other type checkers and IDEs.

Remove the implicit behaviour and make nullable fields explicitly declared as such.
`attrs` is much more beneficial:

* `attrs` is supported by type checkers, such as MyPy & IDEs
* `attrs` is widely used and industry-proven
* `attrs` is explicit in its declarations, there is no magic
* `attrs` has slots

But mainly for the first item — type checking by type checkers.

Those that were runtype classes, are frozen. Those that were not, are unfrozen for now, but we can freeze them later if and where it works (the stricter, the better).
Since we now use `attrs` for some classes, let's use `attrs` for them all — at least those belonging to the same hierarchies.

This will ensure that all classes are slotted and will strictly check that we define attributes properly, especially in cases of multiple inheritance.

Except for Pydantic models and Python exceptions.

Despite the attrs classes are not frozen by default, we keep it explicitly stated, so that we see which classes were or were not frozen before the switch from runtype to attrs. We can later freeze more classes if/when it works (the stricter, the better). For this reason, we never unfreeze classes that were previously frozen.

->?
@nolar nolar merged commit 7a7cd4a into master Oct 2, 2023
5 of 6 checks passed
@nolar nolar deleted the attrs-instead-of-runtype branch October 2, 2023 18:47
@erezsh
Copy link
Contributor

erezsh commented Oct 13, 2023

@nolar Just for the record, runtype does support forward-refs and slots, you only had to upgrade to a later version.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants