Skip to content

Conversation

@bryanforbes
Copy link
Contributor

No description provided.

Copy link
Contributor

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! New types look good. I have some comments below.

There is also a bunch of new errors in our internal codebase where Mapping[Union[str, ColumnClause[Any]], Any] is expected (in various methods), but Dict[Column[Any], Any] is given. This is caused by invariance of Mapping in key type. I am not sure what is the best way to proceed here. Probably we can come back to this problem later. Could you please open an issue for this?

def compare_values(self, x, y): ...
def comparator_factory(self) -> Type[Any]: ...
def type_engine(self, dialect: Dialect) -> TypeEngine[Any]: ...
def load_dialect_impl(self, dialect: Dialect) -> TypeEngine[Any]: ...
Copy link
Contributor

Choose a reason for hiding this comment

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

This creates a bunch of errors because some subtypes in our code are annotated as accepting defaults.DefaultDialect, could you please double-check here and in the other methods below?

(I might well be that we just need to fix annotations in our codebase.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Dialect is the "interface" and DefaultDialect is the default implementation (which inherits from Dialect). From what I can tell, dialects can technically inherit from Dialect and implement all the things they need to, but the dialects in sqlalchemy.dialects all inherit from DefaultDialect. My gut feeling is to leave it as Dialectand build up that object's properties with the properties included in docstring. I can do that in this PR if you'd like.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's just leave it as is then. We can come back to this later if there will be problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you want me to add the properties to the Default interface? If so, should the properties be abstract?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not in this PR. Maybe at some point later. I think this is relatively low priority.

def python_type(self) -> Type[list]: ...
def compare_values(self, x: _T, y: _T) -> bool: ...
def python_type(self) -> Type[List[_T]]: ...
def compare_values(self, x: Any, y: Any) -> bool: ...
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use Any here, could you please add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function just does x == y, so it can take any values. I'll add a comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, sometimes mypy prohibits things that work at runtime. For example:

def add(x: int, y: int) -> int:
    x + y

also works for strings before one adds types. Anyway, if you are sure it is intended to be used with arbitrary objects, then object instead of Any would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I traced this to where it's used and it looks to be used within sqlalchemy.orm.strategies and sqlalchemy.orm.attributes where if compare_function is not provided, operator.eq is used and operator.eq is def eq(a: Any, b: Any) -> Any: .... I'm reasonably confident that Any, Any is fine here.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK

@bryanforbes
Copy link
Contributor Author

I went ahead and made sure that the Mapping[] types have the right permutations. Let me know if that works.

def __getattr__(self, attr: str) -> Any: ...

_ValuesType = Optional[Union[Mapping[str, Any],
Mapping[ColumnClause[Any], Any],
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you might need to also add Mapping[Column[Any], Any] to the union, otherwise the errors I found in our codebases will remain (since Dict[Column[Any], Any] is not a subtype of this because Mapping is invariant in key type).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, you said invariant and I interpreted it as covariant. Now I understand the issue. Maybe we should use Mapping[Any, Any] for now and then possibly create our own mapping type that is covariant.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, It looks like Mapping[Any, Any] is the best option for now. Could you please also add a comment explaining why we don't use "more precise" types?

@ilevkivskyi
Copy link
Contributor

Thanks for the updates! This is almost ready to go, I left few small comments.

@bryanforbes
Copy link
Contributor Author

I pushed the fixes for TypeDecorator and left some replies.

Copy link
Contributor

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

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

LGTM! I will merge when tests pass.

@ilevkivskyi ilevkivskyi merged commit b772662 into dropbox:master Jan 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants