Skip to content

Commit 61404c4

Browse files
authored
Merge pull request #1615 from google/google_sync
Google sync
2 parents 8808ade + 8100dea commit 61404c4

15 files changed

Lines changed: 190 additions & 12 deletions

CHANGELOG

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
Version 2024.04.11:
2+
3+
Updates:
4+
* Change error message hint to suggest `X | None` rather than `Optional[X]`.
5+
6+
Bug fixes:
7+
* Take the 'maybe_missing_members' attribute into account when setting up enum
8+
classes.
9+
* Fix a bug in signature compatibility checking.
10+
* Teach main.py how to fix unescaped spaces in command-line arguments.
11+
* Fix return type of exit() and quit().
12+
* Update pytype_runner.py - change escape_ninja_path to escape all the ninja
13+
path escape-needing characters
14+
* Modify type annotations for coroutines as soon as they are created.
15+
* Fully promote __init_subclass__ to a classmethod.
16+
117
Version 2024.03.19:
218

319
Updates:

pytype/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# pylint: skip-file
2-
__version__ = '2024.03.19'
2+
__version__ = '2024.04.11'

pytype/rewrite/abstract/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ py_library(
6868
containers.py
6969
DEPS
7070
.base
71+
.internal
72+
.utils
7173
)
7274

7375
py_test(

pytype/rewrite/abstract/classes_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,23 @@ def test_get_attribute(self):
5858
self.assertEqual(instance.get_attribute('x'), self.ctx.consts[3])
5959

6060

61+
class ModuleTest(test_utils.ContextfulTestBase):
62+
63+
def test_instance_attribute(self):
64+
attr = classes.Module(self.ctx, 'os').get_attribute('name')
65+
self.assertIsInstance(attr, classes.FrozenInstance)
66+
self.assertEqual(attr.cls.name, 'str')
67+
68+
def test_class_attribute(self):
69+
attr = classes.Module(self.ctx, 'os').get_attribute('__name__')
70+
self.assertIsInstance(attr, classes.FrozenInstance)
71+
self.assertEqual(attr.cls.name, 'str')
72+
73+
def test_submodule(self):
74+
attr = classes.Module(self.ctx, 'os').get_attribute('path')
75+
self.assertIsInstance(attr, classes.Module)
76+
self.assertEqual(attr.name, 'os.path')
77+
78+
6179
if __name__ == '__main__':
6280
unittest.main()

pytype/rewrite/abstract/containers.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from typing import Dict as _Dict, List as _List, Set as _Set, Tuple as _Tuple
66

77
from pytype.rewrite.abstract import base
8+
from pytype.rewrite.abstract import internal
9+
from pytype.rewrite.abstract import utils
810

911
log = logging.getLogger(__name__)
1012

@@ -25,6 +27,19 @@ def __repr__(self):
2527
def append(self, val: _Variable):
2628
self.constant.append(val)
2729

30+
def extend(self, val: _Variable):
31+
try:
32+
const = utils.get_atomic_constant(val)
33+
if not isinstance(const, list):
34+
const = None
35+
except ValueError:
36+
const = None
37+
38+
if const:
39+
self.constant.extend(const)
40+
else:
41+
self.constant.append(internal.Splat(self._ctx, val).to_variable())
42+
2843

2944
class Dict(base.PythonConstant[_Dict[_Variable, _Variable]]):
3045
"""Representation of a Python dict."""
@@ -34,13 +49,27 @@ def __init__(
3449
):
3550
assert isinstance(constant, dict), constant
3651
super().__init__(ctx, constant)
52+
self.indefinite = False
3753

3854
def __repr__(self):
3955
return f'Dict({self.constant!r})'
4056

4157
def setitem(self, key, val):
4258
self.constant[key] = val
4359

60+
def update(self, val: _Variable):
61+
try:
62+
const = utils.get_atomic_constant(val)
63+
if not isinstance(const, dict):
64+
const = None
65+
except ValueError:
66+
const = None
67+
68+
if const:
69+
self.constant.update(const)
70+
else:
71+
self.indefinite = True
72+
4473

4574
class Set(base.PythonConstant[_Set[_Variable]]):
4675
"""Representation of a Python set."""

pytype/rewrite/abstract/functions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class Args(Generic[_FrameT]):
5757
"""Arguments to one function call."""
5858
posargs: Tuple[base.AbstractVariableType, ...] = ()
5959
kwargs: Mapping[str, base.AbstractVariableType] = _EMPTY_MAP
60+
starargs: Optional[base.AbstractVariableType] = None
61+
starstarargs: Optional[base.AbstractVariableType] = None
6062
frame: Optional[_FrameT] = None
6163

6264

pytype/rewrite/abstract/internal.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Abstract types used internally by pytype."""
22

3-
from typing import Dict, Sequence, Tuple
3+
from typing import Dict, Tuple
44

55
import immutabledict
66

@@ -54,9 +54,9 @@ class Splat(base.BaseValue):
5454
(x, *ys, z) in starargs) and let the function arg matcher unpack them.
5555
"""
5656

57-
def __init__(self, ctx: base.ContextType, iterable: Sequence[_Variable]):
57+
def __init__(self, ctx: base.ContextType, iterable: _Variable):
5858
super().__init__(ctx)
59-
self.iterable = tuple(iterable)
59+
self.iterable = iterable
6060

6161
def __repr__(self):
6262
return f"splat({self.iterable!r})"

pytype/rewrite/abstract/internal_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ class SplatTest(test_utils.ContextfulTestBase):
2121

2222
def test_basic(self):
2323
# Basic smoke test, remove when we have some real functionality to test.
24-
seq = [self.ctx.consts[i].to_variable() for i in range(3)]
24+
cls = self.ctx.abstract_loader.load_raw_type(tuple)
25+
seq = cls.instantiate().to_variable()
2526
x = internal.Splat(self.ctx, seq)
26-
self.assertEqual(x.iterable, tuple(seq))
27+
self.assertEqual(x.iterable, seq)
2728

2829

2930
if __name__ == '__main__':

pytype/rewrite/convert.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,9 @@ def _pytd_type_to_value(self, typ: pytd.Type) -> abstract.BaseValue:
107107
f'Abstract conversion not yet implemented for {typ}')
108108
else:
109109
raise ValueError(f'Cannot convert {typ} to an abstract value')
110+
111+
def pytd_alias_to_value(self, alias: pytd.Alias) -> abstract.BaseValue:
112+
if isinstance(alias.type, pytd.Module):
113+
return abstract.Module(self._ctx, alias.type.module_name)
114+
raise NotImplementedError(
115+
f'Abstract conversion not yet implemented for {alias}')

pytype/rewrite/convert_test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,14 @@ class D: ...
9292
self.assertEqual(nested_class.name, 'D')
9393

9494

95+
class PytdAliasToValueTest(ConverterTestBase):
96+
97+
def test_alias(self):
98+
alias = self.build_pytd('import os.path', name='os.path')
99+
module = self.conv.pytd_alias_to_value(alias)
100+
self.assertIsInstance(module, abstract.Module)
101+
self.assertEqual(module.name, 'os.path')
102+
103+
95104
if __name__ == '__main__':
96105
unittest.main()

0 commit comments

Comments
 (0)