Skip to content

Commit 30d84c3

Browse files
committed
Fix a 'duplicate top-level identifier' pyi issue.
We were generating a bad pyi for 'from datetime import datetime' that defined 'datetime' twice (once via an 'import datetime' line and again as a 'datetime: Type[datetime.datetime' constant). Fixed by changing the import statement to 'import datetime as _datetime'. Resolves #1057. PiperOrigin-RevId: 411930502
1 parent bf718ab commit 30d84c3

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

pytype/pytd/printer.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,14 @@ def _UseExistingModuleAlias(self, name):
441441
def _GuessModule(self, maybe_module):
442442
"""Guess which part of the given name is the module prefix."""
443443
if "." not in maybe_module:
444-
return maybe_module
444+
return maybe_module, ""
445445
prefix, suffix = maybe_module.rsplit(".", 1)
446446
# Heuristic: modules are typically lowercase, classes uppercase.
447447
if suffix[0].islower():
448-
return maybe_module
448+
return maybe_module, ""
449449
else:
450-
return self._GuessModule(prefix)
450+
module, rest = self._GuessModule(prefix)
451+
return module, f"{rest}.{suffix}" if rest else suffix
451452

452453
def VisitNamedType(self, node):
453454
"""Convert a type to a string."""
@@ -467,8 +468,16 @@ def VisitNamedType(self, node):
467468
if aliased_name:
468469
node_name = aliased_name
469470
else:
470-
self._RequireImport(self._GuessModule(prefix))
471-
node_name = node.name
471+
module, rest = self._GuessModule(prefix)
472+
module_alias = module
473+
while self._NameCollision(module_alias):
474+
module_alias = f"_{module_alias}"
475+
if module_alias == module:
476+
self._RequireImport(module)
477+
node_name = node.name
478+
else:
479+
self._RequireImport(f"{module} as {module_alias}")
480+
node_name = ".".join(filter(bool, (module_alias, rest, suffix)))
472481
else:
473482
node_name = node.name
474483
else:

pytype/tests/test_import2.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ def test_import_attribute_error(self):
6565
print(err.name)
6666
""")
6767

68+
def test_datetime_datetime(self):
69+
with self.DepTree([("foo.py", "from datetime import datetime")]):
70+
self.Check("""
71+
import foo
72+
assert_type(foo.datetime(1, 1, 1), "datetime.datetime")
73+
""")
74+
6875

6976
if __name__ == "__main__":
7077
test_base.main()

0 commit comments

Comments
 (0)