-
Notifications
You must be signed in to change notification settings - Fork 14
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
Enable mypy's check_untyped_defs #6444
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# type: ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Product/plugin code might need more time consuming refactor to typecheck. Just ignoring it for now to be able to enable check_untyped_defs |
||
from lms.product.plugin.course_copy import CourseCopyPlugin | ||
from lms.product.plugin.grouping import GroupingPlugin | ||
from lms.product.plugin.misc import MiscPlugin | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from typing import Callable | ||
from typing import Any, Callable | ||
|
||
from lms.models import File | ||
from lms.services.exceptions import ExternalRequestError, OAuth2TokenError | ||
|
@@ -20,7 +20,7 @@ def is_file_in_course(self, course_id, file_id, type_) -> bool: | |
|
||
def find_matching_file_in_course( | ||
self, | ||
store_new_course_files: Callable[[str], None], | ||
store_new_course_files: Callable[[str], Any] | Callable[[int], Any], | ||
file_type: str, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be useful if this function had docs to clarify what the "non-obvious" parameters are and what the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... interesting. In TypeScript we use This fails to typecheck: from typing import Callable
def do_something(callback: Callable[[str], None]) -> None:
callback("foo")
def bar(arg: str) -> str:
return arg + arg
do_something(bar) This does work, but requires boilerplate: from typing import Callable, TypeVar
R = TypeVar("R", covariant=True)
def do_something(callback: Callable[[str], R]) -> None:
callback("foo")
def bar(arg: str) -> str:
return arg + arg
do_something(bar) To be clear, this is just me being curious. I think |
||
original_file_id, | ||
new_course_id, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# type: ignore | ||
from dataclasses import dataclass | ||
from typing import cast | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,14 +52,14 @@ def __init__(self, application_instance: ApplicationInstance): | |
) | ||
|
||
|
||
def _email_or_domain_match(columns, email): | ||
def _email_or_domain_match(columns, email: str): | ||
""" | ||
Get an SQL comparator for matching emails. | ||
|
||
This will match the full email if it contains '@' or interpret the text | ||
as a domain if not. This will search over all the provided fields. | ||
""" | ||
return sa.or_( | ||
return sa.or_( # type: ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the issue here? Also, can you add a comments alongside the
As TS fortunately allows us to add notes for future readers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One other useful thing TS can do is to indicate that you expect an error:
This will cause a warning or error if the suppression subsequently becomes unnecessary. Is there a mechanism in mypy to inform us if a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, we'll get an error for those with the current conf 👍 |
||
( | ||
sa.func.lower(column) == email.lower() | ||
if "@" in email | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -400,7 +400,7 @@ def course_infos(self): | |
|
||
for row in self._db.execute(query): | ||
# SQLAlchemy returns None instead of []. | ||
authority_provided_ids = row.authority_provided_ids or [] | ||
row_authority_provided_ids = row.authority_provided_ids or [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was re-typing a variable from the outer scope. |
||
instructor_h_userids = row.instructor_h_userids or [] | ||
|
||
self._course_infos.append( | ||
|
@@ -411,7 +411,8 @@ def course_infos(self): | |
learner_annotations=tuple( | ||
annotation | ||
for annotation in self.annotations | ||
if annotation.authority_provided_id in authority_provided_ids | ||
if annotation.authority_provided_id | ||
in row_authority_provided_ids | ||
and annotation.userid not in instructor_h_userids | ||
), | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,7 +50,7 @@ def __init__(self, request) -> None: | |
self.organization_service: OrganizationService = request.find_service( | ||
OrganizationService | ||
) | ||
self.organization_usage_report_service: OrganizationService = ( | ||
self.organization_usage_report_service: OrganizationUsageReportService = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the wrong annotation. |
||
request.find_service(OrganizationUsageReportService) | ||
) | ||
|
||
|
@@ -155,6 +155,7 @@ def toggle_organization_enabled(self): | |
request_org_id = self.request.matchdict["id_"] | ||
for org_id in self.organization_service.get_hierarchy_ids(request_org_id): | ||
org = self.organization_service.get_by_id(org_id) | ||
assert org, "Organization {org_id} not found" | ||
self.organization_service.update_organization( | ||
org, enabled=self.request.params.get("enabled", "") == "on" | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,9 +75,9 @@ def via_url(self): | |
) | ||
|
||
document_url = self.request.params["document_url"] | ||
file_id = course.get_mapped_file_id( | ||
DOCUMENT_URL_REGEX.search(document_url)["file_id"] | ||
) | ||
document_url_match = DOCUMENT_URL_REGEX.search(document_url) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a few of these, assert that we expect the regex to always be successful. |
||
assert document_url_match | ||
file_id = course.get_mapped_file_id(document_url_match["file_id"]) | ||
try: | ||
if self.request.lti_user.is_instructor: | ||
if not self.course_copy_plugin.is_file_in_course(course_id, file_id): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -266,7 +266,7 @@ def _configure_assignment(self, assignment): | |
) | ||
|
||
def _configure_js_for_file_picker( | ||
self, assignment: Assignment, route: str = "configure_assignment" | ||
self, assignment: Assignment | None, route: str = "configure_assignment" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. _configure_js_for_file_picker takes an empty assignment when first creating an assignment. |
||
) -> dict: | ||
""" | ||
Show the file-picker for the user to choose a document. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -225,7 +225,7 @@ python_version = 3.11 | |
warn_unused_configs = true | ||
warn_redundant_casts = true | ||
warn_unused_ignores = true | ||
|
||
check_untyped_defs = true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main goal of this: Type-checks the interior of functions without type annotations. |
||
|
||
disable_error_code = [ | ||
"import-untyped", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I note in the docs that
lazy="dynamic"
is a deprecated feature. Is it planned to migrate to the new thing at some point?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assigned this small note to myself, I don't think it's that urgent to migrate away.
We'd keep this in mind to avoid adding new usages of it.