Skip to content

[WIP] Move special-cased types from semanal to a separate module #3134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from

Conversation

elazarg
Copy link
Contributor

@elazarg elazarg commented Apr 5, 2017

Following @JukkaL comment in #3102.

Along the way I've added some minor unrelated changes, such as turning methods into staticmethods when possible.

@JelleZijlstra
Copy link
Member

This conflicts with #3081.

@elazarg
Copy link
Contributor Author

elazarg commented Apr 5, 2017

@JelleZijlstra I will rebase after #3081 (and other relevant PRs) will be merged. It's only a refactoring so there's no rush. It's here for the feedback.

Copy link
Collaborator

@JukkaL JukkaL 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 cleaning things up! Some feedback based on a quick pass (this is not a full review).

mypy/semanal.py Outdated
@@ -719,7 +721,8 @@ def unbind_class_type_vars(self) -> None:
def analyze_class_decorator(self, defn: ClassDef, decorator: Expression) -> None:
decorator.accept(self)

def calculate_abstract_status(self, typ: TypeInfo) -> None:
@staticmethod
def calculate_abstract_status(typ: TypeInfo) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

By convention, we usually prefer module-level methods to static methods in the mypy codebase. This would probably be better as a module-level method. There are exceptions such as helper methods that don't make sense outside a particular class, or things that are tightly coupled with the implementations details of a class -- they may be fine as static methods. By default, we use a module-level method if we don't need self.

Rationale:

  • Module-level methods make it obvious on the call site that the method doesn't use self, and without having to use the class prefix.
  • Module-level methods are easier to move to a different module and reuse, and generally make it a bit easier to refactor code.
  • That's how most of the rest of the codebase is written, and consistency is nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You don't need to sell that to me, I completely agree :) I have used staticmethod trying to reduce the footprint of these changes, but this is pretty hopeless (and maybe not desirable, given this is a refactoring PR).

mypy/semanal.py Outdated
@@ -872,7 +856,8 @@ def get_tvars(self, tp: Type) -> List[Tuple[str, TypeVarExpr]]:
tvars.extend(self.get_tvars(arg))
return self.remove_dups(tvars)

def remove_dups(self, tvars: List[T]) -> List[T]:
@staticmethod
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be a module-level method (see above), and most new static methods are probably similar.

@@ -0,0 +1,912 @@
from collections import OrderedDict
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add module docstring.



class Special:
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Style nit: Add summary of what this class does as the first line of the docstring, followed by an empty line.

import mypy.semanal


class Special:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Find a better name for the class.

class Special:
"""
Groups special-cased types:
* NamedTuple
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if it would make sense to move the code related to various special cased types to separate classes (or top-level functions), to improve cohesion? They could all live in the same file still. It may make sense to have a single entry point to the module though. (Note that it's probably not worth using inheritance.)

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 wanted this too, but I couldn't decide how to provide the services from SemanticAnalyzer without duplication. Like you say, inheritance (for code reuse) does not sound like a good idea.

I think there are two kinds of services: lookup operations and analysis. It might be possible to refactor the lookup to a separate class (SymbolTable/Scope).

I should give it more thought.

@elazarg elazarg changed the title Move special-cased types from semanal to a separate module [WIP] Move special-cased types from semanal to a separate module Apr 7, 2017
@elazarg
Copy link
Contributor Author

elazarg commented May 10, 2017

I guess this should wait.

@elazarg elazarg closed this May 10, 2017
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.

4 participants