mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
Merge pull request #1885 from asford/attrs_support
Extend dataclass constructor hinting to attrs next-gen apis.
This commit is contained in:
@@ -6,6 +6,8 @@ Changelog
|
|||||||
Unreleased
|
Unreleased
|
||||||
++++++++++
|
++++++++++
|
||||||
|
|
||||||
|
- Added dataclass-equivalent for attrs.define
|
||||||
|
|
||||||
0.18.1 (2021-11-17)
|
0.18.1 (2021-11-17)
|
||||||
+++++++++++++++++++
|
+++++++++++++++++++
|
||||||
|
|
||||||
|
|||||||
@@ -803,6 +803,15 @@ _implemented = {
|
|||||||
# For now this works at least better than Jedi trying to understand it.
|
# For now this works at least better than Jedi trying to understand it.
|
||||||
'dataclass': _dataclass
|
'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': {
|
'os.path': {
|
||||||
'dirname': _create_string_input_function(os.path.dirname),
|
'dirname': _create_string_input_function(os.path.dirname),
|
||||||
'abspath': _create_string_input_function(os.path.abspath),
|
'abspath': _create_string_input_function(os.path.abspath),
|
||||||
|
|||||||
1
setup.py
1
setup.py
@@ -41,6 +41,7 @@ setup(name='jedi',
|
|||||||
# coloroma for colored debug output
|
# coloroma for colored debug output
|
||||||
'colorama',
|
'colorama',
|
||||||
'Django<3.1', # For now pin this.
|
'Django<3.1', # For now pin this.
|
||||||
|
'attrs',
|
||||||
],
|
],
|
||||||
'qa': [
|
'qa': [
|
||||||
'flake8==3.8.3',
|
'flake8==3.8.3',
|
||||||
|
|||||||
@@ -355,6 +355,48 @@ def test_dataclass_signature(Script, skip_pre_python37, start, start_params):
|
|||||||
price, = sig.params[-2].infer()
|
price, = sig.params[-2].infer()
|
||||||
assert price.name == 'float'
|
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(
|
@pytest.mark.parametrize(
|
||||||
'stmt, expected', [
|
'stmt, expected', [
|
||||||
|
|||||||
Reference in New Issue
Block a user