Skip to content

Commit fe8858d

Browse files
committed
--ide flag
1 parent ca0ae4a commit fe8858d

20 files changed

+234
-43
lines changed

.mypy/baseline.json

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4771,7 +4771,7 @@
47714771
"code": "truthy-bool",
47724772
"column": 11,
47734773
"message": "Member \"options\" has type \"Options\" which does not implement __bool__ or __len__ so it could always be true in boolean context",
4774-
"offset": 735,
4774+
"offset": 738,
47754775
"src": "if self.options:",
47764776
"target": "mypy.errors.Errors.is_error_code_enabled"
47774777
},
@@ -4787,15 +4787,15 @@
47874787
"code": "truthy-bool",
47884788
"column": 69,
47894789
"message": "Member \"options\" has type \"Options\" which does not implement __bool__ or __len__ so it could always be true in boolean context",
4790-
"offset": 52,
4790+
"offset": 53,
47914791
"src": "is_typeshed_file(self.options.abs_custom_typeshed_dir if self.options else None, file)",
47924792
"target": "mypy.errors.Errors.generate_ignore_without_code_errors"
47934793
},
47944794
{
47954795
"code": "unreachable",
47964796
"column": 16,
47974797
"message": "Statement is unreachable",
4798-
"offset": 374,
4798+
"offset": 379,
47994799
"src": "result.append(",
48004800
"target": "mypy.errors.Errors.render_messages"
48014801
}
@@ -7305,7 +7305,7 @@
73057305
"code": "no-any-expr",
73067306
"column": 16,
73077307
"message": "Expression type contains \"Any\" (has type \"list[Any]\")",
7308-
"offset": 254,
7308+
"offset": 257,
73097309
"src": "default=[],",
73107310
"target": "mypy.main.process_options"
73117311
},
@@ -7337,7 +7337,7 @@
73377337
"code": "no-any-expr",
73387338
"column": 67,
73397339
"message": "Expression type contains \"Any\" (has type \"list[Any]\")",
7340-
"offset": 283,
7340+
"offset": 285,
73417341
"src": "\"--package-root\", metavar=\"ROOT\", action=\"append\", default=[], help=argparse.SUPPRESS",
73427342
"target": "mypy.main.process_options"
73437343
},
@@ -7417,7 +7417,7 @@
74177417
"code": "no-any-expr",
74187418
"column": 11,
74197419
"message": "Expression type contains \"Any\" (has type \"dict[str, Any]\")",
7420-
"offset": 20,
7420+
"offset": 22,
74217421
"src": "if not dummy.__dict__[\"special-opts:strict\"]:",
74227422
"target": "mypy.main.process_options"
74237423
},
@@ -7433,15 +7433,23 @@
74337433
"code": "no-any-expr",
74347434
"column": 49,
74357435
"message": "Expression has type \"Any\"",
7436-
"offset": 8,
7436+
"offset": 17,
74377437
"src": "parse_config_file(options, set_strict_flags, config_file, stdout, stderr)",
74387438
"target": "mypy.main.process_options"
74397439
},
7440+
{
7441+
"code": "no-any-expr",
7442+
"column": 7,
7443+
"message": "Expression has type \"Any\"",
7444+
"offset": 4,
7445+
"src": "if dummy.ide:",
7446+
"target": "mypy.main.process_options"
7447+
},
74407448
{
74417449
"code": "no-any-expr",
74427450
"column": 29,
74437451
"message": "Expression has type \"Any\"",
7444-
"offset": 14,
7452+
"offset": 15,
74457453
"src": "options.python_version = special_opts.python_version or options.python_version",
74467454
"target": "mypy.main.process_options"
74477455
},
@@ -8707,6 +8715,14 @@
87078715
"src": "return repr(self)",
87088716
"target": "mypy.nodes.Node.__str__"
87098717
},
8718+
{
8719+
"code": "unreachable",
8720+
"column": 12,
8721+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-unreachable for more info",
8722+
"offset": 0,
8723+
"src": "return repr(self)",
8724+
"target": null
8725+
},
87108726
{
87118727
"code": "no-any-expr",
87128728
"column": 15,
@@ -9249,7 +9265,7 @@
92499265
"code": "no-any-expr",
92509266
"column": 18,
92519267
"message": "Expression has type \"Any\"",
9252-
"offset": 111,
9268+
"offset": 122,
92539269
"src": "MACHDEP = sysconfig.get_config_var(\"MACHDEP\")",
92549270
"target": "mypy.options.Options.__init__"
92559271
},
@@ -9273,7 +9289,7 @@
92739289
"code": "no-any-explicit",
92749290
"column": 8,
92759291
"message": "Explicit \"Any\" is not allowed",
9276-
"offset": 257,
9292+
"offset": 258,
92779293
"src": "self.transform_source: Callable[[Any], Any] | None = None",
92789294
"target": "mypy.options.Options.__init__"
92799295
},
@@ -9395,6 +9411,14 @@
93959411
"src": "def add_symbol_table_node(self, name: str, stnode: SymbolTableNode) -> Any:",
93969412
"target": "mypy.plugin"
93979413
},
9414+
{
9415+
"code": "no-any-decorated",
9416+
"column": 4,
9417+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-no-any-decorated for more info",
9418+
"offset": 0,
9419+
"src": "def add_symbol_table_node(self, name: str, stnode: SymbolTableNode) -> Any:",
9420+
"target": null
9421+
},
93989422
{
93999423
"code": "no-any-explicit",
94009424
"column": 4,
@@ -11035,6 +11059,14 @@
1103511059
"src": "self.__dict__[\"_standard_namespace\"] = standard_namespace",
1103611060
"target": "mypy.split_namespace.SplitNamespace.__init__"
1103711061
},
11062+
{
11063+
"code": "no-any-expr",
11064+
"column": 8,
11065+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-no-any-expr for more info",
11066+
"offset": 0,
11067+
"src": "self.__dict__[\"_standard_namespace\"] = standard_namespace",
11068+
"target": null
11069+
},
1103811070
{
1103911071
"code": "no-any-expr",
1104011072
"column": 8,
@@ -11059,6 +11091,14 @@
1105911091
"src": "def _get(self) -> tuple[Any, Any]:",
1106011092
"target": "mypy.split_namespace.SplitNamespace._get"
1106111093
},
11094+
{
11095+
"code": "no-any-explicit",
11096+
"column": 4,
11097+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-no-any-explicit for more info",
11098+
"offset": 0,
11099+
"src": "def _get(self) -> tuple[Any, Any]:",
11100+
"target": null
11101+
},
1106211102
{
1106311103
"code": "no-any-expr",
1106411104
"column": 15,
@@ -12605,6 +12645,14 @@
1260512645
"src": "if module:",
1260612646
"target": "mypy.stubgenc.strip_or_import"
1260712647
},
12648+
{
12649+
"code": "truthy-bool",
12650+
"column": 7,
12651+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-truthy-bool for more info",
12652+
"offset": 0,
12653+
"src": "if module:",
12654+
"target": null
12655+
},
1260812656
{
1260912657
"code": "no-any-expr",
1261012658
"column": 8,
@@ -12661,6 +12709,14 @@
1266112709
"src": "if arg_module not in local_modules:",
1266212710
"target": "mypy.stubgenc"
1266312711
},
12712+
{
12713+
"code": "possibly-undefined",
12714+
"column": 11,
12715+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-possibly-undefined for more info",
12716+
"offset": 0,
12717+
"src": "if arg_module not in local_modules:",
12718+
"target": null
12719+
},
1266412720
{
1266512721
"code": "no-any-expr",
1266612722
"column": 31,
@@ -15133,6 +15189,14 @@
1513315189
"src": "suite = parent.obj()",
1513415190
"target": "mypy.test.data.DataDrivenTestCase.runtest"
1513515191
},
15192+
{
15193+
"code": "no-untyped-usage",
15194+
"column": 8,
15195+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-no-untyped-usage for more info",
15196+
"offset": 0,
15197+
"src": "suite = parent.obj()",
15198+
"target": null
15199+
},
1513615200
{
1513715201
"code": "no-any-expr",
1513815202
"column": 16,
@@ -15587,7 +15651,7 @@
1558715651
"code": "no-any-expr",
1558815652
"column": 7,
1558915653
"message": "Expression has type \"Untyped\"",
15590-
"offset": 111,
15654+
"offset": 115,
1559115655
"src": "if testcase.config.getoption(\"--mypy-verbose\"):",
1559215656
"target": "mypy.test.helpers.parse_options"
1559315657
},
@@ -15729,7 +15793,7 @@
1572915793
"code": "no-any-expr",
1573015794
"column": 13,
1573115795
"message": "Expression type contains \"Any\" (has type \"int | Any\")",
15732-
"offset": 48,
15796+
"offset": 52,
1573315797
"src": "result = process.returncode",
1573415798
"target": "mypy.test.testcmdline.test_python_cmdline"
1573515799
},
@@ -16211,7 +16275,7 @@
1621116275
"code": "possibly-undefined",
1621216276
"column": 22,
1621316277
"message": "Name \"program\" may be undefined",
16214-
"offset": 162,
16278+
"offset": 170,
1621516279
"src": "os.remove(program)",
1621616280
"target": "mypy.test.testpep561"
1621716281
},
@@ -16385,7 +16449,7 @@
1638516449
"code": "no-any-explicit",
1638616450
"column": 0,
1638716451
"message": "Explicit \"Any\" is not allowed",
16388-
"offset": 142,
16452+
"offset": 144,
1638916453
"src": "def collect_cases(fn: Callable[..., Iterator[Case]]) -> Callable[..., None]:",
1639016454
"target": "mypy.test.teststubtest.collect_cases"
1639116455
},
@@ -18933,6 +18997,14 @@
1893318997
"src": "def visit_mypy_file(self, o: mypy.nodes.MypyFile) -> T:",
1893418998
"target": "mypy.visitor.NodeVisitor.visit_mypy_file"
1893518999
},
19000+
{
19001+
"code": "empty-body",
19002+
"column": 4,
19003+
"message": "See https://kotlinisland.github.io/basedmypy/_refs.html#code-empty-body for more info",
19004+
"offset": 0,
19005+
"src": "def visit_mypy_file(self, o: mypy.nodes.MypyFile) -> T:",
19006+
"target": null
19007+
},
1893619008
{
1893719009
"code": "empty-body",
1893819010
"column": 4,
@@ -22129,7 +22201,7 @@
2212922201
"code": "no-any-expr",
2213022202
"column": 7,
2213122203
"message": "Expression type contains \"Any\" (has type \"False | Untyped\")",
22132-
"offset": 95,
22204+
"offset": 96,
2213322205
"src": "if expected_output != actual and testcase.config.getoption(\"--update-data\", False):",
2213422206
"target": "mypyc.test.testutil.assert_test_output"
2213522207
},

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
### Added
55
- `TypeGuard` is retained in inferred types (#504)
66
- Type narrowing is applied from lambda execution (#504)
7+
- `--ide` flag (#501)
78
### Enhancements
9+
- `show-error-context`/`pretty` are now on by default (#501)
10+
- Show fake column number when `--show-error-end` (#501)
811
### Fixes
912
- Don't show "X defined here" when error context is hidden (#498)
1013
- Fix issue with reveal code in ignore message (#490)

docs/source/command_line.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ You can read more :ref:`here <baseline>`.
156156
Based features
157157
**************
158158

159+
.. option:: --ide
160+
161+
Preset options for best compatibility with an integrated developer environment.
162+
159163
.. option:: --default-return
160164

161165
See :confval:`default_return`.

mypy/dmypy/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self, prog: str) -> None:
4646
"-V",
4747
"--version",
4848
action="version",
49-
version=f"Basedmypy Daemon {__based_version__}\nBased on %(prog)s {__version__}",
49+
version=f"Basedmypy-Daemon {__based_version__}\nBased on %(prog)s {__version__}",
5050
help="Show program's version number and exit",
5151
)
5252
subparsers = parser.add_subparsers()

mypy/errors.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@
4949
codes.NAME_DEFINED,
5050
# Overrides have a custom link to docs
5151
codes.OVERRIDE,
52+
codes.REVEAL,
5253
}
5354

5455
allowed_duplicates: Final = ["@overload", "Got:", "Expected:"]
5556

56-
BASE_RTD_URL: Final = "https://mypy.rtfd.io/en/stable/_refs.html#code"
57+
BASE_RTD_URL: Final = "https://kotlinisland.github.io/basedmypy/_refs.html#code"
5758

5859
# Keep track of the original error code when the error code of a message is changed.
5960
# This is used to give notes about out-of-date "type: ignore" comments.
@@ -648,8 +649,9 @@ def add_error_info(self, info: ErrorInfo) -> None:
648649
and info.code not in HIDE_LINK_CODES
649650
):
650651
message = f"See {BASE_RTD_URL}-{info.code.code} for more info"
651-
if message in self.only_once_messages:
652+
if not self.options.ide and message in self.only_once_messages:
652653
return
654+
info_ = info
653655
self.only_once_messages.add(message)
654656
info = ErrorInfo(
655657
import_ctx=info.import_ctx,
@@ -669,6 +671,7 @@ def add_error_info(self, info: ErrorInfo) -> None:
669671
allow_dups=False,
670672
priority=20,
671673
)
674+
info_.notes.append(info)
672675
self._add_error_info(file, info)
673676

674677
def has_many_errors(self) -> bool:
@@ -793,6 +796,7 @@ def generate_unused_ignore_errors(self, file: str) -> None:
793796
narrower = set(used_ignored_codes) & codes.sub_code_map[unused]
794797
if narrower:
795798
message += f", use narrower [{', '.join(narrower)}] instead of [{unused}] code"
799+
796800
# Don't use report since add_error_info will ignore the error!
797801
info = ErrorInfo(
798802
import_ctx=self.import_context(),
@@ -1185,11 +1189,16 @@ def render_messages(
11851189
)
11861190
)
11871191
src = (
1188-
file == current_file
1189-
and source_lines
1190-
and e.line > 0
1191-
and source_lines[e.line - 1].strip()
1192+
file == current_file and source_lines and e.line > 0 and source_lines[e.line - 1]
11921193
) or ""
1194+
# when there is no column, but we still want an ide to show an error
1195+
if e.column == -1 and self.options.show_error_end:
1196+
if src:
1197+
e.column = src.find(src.strip())
1198+
e.end_column = len(src)
1199+
else:
1200+
e.column = 1
1201+
src = src.strip()
11931202
if isinstance(e.message, ErrorMessage):
11941203
result.append(
11951204
(

0 commit comments

Comments
 (0)