Skip to content

Commit 49abd63

Browse files
authored
Add support for dict.items (pyccel#2073)
Make `Iterable` into a super-class instead of a storage class. Functions that can be used in an iterable context must inherit from this class and define useful methods. The method `get_python_iterable_item` must be defined. If the iterable can be converted to a range the methods `get_range` and `get_assign_targets` must also be defined. Organising iterables via inheritance instead of storing the object in the `Iterable` class avoids problems with circular includes as the low-level `Iterable` object no longer depends on a large number of other ast modules. The new setup is used to add support for `dict.items`. **Commit Summary** - Add an `Iterable` sub-class describing `dict.items`. - Change method names in `Iterable` sub-classes - Remove unnecessary methods `length` and `__getitem__` in `Iterable` sub-classes - Add `Iterable` as a super class of objects that can be iterated over. - Add a `prefer_inhomogeneous` argument to `PythonTuple` which allows the developer to force the creation of an inhomogeneous tuple (e.g. for the target when iterating over an enumerate of integers). - Add a `VariableIterator` class to represent the `iter()` function that is called implicitly in a for loop - Move `Iterable` class from `ast.core` to `ast.internals` - Remove unnecessary line for `Iterable` in sympy_helper. - Save the `For` target as a tuple after the semantic stage - Fix insertion of an inhomogeneous tuple into a loop scope. - Create `_get_for_iterators` function to unify handling of iterators in FunctionalFor/GeneratorExpressions/For loops - Add tests
1 parent e0e7478 commit 49abd63

File tree

20 files changed

+709
-347
lines changed

20 files changed

+709
-347
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ All notable changes to this project will be documented in this file.
4242
- #1918 : Add support for set method `clear()`.
4343
- #1918 : Add support for set method `copy()`.
4444
- #1753 : Add support for set method `union()`.
45+
- #1884 : Add support for dict method `items()`.
4546
- #1936 : Add missing C output for inline decorator example in documentation
4647
- #1937 : Optimise `pyccel.ast.basic.PyccelAstNode.substitute` method.
4748
- #1544 : Add support for `typing.TypeAlias`.
@@ -110,6 +111,7 @@ All notable changes to this project will be documented in this file.
110111
- \[INTERNALS\] Stop using ndarrays as an intermediate step to call Fortran code.
111112
- \[INTERNALS\] Stop using ndarrays as an intermediate step to return arrays from Fortran code.
112113
- \[INTERNALS\] Unify the strategy for handling additional imports in the printing stage for different languages.
114+
- \[INTERNALS\] Make `Iterable` into a super-class instead of a storage class.
113115

114116
### Deprecated
115117

docs/builtin-functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Python contains a limited number of builtin functions defined [here](https://doc
123123
| `clear` | Python-only |
124124
| `copy` | Python-only |
125125
| `get` | Python-only |
126-
| `items` | No |
126+
| `items` | **Yes** |
127127
| `keys` | No |
128128
| `pop` | Python-only |
129129
| `popitem` | Python-only |

pyccel/ast/builtin_methods/dict_methods.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
This module contains objects which describe these methods within Pyccel's AST.
1111
"""
1212

13-
from pyccel.ast.datatypes import InhomogeneousTupleType, VoidType
14-
from pyccel.ast.internals import PyccelFunction
13+
from pyccel.ast.datatypes import InhomogeneousTupleType, VoidType, SymbolicType
14+
from pyccel.ast.internals import PyccelFunction, Iterable
15+
from pyccel.ast.variable import IndexedElement
1516

1617

1718
__all__ = ('DictClear',
1819
'DictCopy',
1920
'DictGet',
21+
'DictItems',
2022
'DictMethod',
2123
'DictPop',
2224
'DictPopitem',
@@ -260,7 +262,6 @@ def __init__(self, dict_obj):
260262
super().__init__(dict_obj)
261263

262264
#==============================================================================
263-
264265
class DictCopy(DictMethod):
265266
"""
266267
Represents a call to the .copy() method.
@@ -280,3 +281,49 @@ def __init__(self, dict_obj):
280281
dict_type = dict_obj.class_type
281282
self._class_type = dict_type
282283
super().__init__(dict_obj)
284+
285+
#==============================================================================
286+
class DictItems(Iterable):
287+
"""
288+
Represents a call to the .items() method.
289+
290+
Represents a call to the .items() method which iterates over a dictionary.
291+
292+
Parameters
293+
----------
294+
dict_obj : TypedAstNode
295+
The object from which the method is called.
296+
"""
297+
__slots__ = ('_dict_obj',)
298+
_attribute_nodes = Iterable._attribute_nodes + ("_dict_obj",)
299+
_shape = None
300+
_class_type = SymbolicType()
301+
name = 'items'
302+
303+
def __init__(self, dict_obj):
304+
self._dict_obj = dict_obj
305+
super().__init__(1)
306+
307+
@property
308+
def variable(self):
309+
"""
310+
Get the object representing the dict.
311+
312+
Get the object representing the dict.
313+
"""
314+
return self._dict_obj
315+
316+
def get_python_iterable_item(self):
317+
"""
318+
Get the item of the iterable that will be saved to the loop targets.
319+
320+
Returns two objects that could be a key and a value of the dictionary.
321+
These elements are used to determine the types of the loop targets.
322+
323+
Returns
324+
-------
325+
list[TypedAstNode]
326+
A list of objects that should be assigned to variables.
327+
"""
328+
item = DictPopitem(self._dict_obj)
329+
return [IndexedElement(item, 0), IndexedElement(item, 1)]

0 commit comments

Comments
 (0)