Merge pull request #1885 from asford/attrs_support

Extend dataclass constructor hinting to attrs next-gen apis.
This commit is contained in:
Dave Halter
2022-10-13 19:12:59 +00:00
committed by GitHub
4 changed files with 54 additions and 0 deletions

View File

@@ -6,6 +6,8 @@ Changelog
Unreleased
++++++++++
- Added dataclass-equivalent for attrs.define
0.18.1 (2021-11-17)
+++++++++++++++++++

View File

@@ -803,6 +803,15 @@ _implemented = {
# For now this works at least better than Jedi trying to understand it.
'dataclass': _dataclass
},
# attrs exposes declaration interface roughly compatible with dataclasses
# via attrs.define, attrs.frozen and attrs.mutable
# https://www.attrs.org/en/stable/names.html
'attr': {
'define': _dataclass,
},
'attrs': {
'define': _dataclass,
},
'os.path': {
'dirname': _create_string_input_function(os.path.dirname),
'abspath': _create_string_input_function(os.path.abspath),

View File

@@ -41,6 +41,7 @@ setup(name='jedi',
# coloroma for colored debug output
'colorama',
'Django<3.1', # For now pin this.
'attrs',
],
'qa': [
'flake8==3.8.3',

View File

@@ -355,6 +355,48 @@ def test_dataclass_signature(Script, skip_pre_python37, start, start_params):
price, = sig.params[-2].infer()
assert price.name == 'float'
@pytest.mark.parametrize(
'start, start_params', [
['@define\nclass X:', []],
['@frozen\nclass X:', []],
['@define(eq=True)\nclass X:', []],
[dedent('''
class Y():
y: int
@define
class X(Y):'''), []],
[dedent('''
@define
class Y():
y: int
z = 5
@define
class X(Y):'''), ['y']],
]
)
def test_attrs_signature(Script, skip_pre_python37, start, start_params):
has_attrs = bool(Script('import attrs').infer())
if not has_attrs:
raise pytest.skip("attrs needed in target environment to run this test")
code = dedent('''
name: str
foo = 3
price: float
quantity: int = 0.0
X(''')
# attrs exposes two namespaces
code = 'from attrs import define, frozen\n' + start + code
sig, = Script(code).get_signatures()
assert [p.name for p in sig.params] == start_params + ['name', 'price', 'quantity']
quantity, = sig.params[-1].infer()
assert quantity.name == 'int'
price, = sig.params[-2].infer()
assert price.name == 'float'
@pytest.mark.parametrize(
'stmt, expected', [